diff --git a/AQOfflineRenderTest.zip b/AQOfflineRenderTest.zip new file mode 100644 index 0000000..874ca6d Binary files /dev/null and b/AQOfflineRenderTest.zip differ diff --git a/AQOfflineRenderTest/AQOfflineRenderTest.xcodeproj/project.pbxproj b/AQOfflineRenderTest/AQOfflineRenderTest.xcodeproj/project.pbxproj new file mode 100755 index 0000000..e3f4358 --- /dev/null +++ b/AQOfflineRenderTest/AQOfflineRenderTest.xcodeproj/project.pbxproj @@ -0,0 +1,350 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1811ED8011D010000068DA4C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1811ED7E11D010000068DA4C /* MainWindow.xib */; }; + 18AD6A7011D56509005232E4 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6911D56509005232E4 /* Icon-72.png */; }; + 18AD6A7111D56509005232E4 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6A11D56509005232E4 /* Icon-Small-50.png */; }; + 18AD6A7211D56509005232E4 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6B11D56509005232E4 /* Icon-Small.png */; }; + 18AD6A7311D56509005232E4 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6C11D56509005232E4 /* Icon-Small@2x.png */; }; + 18AD6A7411D56509005232E4 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6D11D56509005232E4 /* Icon.png */; }; + 18AD6A7511D56509005232E4 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6E11D56509005232E4 /* Icon@2x.png */; }; + 18AD6A7611D56509005232E4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6A6F11D56509005232E4 /* iTunesArtwork */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 2B2115140FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B2115130FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.m */; }; + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C70F5383D30033DE8C /* AVFoundation.framework */; }; + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */; }; + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */; }; + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1C0F59F67E00D63998 /* green_button.png */; }; + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1D0F59F67E00D63998 /* red_button.png */; }; + 2BE30B220F59F67E00D63998 /* soundalac.caf in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1E0F59F67E00D63998 /* soundalac.caf */; }; + 2BE30B230F59F67E00D63998 /* info.html in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1F0F59F67E00D63998 /* info.html */; }; + 2BE30B650F5A054000D63998 /* aqofflinerender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE30B640F5A054000D63998 /* aqofflinerender.cpp */; }; + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */; }; + 2BFC8D761047097E00C9A1B3 /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BFC8D741047097E00C9A1B3 /* CAXException.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1811ED7F11D010000068DA4C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 18AD6A6911D56509005232E4 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18AD6A6A11D56509005232E4 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18AD6A6B11D56509005232E4 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18AD6A6C11D56509005232E4 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18AD6A6D11D56509005232E4 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18AD6A6E11D56509005232E4 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18AD6A6F11D56509005232E4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* AQOffilineRenderTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AQOffilineRenderTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B2115120FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AQOfflineRenderTestAppDelegate.h; sourceTree = ""; }; + 2B2115130FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AQOfflineRenderTestAppDelegate.m; sourceTree = ""; }; + 2B2115150FC4D8C700EFBE56 /* AQOfflineRenderTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AQOfflineRenderTest_Prefix.pch; sourceTree = ""; }; + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = ""; }; + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = ""; }; + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + 2BE30B1C0F59F67E00D63998 /* green_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = green_button.png; path = Resources/green_button.png; sourceTree = ""; }; + 2BE30B1D0F59F67E00D63998 /* red_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = red_button.png; path = Resources/red_button.png; sourceTree = ""; }; + 2BE30B1E0F59F67E00D63998 /* soundalac.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = soundalac.caf; path = Resources/soundalac.caf; sourceTree = ""; }; + 2BE30B1F0F59F67E00D63998 /* info.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = info.html; path = Resources/info.html; sourceTree = ""; }; + 2BE30B640F5A054000D63998 /* aqofflinerender.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = aqofflinerender.cpp; sourceTree = ""; }; + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 2BFC8D741047097E00C9A1B3 /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = ""; }; + 2BFC8D751047097E00C9A1B3 /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */, + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 2B2115120FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.h */, + 2B2115130FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.m */, + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */, + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* AQOffilineRenderTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */, + 2BE30B640F5A054000D63998 /* aqofflinerender.cpp */, + 080E96DDFE201D6D7F000001 /* Classes */, + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 2B2115150FC4D8C700EFBE56 /* AQOfflineRenderTest_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18AD6A6911D56509005232E4 /* Icon-72.png */, + 18AD6A6A11D56509005232E4 /* Icon-Small-50.png */, + 18AD6A6B11D56509005232E4 /* Icon-Small.png */, + 18AD6A6C11D56509005232E4 /* Icon-Small@2x.png */, + 18AD6A6D11D56509005232E4 /* Icon.png */, + 18AD6A6E11D56509005232E4 /* Icon@2x.png */, + 18AD6A6F11D56509005232E4 /* iTunesArtwork */, + 1811ED7E11D010000068DA4C /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 2BE30B1C0F59F67E00D63998 /* green_button.png */, + 2BE30B1D0F59F67E00D63998 /* red_button.png */, + 2BE30B1E0F59F67E00D63998 /* soundalac.caf */, + 2BE30B1F0F59F67E00D63998 /* info.html */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */, + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */ = { + isa = PBXGroup; + children = ( + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */, + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */, + 2BFC8D751047097E00C9A1B3 /* CAXException.h */, + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */, + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */, + 2BFC8D741047097E00C9A1B3 /* CAXException.cpp */, + ); + path = iPublicUtility; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* AQOffilineRenderTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AQOffilineRenderTest" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AQOffilineRenderTest; + productName = AQOffilineRenderTest; + productReference = 1D6058910D05DD3D006BFB54 /* AQOffilineRenderTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AQOfflineRenderTest" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* AQOffilineRenderTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */, + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */, + 2BE30B220F59F67E00D63998 /* soundalac.caf in Resources */, + 2BE30B230F59F67E00D63998 /* info.html in Resources */, + 1811ED8011D010000068DA4C /* MainWindow.xib in Resources */, + 18AD6A7011D56509005232E4 /* Icon-72.png in Resources */, + 18AD6A7111D56509005232E4 /* Icon-Small-50.png in Resources */, + 18AD6A7211D56509005232E4 /* Icon-Small.png in Resources */, + 18AD6A7311D56509005232E4 /* Icon-Small@2x.png in Resources */, + 18AD6A7411D56509005232E4 /* Icon.png in Resources */, + 18AD6A7511D56509005232E4 /* Icon@2x.png in Resources */, + 18AD6A7611D56509005232E4 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */, + 2BE30B650F5A054000D63998 /* aqofflinerender.cpp in Sources */, + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */, + 2B2115140FC4D8B700EFBE56 /* AQOfflineRenderTestAppDelegate.m in Sources */, + 2BFC8D761047097E00C9A1B3 /* CAXException.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 1811ED7E11D010000068DA4C /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 1811ED7F11D010000068DA4C /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AQOfflineRenderTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = AQOffilineRenderTest; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AQOfflineRenderTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = AQOffilineRenderTest; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AQOffilineRenderTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AQOfflineRenderTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/AQOfflineRenderTest/AQOfflineRenderTest_Prefix.pch b/AQOfflineRenderTest/AQOfflineRenderTest_Prefix.pch new file mode 100644 index 0000000..f5eac59 --- /dev/null +++ b/AQOfflineRenderTest/AQOfflineRenderTest_Prefix.pch @@ -0,0 +1,52 @@ +// +// Prefix header for all source files of the 'AQOfflineRenderTest' target in the 'AQOffilineRenderTest' project +// +// File: AQOfflineRenderTest_Prefix.pch +// Abstract: n/a +// Version: 1.2 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +// Inc. ("Apple") in consideration of your agreement to the following +// terms, and your use, installation, modification or redistribution of +// this Apple software constitutes acceptance of these terms. If you do +// not agree with these terms, please do not use, install, modify or +// redistribute this Apple software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non-exclusive +// license, under Apple's copyrights in this original Apple software (the +// "Apple Software"), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and/or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following +// text and disclaimers in all such redistributions of the Apple Software. +// Neither the name, trademarks, service marks or logos of Apple Inc. may +// be used to endorse or promote products derived from the Apple Software +// without specific prior written permission from Apple. Except as +// expressly stated in this notice, no other rights or licenses, express or +// implied, are granted by Apple herein, including but not limited to any +// patent rights that may be infringed by your derivative works or by other +// works in which the Apple Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE +// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (C) 2010 Apple Inc. All Rights Reserved. +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/AQOfflineRenderTest/Classes/AQOfflineRenderTestAppDelegate.h b/AQOfflineRenderTest/Classes/AQOfflineRenderTestAppDelegate.h new file mode 100644 index 0000000..016d32c --- /dev/null +++ b/AQOfflineRenderTest/Classes/AQOfflineRenderTestAppDelegate.h @@ -0,0 +1,60 @@ +/* + File: AQOfflineRenderTestAppDelegate.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface AQOfflineRenderTestAppDelegate : NSObject { + UIWindow *window; + + IBOutlet UINavigationController *navigationController; + IBOutlet UIViewController *myViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; + +@end + diff --git a/AQOfflineRenderTest/Classes/AQOfflineRenderTestAppDelegate.m b/AQOfflineRenderTest/Classes/AQOfflineRenderTestAppDelegate.m new file mode 100644 index 0000000..8f98823 --- /dev/null +++ b/AQOfflineRenderTest/Classes/AQOfflineRenderTestAppDelegate.m @@ -0,0 +1,66 @@ +/* + File: AQOfflineRenderTestAppDelegate.m + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AQOfflineRenderTestAppDelegate.h" + +@implementation AQOfflineRenderTestAppDelegate + +@synthesize window; + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after application launch + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + +- (void)dealloc { + [window release]; + [super dealloc]; +} + +@end diff --git a/AQOfflineRenderTest/Classes/MyViewController.h b/AQOfflineRenderTest/Classes/MyViewController.h new file mode 100755 index 0000000..bc09a3d --- /dev/null +++ b/AQOfflineRenderTest/Classes/MyViewController.h @@ -0,0 +1,80 @@ +/* + File: MyViewController.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import + +@interface MyViewController : UIViewController +{ + IBOutlet UIView *instructionsView; + IBOutlet UIWebView *webView; + IBOutlet UIView *contentView; + + IBOutlet UIButton *startButton; + IBOutlet UIActivityIndicatorView *activityIndicator; + + UIBarButtonItem *flipButton; + UIBarButtonItem *doneButton; + + NSString *destinationFilePath; + CFURLRef sourceURL; + CFURLRef destinationURL; +} + +@property (readonly, nonatomic) UIView *instructionsView; +@property (readonly, nonatomic) UIWebView *webView; +@property (readonly, nonatomic) UIView *contentView; +@property (readonly, nonatomic) UIButton *startButton; +@property (readonly, nonatomic) UIActivityIndicatorView *activityIndicator; + +@property (nonatomic, retain) UIBarButtonItem *flipButton; +@property (nonatomic, retain) UIBarButtonItem *doneButton; + +- (IBAction)doSomethingAction:(id)sender; + +@end \ No newline at end of file diff --git a/AQOfflineRenderTest/Classes/MyViewController.m b/AQOfflineRenderTest/Classes/MyViewController.m new file mode 100755 index 0000000..0cb3f31 --- /dev/null +++ b/AQOfflineRenderTest/Classes/MyViewController.m @@ -0,0 +1,201 @@ +/* + File: MyViewController.m + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyViewController.h" + +#define kTransitionDuration 0.75 + +extern void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL); + +@implementation MyViewController + +@synthesize instructionsView, webView, contentView, startButton, activityIndicator, flipButton, doneButton; + +- (void)dealloc +{ + [flipButton release]; + [doneButton release]; + + [destinationFilePath release]; + CFRelease(sourceURL); + CFRelease(destinationURL); + + [super dealloc]; +} + +- (void)viewDidLoad +{ + // create the URLs we'll use for source and destination + NSString *source = [[NSBundle mainBundle] pathForResource:@"soundalac" ofType:@"caf"]; + sourceURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)source, kCFURLPOSIXPathStyle, false); + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory]; + destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); + + // load up the info text + NSString *infoSouceFile = [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]; + NSString *infoText = [NSString stringWithContentsOfFile:infoSouceFile encoding:NSUTF8StringEncoding error:nil]; + [self.webView loadHTMLString:infoText baseURL:nil]; + + // set up start button + UIImage *greenImage = [[UIImage imageNamed:@"green_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + UIImage *redImage = [[UIImage imageNamed:@"red_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + + [startButton setBackgroundImage:greenImage forState:UIControlStateNormal]; + [startButton setBackgroundImage:redImage forState:UIControlStateDisabled]; + [startButton setEnabled:YES]; + + // add the subview + [self.view addSubview:contentView]; + + // add our custom flip buttons as the nav bars custom right view + UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; + [infoButton addTarget:self action:@selector(flipAction:) forControlEvents:UIControlEventTouchUpInside]; + + flipButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + self.navigationItem.rightBarButtonItem = flipButton; + + // create our done button as the nav bar's custom right view for the flipped view (used later) + doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(flipAction:)]; +} + +- (void)didReceiveMemoryWarning +{ + // Invoke super's implementation to do the Right Thing, but also release the input controller since we can do that + // In practice this is unlikely to be used in this application, and it would be of little benefit, + // but the principle is the important thing. + // + [super didReceiveMemoryWarning]; +} + +#pragma mark- Actions + +- (void)flipAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + + [UIView setAnimationTransition:([self.contentView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) + forView:self.view + cache:YES]; + + if ([self.instructionsView superview]) { + [self.instructionsView removeFromSuperview]; + [self.view addSubview:contentView]; + } else { + [self.contentView removeFromSuperview]; + [self.view addSubview:instructionsView]; + } + + [UIView commitAnimations]; + + // adjust our done/info buttons accordingly + if ([instructionsView superview]) { + self.navigationItem.rightBarButtonItem = doneButton; + } else { + self.navigationItem.rightBarButtonItem = flipButton; + } +} + +- (IBAction)doSomethingAction:(id)sender +{ + [self.startButton setTitle:@"Rendering Audio..." forState:UIControlStateDisabled]; + [startButton setEnabled:NO]; + + [self.activityIndicator startAnimating]; + + // run AQ code in a background thread + [self performSelectorInBackground:(@selector(renderAudio)) withObject:nil]; +} + +#pragma mark- AVAudioPlayer +- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag +{ + if (flag == NO) NSLog(@"Playback finished unsuccessfully!"); + + [player setDelegate:nil]; + [player release]; + + [startButton setEnabled:YES]; +} + +- (void)playAudio +{ + // play the result + AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:(NSURL *)destinationURL error:nil]; + + [player setDelegate:self]; + [player play]; +} + +#pragma mark- AudioQueue + +- (void)renderAudio +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + // delete the previous output file if it exists, not required but good for the test + if ([[NSFileManager defaultManager] fileExistsAtPath:destinationFilePath]) { + [[NSFileManager defaultManager] removeItemAtPath:destinationFilePath error:nil]; + } + + DoAQOfflineRender(sourceURL, destinationURL); + + [self.activityIndicator stopAnimating]; + + [self.startButton setTitle:@"Playing Rendered Audio..." forState:UIControlStateDisabled]; + + [self performSelectorOnMainThread:(@selector(playAudio)) withObject:nil waitUntilDone:NO]; + + [pool release]; +} + +@end \ No newline at end of file diff --git a/AQOfflineRenderTest/Info.plist b/AQOfflineRenderTest/Info.plist new file mode 100644 index 0000000..c977d80 --- /dev/null +++ b/AQOfflineRenderTest/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.dts.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + eDTS + CFBundleVersion + 1.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/AQOfflineRenderTest/ReadMe.txt b/AQOfflineRenderTest/ReadMe.txt new file mode 100755 index 0000000..180423b --- /dev/null +++ b/AQOfflineRenderTest/ReadMe.txt @@ -0,0 +1,64 @@ +AQOfflineRenderTest + +=========================================================================== +DESCRIPTION: + +AQOfflineRenderTest demonstrates the use of the AudioQueueOfflineRender API. + +All the relevant code is in the file aqofflinerender.cpp. + +Touching the "Start" button simply calls the function DoAQOfflineRender() producing LPCM output buffers from an ALAC encoded source file. These buffers are then written to a .caf file which is played back after rendering using AVAudioPlayer to confirm success. + +=========================================================================== +RELATED INFORMATION: + +Core Audio Overview +Audio Queue Programming Guide +Audio Queue Services Reference + +=========================================================================== +SPECIAL CONSIDERATIONS: + +See Technical Q&A QA1562 - Audio Queue - Offline Rendering + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + + +=========================================================================== +PACKAGING LIST: + +AQOfflineRenderTestAppDelegate.h +AQOfflineRenderTestAppDelegate.m + +The AQOfflineRenderTestAppDelegate class defines the application delegate object, responsible for adding the navigation controllers view to the application window. + +MyViewController.h +MyViewController.m + +The MyViewController class defines the controller object for the application. The object helps set up the user interface, responds to and manages user interaction, and implements sound playback. + +qofflinerender.cpp + +This file implements the DoAQOfflineRender function which is called on a background thread from the MyViewController class. + +All the code demonstrating how to perform offline render is contained in this one file, the rest of the sample can be thought of as a simple framework for the demonstration code in this file. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.2, added CFBundleIconFiles in Info.plist. +Version 1.1, upgraded project to build with the iOS 4.0 SDK. +Version 1.0, tested with iPhone OS 2.2.1. First public release. + + +================================================================================ +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/AQOfflineRenderTest/Resources/green_button.png b/AQOfflineRenderTest/Resources/green_button.png new file mode 100755 index 0000000..6c8b20e Binary files /dev/null and b/AQOfflineRenderTest/Resources/green_button.png differ diff --git a/AQOfflineRenderTest/Resources/info.html b/AQOfflineRenderTest/Resources/info.html new file mode 100644 index 0000000..87767eb --- /dev/null +++ b/AQOfflineRenderTest/Resources/info.html @@ -0,0 +1,46 @@ + + +

Audio Queue Offline Render Test Sample

+ +

Demonstrates the use of the AudioQueueOfflineRender API. All the relevant code is +in the file aqofflinerender.cpp. Touching the "Start" button simply calls +DoAQOfflineRender() producing LPCM output buffers from an ALAC encoded source file. +These buffers are then written to a .caf file which is played back after rendering using +AVAudioPlayer to confirm success.

+ +


+ +

Audio Queue Services provides a straightforward, low overhead way to record +and play audio in iPhone OS and Mac OS X. It is the recommended technology +to use for adding basic recording or playback features to your iPhone OS or +Mac OS X application.

+ +

Offline rendering with an audio queue output allows applications to render +audio to a buffer instead of directly to an output device. This is +especially useful with the iPhone OS, since the Audio Converter and Extended +Audio File APIs do not currently (up to iPhone OS 2.2.x) support +decompressing AAC, ALAC or MP3 encoded audio to LPCM if further processing +is desired.

+ +

If you need to generate buffers of LPCM data from AAC, ALAC or MP3 encoded +audio, using audio queue offline rendering is the recommended approach.

+ +

Audio Queue Services lets you record and play audio in any of the following +formats:

+
    +
  • Linear PCM.
  • +
  • Any compressed format supported natively on the Apple platform you are +developing for.
  • +
  • Any other format for which a user has an installed codec.
  • +
+ +

Audio Queue Services is high level. It lets your application use hardware +recording and playback devices (such as microphones and loudspeakers) +without knowledge of the hardware interface. It also lets you use +sophisticated codecs without knowledge of how the codecs work. +At the same time, Audio Queue Services supports some advanced features. It +provides fine-grained timing control to support scheduled playback and +synchronization, for example synchronizing playback of multiple audio +queues.

+
+
\ No newline at end of file diff --git a/AQOfflineRenderTest/Resources/red_button.png b/AQOfflineRenderTest/Resources/red_button.png new file mode 100755 index 0000000..42de34e Binary files /dev/null and b/AQOfflineRenderTest/Resources/red_button.png differ diff --git a/AQOfflineRenderTest/Resources/soundalac.caf b/AQOfflineRenderTest/Resources/soundalac.caf new file mode 100644 index 0000000..15eaecc Binary files /dev/null and b/AQOfflineRenderTest/Resources/soundalac.caf differ diff --git a/AQOfflineRenderTest/aqofflinerender.cpp b/AQOfflineRenderTest/aqofflinerender.cpp new file mode 100644 index 0000000..4ff40ab --- /dev/null +++ b/AQOfflineRenderTest/aqofflinerender.cpp @@ -0,0 +1,333 @@ +/* + File: aqofflinerender.cpp +Abstract: Demonstrates the use of AudioQueueOfflineRender + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +// standard includes +#include +#include +#include + +// helpers +#include "CAXException.h" +#include "CAStreamBasicDescription.h" + +// the application specific info we keep track of +struct AQTestInfo +{ + AudioFileID mAudioFile; + CAStreamBasicDescription mDataFormat; + AudioQueueRef mQueue; + AudioQueueBufferRef mBuffer; + SInt64 mCurrentPacket; + UInt32 mNumPacketsToRead; + AudioStreamPacketDescription *mPacketDescs; + bool mFlushed; + bool mDone; +}; + +#pragma mark- Helper Functions +// *********************** +// CalculateBytesForTime Utility Function + + // we only use time here as a guideline + // we are really trying to get somewhere between 16K and 64K buffers, but not allocate too much if we don't need it +void CalculateBytesForTime (CAStreamBasicDescription & inDesc, UInt32 inMaxPacketSize, Float64 inSeconds, UInt32 *outBufferSize, UInt32 *outNumPackets) +{ + static const int maxBufferSize = 0x10000; // limit size to 64K + static const int minBufferSize = 0x4000; // limit size to 16K + + if (inDesc.mFramesPerPacket) { + Float64 numPacketsForTime = inDesc.mSampleRate / inDesc.mFramesPerPacket * inSeconds; + *outBufferSize = numPacketsForTime * inMaxPacketSize; + } else { + // if frames per packet is zero, then the codec has no predictable packet == time + // so we can't tailor this (we don't know how many Packets represent a time period + // we'll just return a default buffer size + *outBufferSize = maxBufferSize > inMaxPacketSize ? maxBufferSize : inMaxPacketSize; + } + + // we're going to limit our size to our default + if (*outBufferSize > maxBufferSize && *outBufferSize > inMaxPacketSize) { + *outBufferSize = maxBufferSize; + } else { + // also make sure we're not too small - we don't want to go the disk for too small chunks + if (*outBufferSize < minBufferSize) { + *outBufferSize = minBufferSize; + } + } + + *outNumPackets = *outBufferSize / inMaxPacketSize; +} + +#pragma mark- AQOutputCallback +// *********************** +// AudioQueueOutputCallback function used to push data into the audio queue + +static void AQTestBufferCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) +{ + AQTestInfo * myInfo = (AQTestInfo *)inUserData; + if (myInfo->mDone) return; + + UInt32 numBytes; + UInt32 nPackets = myInfo->mNumPacketsToRead; + OSStatus result = AudioFileReadPackets(myInfo->mAudioFile, // The audio file from which packets of audio data are to be read. + false, // Set to true to cache the data. Otherwise, set to false. + &numBytes, // On output, a pointer to the number of bytes actually returned. + myInfo->mPacketDescs, // A pointer to an array of packet descriptions that have been allocated. + myInfo->mCurrentPacket, // The packet index of the first packet you want to be returned. + &nPackets, // On input, a pointer to the number of packets to read. On output, the number of packets actually read. + inCompleteAQBuffer->mAudioData); // A pointer to user-allocated memory. + if (result) { + DebugMessageN1 ("Error reading from file: %d\n", (int)result); + exit(1); + } + + // we have some data + if (nPackets > 0) { + inCompleteAQBuffer->mAudioDataByteSize = numBytes; + + result = AudioQueueEnqueueBuffer(inAQ, // The audio queue that owns the audio queue buffer. + inCompleteAQBuffer, // The audio queue buffer to add to the buffer queue. + (myInfo->mPacketDescs ? nPackets : 0), // The number of packets of audio data in the inBuffer parameter. See Docs. + myInfo->mPacketDescs); // An array of packet descriptions. Or NULL. See Docs. + if (result) { + DebugMessageN1 ("Error enqueuing buffer: %d\n", (int)result); + exit(1); + } + + myInfo->mCurrentPacket += nPackets; + + } else { + // **** This ensures that we flush the queue when done -- ensures you get all the data out **** + + if (!myInfo->mFlushed) { + result = AudioQueueFlush(myInfo->mQueue); + + if (result) { + DebugMessageN1("AudioQueueFlush failed: %d", (int)result); + exit(1); + } + + myInfo->mFlushed = true; + } + + result = AudioQueueStop(myInfo->mQueue, false); + if (result) { + DebugMessageN1("AudioQueueStop(false) failed: %d", (int)result); + exit(1); + } + + // reading nPackets == 0 is our EOF condition + myInfo->mDone = true; + } +} + +// *********************** +#pragma mark- Main Render Function + +void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL) +{ + // main audio queue code + try { + AQTestInfo myInfo; + + myInfo.mDone = false; + myInfo.mFlushed = false; + myInfo.mCurrentPacket = 0; + + // get the source file + XThrowIfError(AudioFileOpenURL(sourceURL, 0x01/*fsRdPerm*/, 0/*inFileTypeHint*/, &myInfo.mAudioFile), "AudioFileOpen failed"); + + UInt32 size = sizeof(myInfo.mDataFormat); + XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyDataFormat, &size, &myInfo.mDataFormat), "couldn't get file's data format"); + + printf ("File format: "); myInfo.mDataFormat.Print(); + + // create a new audio queue output + XThrowIfError(AudioQueueNewOutput(&myInfo.mDataFormat, // The data format of the audio to play. For linear PCM, only interleaved formats are supported. + AQTestBufferCallback, // A callback function to use with the playback audio queue. + &myInfo, // A custom data structure for use with the callback function. + CFRunLoopGetCurrent(), // The event loop on which the callback function pointed to by the inCallbackProc parameter is to be called. + // If you specify NULL, the callback is invoked on one of the audio queue’s internal threads. + kCFRunLoopCommonModes, // The run loop mode in which to invoke the callback function specified in the inCallbackProc parameter. + 0, // Reserved for future use. Must be 0. + &myInfo.mQueue), // On output, the newly created playback audio queue object. + "AudioQueueNew failed"); + + UInt32 bufferByteSize; + + // we need to calculate how many packets we read at a time and how big a buffer we need + // we base this on the size of the packets in the file and an approximate duration for each buffer + { + bool isFormatVBR = (myInfo.mDataFormat.mBytesPerPacket == 0 || myInfo.mDataFormat.mFramesPerPacket == 0); + + // first check to see what the max size of a packet is - if it is bigger + // than our allocation default size, that needs to become larger + UInt32 maxPacketSize; + size = sizeof(maxPacketSize); + XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize), "couldn't get file's max packet size"); + + // adjust buffer size to represent about a second of audio based on this format + CalculateBytesForTime(myInfo.mDataFormat, maxPacketSize, 1.0/*seconds*/, &bufferByteSize, &myInfo.mNumPacketsToRead); + + if (isFormatVBR) { + myInfo.mPacketDescs = new AudioStreamPacketDescription [myInfo.mNumPacketsToRead]; + } else { + myInfo.mPacketDescs = NULL; // we don't provide packet descriptions for constant bit rate formats (like linear PCM) + } + + printf ("Buffer Byte Size: %d, Num Packets to Read: %d\n", (int)bufferByteSize, (int)myInfo.mNumPacketsToRead); + } + + // if the file has a magic cookie, we should get it and set it on the AQ + size = sizeof(UInt32); + OSStatus result = AudioFileGetPropertyInfo (myInfo.mAudioFile, kAudioFilePropertyMagicCookieData, &size, NULL); + + if (!result && size) { + char* cookie = new char [size]; + XThrowIfError (AudioFileGetProperty (myInfo.mAudioFile, kAudioFilePropertyMagicCookieData, &size, cookie), "get cookie from file"); + XThrowIfError (AudioQueueSetProperty(myInfo.mQueue, kAudioQueueProperty_MagicCookie, cookie, size), "set cookie on queue"); + delete [] cookie; + } + + // channel layout? + OSStatus err = AudioFileGetPropertyInfo(myInfo.mAudioFile, kAudioFilePropertyChannelLayout, &size, NULL); + AudioChannelLayout *acl = NULL; + if (err == noErr && size > 0) { + acl = (AudioChannelLayout *)malloc(size); + XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyChannelLayout, &size, acl), "get audio file's channel layout"); + XThrowIfError(AudioQueueSetProperty(myInfo.mQueue, kAudioQueueProperty_ChannelLayout, acl, size), "set channel layout on queue"); + } + + //allocate the input read buffer + XThrowIfError(AudioQueueAllocateBuffer(myInfo.mQueue, bufferByteSize, &myInfo.mBuffer), "AudioQueueAllocateBuffer"); + + // prepare a canonical interleaved capture format + CAStreamBasicDescription captureFormat; + captureFormat.mSampleRate = myInfo.mDataFormat.mSampleRate; + captureFormat.SetAUCanonical(myInfo.mDataFormat.mChannelsPerFrame, true); // interleaved + XThrowIfError(AudioQueueSetOfflineRenderFormat(myInfo.mQueue, &captureFormat, acl), "set offline render format"); + + ExtAudioFileRef captureFile; + + // prepare a 16-bit int file format, sample channel count and sample rate + CAStreamBasicDescription dstFormat; + dstFormat.mSampleRate = myInfo.mDataFormat.mSampleRate; + dstFormat.mChannelsPerFrame = myInfo.mDataFormat.mChannelsPerFrame; + dstFormat.mFormatID = kAudioFormatLinearPCM; + dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian + dstFormat.mBitsPerChannel = 16; + dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame; + dstFormat.mFramesPerPacket = 1; + + // create the capture file + XThrowIfError(ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, acl, kAudioFileFlags_EraseFile, &captureFile), "ExtAudioFileCreateWithURL"); + + // set the capture file's client format to be the canonical format from the queue + XThrowIfError(ExtAudioFileSetProperty(captureFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &captureFormat), "set ExtAudioFile client format"); + + // allocate the capture buffer, just keep it at half the size of the enqueue buffer + // we don't ever want to pull any faster than we can push data in for render + // this 2:1 ratio keeps the AQ Offline Render happy + const UInt32 captureBufferByteSize = bufferByteSize / 2; + + AudioQueueBufferRef captureBuffer; + AudioBufferList captureABL; + + XThrowIfError(AudioQueueAllocateBuffer(myInfo.mQueue, captureBufferByteSize, &captureBuffer), "AudioQueueAllocateBuffer"); + + captureABL.mNumberBuffers = 1; + captureABL.mBuffers[0].mData = captureBuffer->mAudioData; + captureABL.mBuffers[0].mNumberChannels = captureFormat.mChannelsPerFrame; + + // lets start playing now - stop is called in the AQTestBufferCallback when there's + // no more to read from the file + XThrowIfError(AudioQueueStart(myInfo.mQueue, NULL), "AudioQueueStart failed"); + + AudioTimeStamp ts; + ts.mFlags = kAudioTimeStampSampleTimeValid; + ts.mSampleTime = 0; + + // we need to call this once asking for 0 frames + XThrowIfError(AudioQueueOfflineRender(myInfo.mQueue, &ts, captureBuffer, 0), "AudioQueueOfflineRender"); + + // we need to enqueue a buffer after the queue has started + AQTestBufferCallback(&myInfo, myInfo.mQueue, myInfo.mBuffer); + + while (true) { + UInt32 reqFrames = captureBufferByteSize / captureFormat.mBytesPerFrame; + + XThrowIfError(AudioQueueOfflineRender(myInfo.mQueue, &ts, captureBuffer, reqFrames), "AudioQueueOfflineRender"); + + captureABL.mBuffers[0].mData = captureBuffer->mAudioData; + captureABL.mBuffers[0].mDataByteSize = captureBuffer->mAudioDataByteSize; + UInt32 writeFrames = captureABL.mBuffers[0].mDataByteSize / captureFormat.mBytesPerFrame; + + printf("t = %.f: AudioQueueOfflineRender: req %d fr/%d bytes, got %ld fr/%d bytes\n", ts.mSampleTime, (int)reqFrames, (int)captureBufferByteSize, writeFrames, (int)captureABL.mBuffers[0].mDataByteSize); + + XThrowIfError(ExtAudioFileWrite(captureFile, writeFrames, &captureABL), "ExtAudioFileWrite"); + + if (myInfo.mFlushed) break; + + ts.mSampleTime += writeFrames; + } + + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false); + + XThrowIfError(AudioQueueDispose(myInfo.mQueue, true), "AudioQueueDispose(true) failed"); + XThrowIfError(AudioFileClose(myInfo.mAudioFile), "AudioQueueDispose(false) failed"); + XThrowIfError(ExtAudioFileDispose(captureFile), "ExtAudioFileDispose failed"); + + if (myInfo.mPacketDescs) delete [] myInfo.mPacketDescs; + if (acl) free(acl); + } + catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + + return; +} \ No newline at end of file diff --git a/AQOfflineRenderTest/en.lproj/MainWindow.xib b/AQOfflineRenderTest/en.lproj/MainWindow.xib new file mode 100644 index 0000000..6015b07 --- /dev/null +++ b/AQOfflineRenderTest/en.lproj/MainWindow.xib @@ -0,0 +1,531 @@ + + + + 544 + 9L30 + 677 + 949.54 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MCAwIDAAA + + NO + NO + YES + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 436} + + 1 + MSAxIDEAA + + NO + + + AQ Offline Render + + + + + + + + 268 + + YES + + + 268 + {{-2250, 100}, {42, 21}} + + + NO + YES + NO + Label + + + 1 + 1.000000e+01 + + + + 292 + {{20, 20}, {280, 420}} + + + + YES + YES + YES + 1 + YES + + + {320, 460} + + + + 3 + MQA + + 2 + + + NO + + + + 292 + + YES + + + 292 + {{62, 153}, {201, 40}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + NO + + + + Render and Play Audio... + + + + + 3 + MAA + + + + + -2147483356 + {{143, 241}, {37, 37}} + + NO + NO + NO + 0 + + + {320, 460} + + NO + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + instructionsView + + + + 26 + + + + contentView + + + + 27 + + + + navigationController + + + + 28 + + + + myViewController + + + + 29 + + + + activityIndicator + + + + 31 + + + + webView + + + + 32 + + + + startButton + + + + 33 + + + + doSomethingAction: + + + 7 + + 36 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 10 + + + YES + + + + + + + 11 + + + YES + + + + + + + 12 + + + + + 13 + + + + + 14 + + + YES + + + + + InstructionsView + + + 18 + + + + + 19 + + + YES + + + + + ContentView + + + 20 + + + + + 21 + + + + + 22 + + + YES + + + + + 30 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 11.CustomClassName + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBEditorWindowLastContentRect + 14.IBPluginDependency + 14.IBViewEditorWindowController.showingLayoutRectangles + 18.IBPluginDependency + 19.IBEditorWindowLastContentRect + 19.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 30.IBPluginDependency + + + YES + UIApplication + UIResponder + {{151, 204}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{133, 77}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{306, 287}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{789, 411}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AQOfflineRenderTestAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 36 + + + + YES + + AQOfflineRenderTestAppDelegate + NSObject + + YES + + YES + myViewController + navigationController + window + + + YES + UIViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/AQOfflineRenderTestAppDelegate.h + + + + MyViewController + UIViewController + + doSomethingAction: + id + + + YES + + YES + activityIndicator + contentView + instructionsView + startButton + webView + + + YES + UIActivityIndicatorView + UIView + UIView + UIButton + UIWebView + + + + IBProjectSource + Classes/MyViewController.h + + + + UIView + UIResponder + + IBUserSource + + + + + + 0 + AQOfflineRenderTest.xcodeproj + 3 + 3.0 + + diff --git a/AQOfflineRenderTest/iPublicUtility/CADebugMacros.h b/AQOfflineRenderTest/iPublicUtility/CADebugMacros.h new file mode 100755 index 0000000..32f3b6e --- /dev/null +++ b/AQOfflineRenderTest/iPublicUtility/CADebugMacros.h @@ -0,0 +1,438 @@ +/* + File: CADebugMacros.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#if !defined(__CADebugMacros_h__) +#define __CADebugMacros_h__ + +//============================================================================= +// Includes +//============================================================================= + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CADebugMacros +//============================================================================= + +//#define CoreAudio_StopOnFailure 1 +//#define CoreAudio_TimeStampMessages 1 +//#define CoreAudio_ThreadStampMessages 1 +//#define CoreAudio_FlushDebugMessages 1 + +#if TARGET_RT_BIG_ENDIAN + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } +#else + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } +#endif + +#pragma mark Basic Definitions + +#if DEBUG || CoreAudio_Debug + + // can be used to break into debugger immediately, also see CADebugger + #define BusError() (*(long *)0 = 0) + + // basic debugging print routines + #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON + extern void DebugStr(const unsigned char* debuggerMsg); + #define DebugMessage(msg) DebugStr("\p"msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #else + #include "CADebugPrintf.h" + + #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) + #define FlushRtn ,fflush(DebugPrintfFile) + #else + #define FlushRtn + #endif + + #if CoreAudio_ThreadStampMessages + #include + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #elif CoreAudio_TimeStampMessages + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #else + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%s"DebugPrintfLineEnding, msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #endif + #endif + void DebugPrint(const char *fmt, ...); // can be used like printf + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) + #endif + #if VERBOSE + #define vprint(msg) DEBUGPRINT(msg) + #else + #define vprint(msg) + #endif + + #if CoreAudio_StopOnFailure + #include "CADebugger.h" + #define STOP CADebuggerStop() + #else + #define STOP + #endif + +#else + #define DebugMessage(msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #define DebugMessageN4(msg, N1, N2, N3, N4) + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) + #define DEBUGPRINT(msg) + #define vprint(msg) + #define STOP +#endif + +void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) +void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) + +#if DEBUG || CoreAudio_Debug + +#pragma mark Debug Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + DebugMessage(inMethodName": Subclasses must implement this method"); \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#else + +#pragma mark Release Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + if((inKernelError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + if((inError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#endif // DEBUG || CoreAudio_Debug + +#endif diff --git a/AQOfflineRenderTest/iPublicUtility/CAMath.h b/AQOfflineRenderTest/iPublicUtility/CAMath.h new file mode 100755 index 0000000..9b1e639 --- /dev/null +++ b/AQOfflineRenderTest/iPublicUtility/CAMath.h @@ -0,0 +1,69 @@ +/* + File: CAMath.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAMath_h__ +#define __CAMath_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +inline bool fiszero(Float64 f) { return (f == 0.); } +inline bool fiszero(Float32 f) { return (f == 0.f); } + +inline bool fnonzero(Float64 f) { return !fiszero(f); } +inline bool fnonzero(Float32 f) { return !fiszero(f); } + +inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } +inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } + +inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } +inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } + +#endif // __CAMath_h__ diff --git a/AQOfflineRenderTest/iPublicUtility/CAStreamBasicDescription.cpp b/AQOfflineRenderTest/iPublicUtility/CAStreamBasicDescription.cpp new file mode 100755 index 0000000..cf25a5f --- /dev/null +++ b/AQOfflineRenderTest/iPublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,550 @@ +/* + File: CAStreamBasicDescription.cpp + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include "CAStreamBasicDescription.h" +#include "CAMath.h" + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +#if TARGET_OS_WIN32 + #include +#endif + +#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; + mReserved = 0; +} + +char *CAStreamBasicDescription::AsString(char *buf, size_t bufsize) const +{ + char *theBuffer = buf; + int nc; + char formatID[5]; + *(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID); + formatID[4] = '\0'; + nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); + buf += nc; bufsize -= nc; + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (wordSize > 0 && PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + sprintf(packed, "packed in %d bytes", wordSize); + else + sprintf(packed, "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + char bitdepth[20]; + +#if CA_PREFER_FIXED_POINT + int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; + if (fracbits > 0) + sprintf(bitdepth, "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); + else +#endif + sprintf(bitdepth, "%d", (int)mBitsPerChannel); + + nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s", + bitdepth, endian, sign, floatInt, + commaSpace, packed, align, deinter); + //buf += nc; bufsize -= nc; + } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless + int sourceBits = 0; + switch (mFormatFlags) + { + case 1: // kAppleLosslessFormatFlag_16BitSourceData + sourceBits = 16; + break; + case 2: // kAppleLosslessFormatFlag_20BitSourceData + sourceBits = 20; + break; + case 3: // kAppleLosslessFormatFlag_24BitSourceData + sourceBits = 24; + break; + case 4: // kAppleLosslessFormatFlag_32BitSourceData + sourceBits = 32; + break; + } + if (sourceBits) + nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits); + else + nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, "); + buf += nc; bufsize -= nc; + nc = snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket); + //buf += nc; bufsize -= nc; + } + else + nc = snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", + (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); + return theBuffer; +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format + if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) + { + // the canonical linear PCM format + ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; + ioDescription.mBytesPerPacket = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerFrame = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType); + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(fiszero(ioDescription.mSampleRate)) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + const char* theMixabilityString = NULL; + if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) + { + theMixabilityString = "Mixable"; + } + else + { + theMixabilityString = "Unmixable"; + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strcpy(outName, "AC-3"); + break; + + case kAudioFormat60958AC3: + strcpy(outName, "AC-3 for SPDIF"); + break; + + default: + CACopy4CCToCString(outName, inDescription.mFormatID); + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + + // mixable is always better than non-mixable for linear PCM and should be the second order sort item + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) + { + theAnswer = true; + isDone = true; + } + else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) + { + theAnswer = false; + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) + { + if(fnotequal(x.mSampleRate, y.mSampleRate)) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + + // if the number of channels is 0 or 1, we don't care about non-interleavedness + if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) { + xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const +{ + if (interpretingWildcards) + return *this == other; + return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0.) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024); +} diff --git a/AQOfflineRenderTest/iPublicUtility/CAStreamBasicDescription.h b/AQOfflineRenderTest/iPublicUtility/CAStreamBasicDescription.h new file mode 100755 index 0000000..4169bdf --- /dev/null +++ b/AQOfflineRenderTest/iPublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,307 @@ +/* + File: CAStreamBasicDescription.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CoreFoundation.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it + +// define Leopard specific symbols for backward compatibility if applicable +#if COREAUDIOTYPES_VERSION < 1050 +typedef Float32 AudioSampleType; +enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; +#endif +#if COREAUDIOTYPES_VERSION < 1051 +typedef Float32 AudioUnitSampleType; +#endif + +// define the IsMixable format flag for all versions of the system +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; +#else + enum { kIsNonMixableFlag = (1L << 6) }; +#endif + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { + return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; + } + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; +#if CA_ENV_MACOSX + int sampleSize = sizeof(Float32); + mFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + int sampleSize = sizeof(AudioSampleType); + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mBitsPerChannel = 8 * sampleSize; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; + else { + mBytesPerPacket = mBytesPerFrame = sampleSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + bool IsCanonical() const + { + if (mFormatID != kAudioFormatLinearPCM) return false; + UInt32 reqFormatFlags; +#if (COREAUDIOTYPES_VERSION <= 1050) + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh); +#else + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); +#endif + bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; +#if CA_ENV_MACOSX + unsigned sampleSize = sizeof(Float32); + reqFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + unsigned sampleSize = sizeof(AudioSampleType); + reqFormatFlags = kAudioFormatFlagsCanonical; +#endif + UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; + + return ((mFormatFlags & flagsMask) == reqFormatFlags + && mBitsPerChannel == 8 * sampleSize + && mFramesPerPacket == 1 + && mBytesPerFrame == reqFrameSize + && mBytesPerPacket == reqFrameSize); + } + + void SetAUCanonical(UInt32 nChannels, bool interleaved) + { + mFormatID = kAudioFormatLinearPCM; +#if CA_PREFER_FIXED_POINT + mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); +#else + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); + else { + mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + if (wordSize == 0) + wordSize = (mBitsPerChannel + 7) / 8; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; + + void Print() const { + Print (stdout); + } + + void Print(FILE* file) const { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const { + char buf[256]; + fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); + } + + void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline + char buf[256]; + fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); + } + + char * AsString(char *buf, size_t bufsize) const; + + static void Print (const AudioStreamBasicDescription &inDesc) + { + CAStreamBasicDescription desc(inDesc); + desc.Print (); + } + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__ diff --git a/AQOfflineRenderTest/iPublicUtility/CAXException.cpp b/AQOfflineRenderTest/iPublicUtility/CAXException.cpp new file mode 100644 index 0000000..db2aeca --- /dev/null +++ b/AQOfflineRenderTest/iPublicUtility/CAXException.cpp @@ -0,0 +1,50 @@ +/* + File: CAXException.cpp + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include "CAXException.h" + +CAXException::WarningHandler CAXException::sWarningHandler = NULL; diff --git a/AQOfflineRenderTest/iPublicUtility/CAXException.h b/AQOfflineRenderTest/iPublicUtility/CAXException.h new file mode 100644 index 0000000..85d9278 --- /dev/null +++ b/AQOfflineRenderTest/iPublicUtility/CAXException.h @@ -0,0 +1,196 @@ +/* + File: CAXException.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAXException_h__ +#define __CAXException_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif +#include "CADebugMacros.h" +#include +#include +#include + +// An extended exception class that includes the name of the failed operation +class CAXException { +public: + CAXException(const char *operation, OSStatus err) : + mError(err) + { + if (operation == NULL) + mOperation[0] = '\0'; + else if (strlen(operation) >= sizeof(mOperation)) { + memcpy(mOperation, operation, sizeof(mOperation) - 1); + mOperation[sizeof(mOperation) - 1] = '\0'; + } else + strcpy(mOperation, operation); + } + + char *FormatError(char *str) const + { + return FormatError(str, mError); + } + + char mOperation[256]; + const OSStatus mError; + + // ------------------------------------------------- + + typedef void (*WarningHandler)(const char *msg, OSStatus err); + + /*static void Throw(const char *operation, OSStatus err) + { + throw CAXException(operation, err); + }*/ + + static char *FormatError(char *str, OSStatus error) + { + // see if it appears to be a 4-char-code + *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); + if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { + str[0] = str[5] = '\''; + str[6] = '\0'; + } else + // no, format it as an integer + sprintf(str, "%d", (int)error); + return str; + } + + static void Warning(const char *s, OSStatus error) + { + if (sWarningHandler) + (*sWarningHandler)(s, error); + } + + static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } +private: + static WarningHandler sWarningHandler; +}; + +#if DEBUG || CoreAudio_Debug + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + } \ + } while (0) + +#else + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + /*OSStatus __err =*/ error; \ + } while (0) +#endif + +#define XThrow(error, operation) XThrowIf(true, error, operation) +#define XThrowIfErr(error) XThrowIfError(error, #error) + +#endif // __CAXException_h__ diff --git a/AQOfflineRenderTest/images/Icon-72.png b/AQOfflineRenderTest/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/AQOfflineRenderTest/images/Icon-72.png differ diff --git a/AQOfflineRenderTest/images/Icon-Small-50.png b/AQOfflineRenderTest/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/AQOfflineRenderTest/images/Icon-Small-50.png differ diff --git a/AQOfflineRenderTest/images/Icon-Small.png b/AQOfflineRenderTest/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/AQOfflineRenderTest/images/Icon-Small.png differ diff --git a/AQOfflineRenderTest/images/Icon-Small@2x.png b/AQOfflineRenderTest/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/AQOfflineRenderTest/images/Icon-Small@2x.png differ diff --git a/AQOfflineRenderTest/images/Icon.png b/AQOfflineRenderTest/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/AQOfflineRenderTest/images/Icon.png differ diff --git a/AQOfflineRenderTest/images/Icon@2x.png b/AQOfflineRenderTest/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/AQOfflineRenderTest/images/Icon@2x.png differ diff --git a/AQOfflineRenderTest/images/iTunesArtwork b/AQOfflineRenderTest/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/AQOfflineRenderTest/images/iTunesArtwork differ diff --git a/AQOfflineRenderTest/main.m b/AQOfflineRenderTest/main.m new file mode 100644 index 0000000..7c621b1 --- /dev/null +++ b/AQOfflineRenderTest/main.m @@ -0,0 +1,54 @@ +// File: main.m +// Abstract: n/a +// Version: 1.2 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +// Inc. ("Apple") in consideration of your agreement to the following +// terms, and your use, installation, modification or redistribution of +// this Apple software constitutes acceptance of these terms. If you do +// not agree with these terms, please do not use, install, modify or +// redistribute this Apple software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non-exclusive +// license, under Apple's copyrights in this original Apple software (the +// "Apple Software"), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and/or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following +// text and disclaimers in all such redistributions of the Apple Software. +// Neither the name, trademarks, service marks or logos of Apple Inc. may +// be used to endorse or promote products derived from the Apple Software +// without specific prior written permission from Apple. Except as +// expressly stated in this notice, no other rights or licenses, express or +// implied, are granted by Apple herein, including but not limited to any +// patent rights that may be infringed by your derivative works or by other +// works in which the Apple Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE +// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (C) 2010 Apple Inc. All Rights Reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/AccelerometerGraph.zip b/AccelerometerGraph.zip new file mode 100644 index 0000000..a0ccf5f Binary files /dev/null and b/AccelerometerGraph.zip differ diff --git a/AccelerometerGraph/AccelerometerFilter.h b/AccelerometerGraph/AccelerometerFilter.h new file mode 100644 index 0000000..a6ed7b8 --- /dev/null +++ b/AccelerometerGraph/AccelerometerFilter.h @@ -0,0 +1,89 @@ +/* + File: AccelerometerFilter.h + Abstract: Implements a low and high pass filter with optional adaptive filtering. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +// Basic filter object. +@interface AccelerometerFilter : NSObject +{ + BOOL adaptive; + UIAccelerationValue x, y, z; +} + +// Add a UIAcceleration to the filter. +-(void)addAcceleration:(UIAcceleration*)accel; + +@property(nonatomic, readonly) UIAccelerationValue x; +@property(nonatomic, readonly) UIAccelerationValue y; +@property(nonatomic, readonly) UIAccelerationValue z; + +@property(nonatomic, getter=isAdaptive) BOOL adaptive; +@property(nonatomic, readonly) NSString *name; + +@end + +// A filter class to represent a lowpass filter +@interface LowpassFilter : AccelerometerFilter +{ + double filterConstant; + UIAccelerationValue lastX, lastY, lastZ; +} + +-(id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq; + +@end + +// A filter class to represent a highpass filter. +@interface HighpassFilter : AccelerometerFilter +{ + double filterConstant; + UIAccelerationValue lastX, lastY, lastZ; +} + +-(id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq; + +@end \ No newline at end of file diff --git a/AccelerometerGraph/AccelerometerFilter.m b/AccelerometerGraph/AccelerometerFilter.m new file mode 100644 index 0000000..6353ca8 --- /dev/null +++ b/AccelerometerGraph/AccelerometerFilter.m @@ -0,0 +1,164 @@ +/* + File: AccelerometerFilter.m + Abstract: Implements a low and high pass filter with optional adaptive filtering. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AccelerometerFilter.h" + +// Implementation of the basic filter. All it does is mirror input to output. + +@implementation AccelerometerFilter + +@synthesize x, y, z, adaptive; + +-(void)addAcceleration:(UIAcceleration*)accel +{ + x = accel.x; + y = accel.y; + z = accel.z; +} + +-(NSString*)name +{ + return @"You should not see this"; +} + +@end + +#define kAccelerometerMinStep 0.02 +#define kAccelerometerNoiseAttenuation 3.0 + +double Norm(double x, double y, double z) +{ + return sqrt(x * x + y * y + z * z); +} + +double Clamp(double v, double min, double max) +{ + if(v > max) + return max; + else if(v < min) + return min; + else + return v; +} + +// See http://en.wikipedia.org/wiki/Low-pass_filter for details low pass filtering +@implementation LowpassFilter + +-(id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq +{ + self = [super init]; + if(self != nil) + { + double dt = 1.0 / rate; + double RC = 1.0 / freq; + filterConstant = dt / (dt + RC); + } + return self; +} + +-(void)addAcceleration:(UIAcceleration*)accel +{ + double alpha = filterConstant; + + if(adaptive) + { + double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0); + alpha = (1.0 - d) * filterConstant / kAccelerometerNoiseAttenuation + d * filterConstant; + } + + x = accel.x * alpha + x * (1.0 - alpha); + y = accel.y * alpha + y * (1.0 - alpha); + z = accel.z * alpha + z * (1.0 - alpha); +} + +-(NSString*)name +{ + return adaptive ? @"Adaptive Lowpass Filter" : @"Lowpass Filter"; +} + +@end + +// See http://en.wikipedia.org/wiki/High-pass_filter for details on high pass filtering +@implementation HighpassFilter + +-(id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq +{ + self = [super init]; + if(self != nil) + { + double dt = 1.0 / rate; + double RC = 1.0 / freq; + filterConstant = RC / (dt + RC); + } + return self; +} + +-(void)addAcceleration:(UIAcceleration*)accel +{ + double alpha = filterConstant; + + if(adaptive) + { + double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0); + alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0 - d) * filterConstant; + } + + x = alpha * (x + accel.x - lastX); + y = alpha * (y + accel.y - lastY); + z = alpha * (z + accel.z - lastZ); + + lastX = accel.x; + lastY = accel.y; + lastZ = accel.z; +} + +-(NSString*)name +{ + return adaptive ? @"Adaptive Highpass Filter" : @"Highpass Filter"; +} + +@end \ No newline at end of file diff --git a/AccelerometerGraph/AccelerometerGraph.xcodeproj/project.pbxproj b/AccelerometerGraph/AccelerometerGraph.xcodeproj/project.pbxproj new file mode 100755 index 0000000..9d86db4 --- /dev/null +++ b/AccelerometerGraph/AccelerometerGraph.xcodeproj/project.pbxproj @@ -0,0 +1,346 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 14D2E8F90DEF831F00195E03 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 14D2E8F80DEF831F00195E03 /* MainWindow.xib */; }; + 188D3E9A0D6D207B0076AE1E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 18AD69BC11D559E7005232E4 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69B511D559E7005232E4 /* Icon-72.png */; }; + 18AD69BD11D559E7005232E4 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69B611D559E7005232E4 /* Icon-Small-50.png */; }; + 18AD69BE11D559E7005232E4 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69B711D559E7005232E4 /* Icon-Small.png */; }; + 18AD69BF11D559E7005232E4 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69B811D559E7005232E4 /* Icon-Small@2x.png */; }; + 18AD69C011D559E7005232E4 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69B911D559E7005232E4 /* Icon.png */; }; + 18AD69C111D559E7005232E4 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69BA11D559E7005232E4 /* Icon@2x.png */; }; + 18AD69C211D559E7005232E4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18AD69BB11D559E7005232E4 /* iTunesArtwork */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 30D873970D76212900B213B8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 30D873960D76212900B213B8 /* AppDelegate.m */; }; + 6390467F0F7C386600F2FB94 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6390467E0F7C386600F2FB94 /* MainViewController.m */; }; + 639046B00F7C400300F2FB94 /* AccelerometerFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 639046AF0F7C400300F2FB94 /* AccelerometerFilter.m */; }; + 6390470D0F7C4B3B00F2FB94 /* GraphView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6390470C0F7C4B3B00F2FB94 /* GraphView.m */; }; + 639A50BA0FDB1BC9007BE898 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 639A50B80FDB1BC9007BE898 /* Localizable.strings */; }; + 63ABFA440FDDCA4800218D27 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63ABFA420FDDCA4800218D27 /* MainViewController.xib */; }; + 63D21B500F93E74800361BAB /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D21B4F0F93E74800361BAB /* QuartzCore.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 14D2E8FA0DEF831F00195E03 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 14D8295D0DB6E14B00198EC5 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 18AD69B511D559E7005232E4 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18AD69B611D559E7005232E4 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18AD69B711D559E7005232E4 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18AD69B811D559E7005232E4 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18AD69B911D559E7005232E4 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18AD69BA11D559E7005232E4 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18AD69BB11D559E7005232E4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* AccelerometerGraph.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AccelerometerGraph.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 30D873950D76212900B213B8 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 30D873960D76212900B213B8 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 6390467D0F7C386600F2FB94 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 6390467E0F7C386600F2FB94 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 639046AE0F7C400300F2FB94 /* AccelerometerFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccelerometerFilter.h; sourceTree = ""; }; + 639046AF0F7C400300F2FB94 /* AccelerometerFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AccelerometerFilter.m; sourceTree = ""; }; + 6390470B0F7C4B3B00F2FB94 /* GraphView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphView.h; sourceTree = ""; }; + 6390470C0F7C4B3B00F2FB94 /* GraphView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GraphView.m; sourceTree = ""; }; + 639A50B90FDB1BC9007BE898 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 63ABFA430FDDCA4800218D27 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainViewController.xib; sourceTree = ""; }; + 63D21B4F0F93E74800361BAB /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 188D3E9A0D6D207B0076AE1E /* CoreGraphics.framework in Frameworks */, + 63D21B500F93E74800361BAB /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* AccelerometerGraph.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 14D8295D0DB6E14B00198EC5 /* ReadMe.txt */, + 2D500B1D0D5A766B00DBA0E3 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18AD69B511D559E7005232E4 /* Icon-72.png */, + 18AD69B611D559E7005232E4 /* Icon-Small-50.png */, + 18AD69B711D559E7005232E4 /* Icon-Small.png */, + 18AD69B811D559E7005232E4 /* Icon-Small@2x.png */, + 18AD69B911D559E7005232E4 /* Icon.png */, + 18AD69BA11D559E7005232E4 /* Icon@2x.png */, + 18AD69BB11D559E7005232E4 /* iTunesArtwork */, + 63ABFA420FDDCA4800218D27 /* MainViewController.xib */, + 14D2E8F80DEF831F00195E03 /* MainWindow.xib */, + 639A50B80FDB1BC9007BE898 /* Localizable.strings */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 63D21B4F0F93E74800361BAB /* QuartzCore.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2D500B1D0D5A766B00DBA0E3 /* Classes */ = { + isa = PBXGroup; + children = ( + 639046AE0F7C400300F2FB94 /* AccelerometerFilter.h */, + 639046AF0F7C400300F2FB94 /* AccelerometerFilter.m */, + 30D873950D76212900B213B8 /* AppDelegate.h */, + 30D873960D76212900B213B8 /* AppDelegate.m */, + 6390467D0F7C386600F2FB94 /* MainViewController.h */, + 6390467E0F7C386600F2FB94 /* MainViewController.m */, + 6390470B0F7C4B3B00F2FB94 /* GraphView.h */, + 6390470C0F7C4B3B00F2FB94 /* GraphView.m */, + ); + name = Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* AccelerometerGraph */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AccelerometerGraph" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AccelerometerGraph; + productName = AccelerometerGraph; + productReference = 1D6058910D05DD3D006BFB54 /* AccelerometerGraph.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AccelerometerGraph" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* AccelerometerGraph */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 14D2E8F90DEF831F00195E03 /* MainWindow.xib in Resources */, + 639A50BA0FDB1BC9007BE898 /* Localizable.strings in Resources */, + 63ABFA440FDDCA4800218D27 /* MainViewController.xib in Resources */, + 18AD69BC11D559E7005232E4 /* Icon-72.png in Resources */, + 18AD69BD11D559E7005232E4 /* Icon-Small-50.png in Resources */, + 18AD69BE11D559E7005232E4 /* Icon-Small.png in Resources */, + 18AD69BF11D559E7005232E4 /* Icon-Small@2x.png in Resources */, + 18AD69C011D559E7005232E4 /* Icon.png in Resources */, + 18AD69C111D559E7005232E4 /* Icon@2x.png in Resources */, + 18AD69C211D559E7005232E4 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 30D873970D76212900B213B8 /* AppDelegate.m in Sources */, + 6390467F0F7C386600F2FB94 /* MainViewController.m in Sources */, + 639046B00F7C400300F2FB94 /* AccelerometerFilter.m in Sources */, + 6390470D0F7C4B3B00F2FB94 /* GraphView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 14D2E8F80DEF831F00195E03 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 14D2E8FA0DEF831F00195E03 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 639A50B80FDB1BC9007BE898 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 639A50B90FDB1BC9007BE898 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 63ABFA420FDDCA4800218D27 /* MainViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 63ABFA430FDDCA4800218D27 /* en */, + ); + name = MainViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = AccelerometerGraph; + WARNING_CFLAGS = "-Wall"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = AccelerometerGraph; + WARNING_CFLAGS = "-Wall"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AccelerometerGraph" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AccelerometerGraph" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/AccelerometerGraph/AppDelegate.h b/AccelerometerGraph/AppDelegate.h new file mode 100644 index 0000000..06e8a66 --- /dev/null +++ b/AccelerometerGraph/AppDelegate.h @@ -0,0 +1,57 @@ +/* + File: AppDelegate.h +Abstract: Responsbile for loading the initial UI and responding to application events. + Version: 2.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UIViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UIViewController *viewController; + +@end \ No newline at end of file diff --git a/AccelerometerGraph/AppDelegate.m b/AccelerometerGraph/AppDelegate.m new file mode 100644 index 0000000..17dd70f --- /dev/null +++ b/AccelerometerGraph/AppDelegate.m @@ -0,0 +1,69 @@ +/* + File: AppDelegate.m +Abstract: Responsbile for loading the initial UI and responding to application events. + Version: 2.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "MainViewController.h" + +@implementation AppDelegate + +@synthesize window, viewController; + +-(void)applicationDidFinishLaunching:(UIApplication*)application +{ + // Add the view controller's view to the window + [window addSubview:viewController.view]; +} + +// Release resources. +-(void)dealloc +{ + [window release]; + [viewController release]; + [super dealloc]; +} + +@end diff --git a/AccelerometerGraph/GraphView.h b/AccelerometerGraph/GraphView.h new file mode 100644 index 0000000..3632982 --- /dev/null +++ b/AccelerometerGraph/GraphView.h @@ -0,0 +1,62 @@ +/* + File: GraphView.h + Abstract: Displays a graph of accelerometer output using. This class uses Core Animation techniques to avoid needing to render the entire graph every update + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +@class GraphViewSegment; +@class GraphTextView; +@interface GraphView : UIView +{ + NSMutableArray *segments; + GraphViewSegment *current; // weak reference + GraphTextView *text; // weak reference +} + +-(void)addX:(UIAccelerationValue)x y:(UIAccelerationValue)y z:(UIAccelerationValue)z; + +@end diff --git a/AccelerometerGraph/GraphView.m b/AccelerometerGraph/GraphView.m new file mode 100644 index 0000000..2de6f10 --- /dev/null +++ b/AccelerometerGraph/GraphView.m @@ -0,0 +1,520 @@ +/* + File: GraphView.m + Abstract: Displays a graph of accelerometer output using. This class uses Core Animation techniques to avoid needing to render the entire graph every update + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "GraphView.h" + +#pragma mark - Overview of operation + +// The GraphView class needs to be able to update the scene quickly in order to track the accelerometer data +// at a fast enough frame rate. The naive implementation tries to draw the entire graph every frame, +// but unfortunately that is too much content to sustain a high framerate. As such this class uses CALayers +// to cache previously drawn content and arranges them carefully to create an illusion that we are +// redrawing the entire graph every frame. + +#pragma mark - Quartz Helpers + +// Functions used to draw all content + +CGColorRef CreateDeviceGrayColor(CGFloat w, CGFloat a) +{ + CGColorSpaceRef gray = CGColorSpaceCreateDeviceGray(); + CGFloat comps[] = {w, a}; + CGColorRef color = CGColorCreate(gray, comps); + CGColorSpaceRelease(gray); + return color; +} + +CGColorRef CreateDeviceRGBColor(CGFloat r, CGFloat g, CGFloat b, CGFloat a) +{ + CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); + CGFloat comps[] = {r, g, b, a}; + CGColorRef color = CGColorCreate(rgb, comps); + CGColorSpaceRelease(rgb); + return color; +} + +CGColorRef graphBackgroundColor() +{ + static CGColorRef c = NULL; + if(c == NULL) + { + c = CreateDeviceGrayColor(0.6, 1.0); + } + return c; +} + +CGColorRef graphLineColor() +{ + static CGColorRef c = NULL; + if(c == NULL) + { + c = CreateDeviceGrayColor(0.5, 1.0); + } + return c; +} + +CGColorRef graphXColor() +{ + static CGColorRef c = NULL; + if(c == NULL) + { + c = CreateDeviceRGBColor(1.0, 0.0, 0.0, 1.0); + } + return c; +} + +CGColorRef graphYColor() +{ + static CGColorRef c = NULL; + if(c == NULL) + { + c = CreateDeviceRGBColor(0.0, 1.0, 0.0, 1.0); + } + return c; +} + +CGColorRef graphZColor() +{ + static CGColorRef c = NULL; + if(c == NULL) + { + c = CreateDeviceRGBColor(0.0, 0.0, 1.0, 1.0); + } + return c; +} + +void DrawGridlines(CGContextRef context, CGFloat x, CGFloat width) +{ + for(CGFloat y = -48.5; y <= 48.5; y += 16.0) + { + CGContextMoveToPoint(context, x, y); + CGContextAddLineToPoint(context, x + width, y); + } + CGContextSetStrokeColorWithColor(context, graphLineColor()); + CGContextStrokePath(context); +} + +#pragma mark - GraphViewSegment + +// The GraphViewSegment manages up to 32 accelerometer values and a CALayer that it updates with +// the segment of the graph that those values represent. + +@interface GraphViewSegment : NSObject +{ + CALayer *layer; + // Need 33 values to fill 32 pixel width. + UIAccelerationValue xhistory[33]; + UIAccelerationValue yhistory[33]; + UIAccelerationValue zhistory[33]; + int index; +} + +// returns true if adding this value fills the segment, which is necessary for properly updating the segments +-(BOOL)addX:(UIAccelerationValue)x y:(UIAccelerationValue)y z:(UIAccelerationValue)z; + +// When this object gets recycled (when it falls off the end of the graph) +// -reset is sent to clear values and prepare for reuse. +-(void)reset; + +// Returns true if this segment has consumed 32 values. +-(BOOL)isFull; + +// Returns true if the layer for this segment is visible in the given rect. +-(BOOL)isVisibleInRect:(CGRect)r; + +// The layer that this segment is drawing into +@property(nonatomic, readonly) CALayer *layer; + +@end + +@implementation GraphViewSegment + +@synthesize layer; + +-(id)init +{ + self = [super init]; + if(self != nil) + { + layer = [[CALayer alloc] init]; + // the layer will call our -drawLayer:inContext: method to provide content + // and our -actionForLayer:forKey: for implicit animations + layer.delegate = self; + // This sets our coordinate system such that it has an origin of 0.0,-56 and a size of 32,112. + // This would need to be changed if you change either the number of pixel values that a segment + // represented, or if you changed the size of the graph view. + layer.bounds = CGRectMake(0.0, -56.0, 32.0, 112.0); + // Disable blending as this layer consists of non-transperant content. + // Unlike UIView, a CALayer defaults to opaque=NO + layer.opaque = YES; + // Index represents how many slots are left to be filled in the graph, + // which is also +1 compared to the array index that a new entry will be added + index = 33; + } + return self; +} + +-(void)dealloc +{ + [layer release]; + [super dealloc]; +} + +-(void)reset +{ + // Clear out our components and reset the index to 33 to start filling values again... + memset(xhistory, 0, sizeof(xhistory)); + memset(yhistory, 0, sizeof(yhistory)); + memset(zhistory, 0, sizeof(zhistory)); + index = 33; + // Inform Core Animation that we need to redraw this layer. + [layer setNeedsDisplay]; +} + +-(BOOL)isFull +{ + // Simple, this segment is full if there are no more space in the history. + return index == 0; +} + +-(BOOL)isVisibleInRect:(CGRect)r +{ + // Just check if there is an intersection between the layer's frame and the given rect. + return CGRectIntersectsRect(r, layer.frame); +} + +-(BOOL)addX:(UIAccelerationValue)x y:(UIAccelerationValue)y z:(UIAccelerationValue)z +{ + // If this segment is not full, then we add a new acceleration value to the history. + if(index > 0) + { + // First decrement, both to get to a zero-based index and to flag one fewer position left + --index; + xhistory[index] = x; + yhistory[index] = y; + zhistory[index] = z; + // And inform Core Animation to redraw the layer. + [layer setNeedsDisplay]; + } + // And return if we are now full or not (really just avoids needing to call isFull after adding a value). + return index == 0; +} + +-(void)drawLayer:(CALayer*)l inContext:(CGContextRef)context +{ + // Fill in the background + CGContextSetFillColorWithColor(context, graphBackgroundColor()); + CGContextFillRect(context, layer.bounds); + + // Draw the grid lines + DrawGridlines(context, 0.0, 32.0); + + // Draw the graph + CGPoint lines[64]; + int i; + + // X + for(i = 0; i < 32; ++i) + { + lines[i*2].x = i; + lines[i*2].y = -xhistory[i] * 16.0; + lines[i*2+1].x = i + 1; + lines[i*2+1].y = -xhistory[i+1] * 16.0; + } + CGContextSetStrokeColorWithColor(context, graphXColor()); + CGContextStrokeLineSegments(context, lines, 64); + + // Y + for(i = 0; i < 32; ++i) + { + lines[i*2].y = -yhistory[i] * 16.0; + lines[i*2+1].y = -yhistory[i+1] * 16.0; + } + CGContextSetStrokeColorWithColor(context, graphYColor()); + CGContextStrokeLineSegments(context, lines, 64); + + // Z + for(i = 0; i < 32; ++i) + { + lines[i*2].y = -zhistory[i] * 16.0; + lines[i*2+1].y = -zhistory[i+1] * 16.0; + } + CGContextSetStrokeColorWithColor(context, graphZColor()); + CGContextStrokeLineSegments(context, lines, 64); +} + +-(id)actionForLayer:(CALayer *)layer forKey :(NSString *)key +{ + // We disable all actions for the layer, so no content cross fades, no implicit animation on moves, etc. + return [NSNull null]; +} + +// The accessibilityValue of this segment should be the x,y,z values last added. +- (NSString *)accessibilityValue +{ + return [NSString stringWithFormat:NSLocalizedString(@"graphSegmentFormat", @""), xhistory[index], yhistory[index], zhistory[index]]; +} + +@end + +#pragma mark - GraphTextView + +// We use a seperate view to draw the text for the graph so that we can layer the segment layers below it +// which gives the illusion that the numbers are draw over the graph, and hides the fact that the graph drawing +// for each segment is incomplete until the segment is filled. + +@interface GraphTextView : UIView +{ +} + +@end + +@implementation GraphTextView + +-(void)drawRect:(CGRect)rect +{ + CGContextRef context = UIGraphicsGetCurrentContext(); + + // Fill in the background + CGContextSetFillColorWithColor(context, graphBackgroundColor()); + CGContextFillRect(context, self.bounds); + + CGContextTranslateCTM(context, 0.0, 56.0); + + // Draw the grid lines + DrawGridlines(context, 26.0, 6.0); + + // Draw the text + UIFont *systemFont = [UIFont systemFontOfSize:12.0]; + [[UIColor whiteColor] set]; + [@"+3.0" drawInRect:CGRectMake(2.0, -56.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + [@"+2.0" drawInRect:CGRectMake(2.0, -40.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + [@"+1.0" drawInRect:CGRectMake(2.0, -24.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + [@" 0.0" drawInRect:CGRectMake(2.0, -8.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + [@"-1.0" drawInRect:CGRectMake(2.0, 8.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + [@"-2.0" drawInRect:CGRectMake(2.0, 24.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + [@"-3.0" drawInRect:CGRectMake(2.0, 40.0, 24.0, 16.0) withFont:systemFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; +} + +@end + +#pragma mark - GraphView + +// Finally the actual GraphView class. This class handles the public interface as well as arranging +// the subviews and sublayers to produce the intended effect. + +@interface GraphView() + +// Internal accessors +@property(nonatomic, retain) NSMutableArray *segments; +@property(nonatomic, assign) GraphViewSegment *current; +@property(nonatomic, assign) GraphTextView *text; + +// A common init routine for use with -initWithFrame: and -initWithCoder: +-(void)commonInit; + +// Creates a new segment, adds it to 'segments', and returns a weak reference to that segment +// Typically a graph will have around a dozen segments, but this depends on the width of the graph view and segments +-(GraphViewSegment*)addSegment; + +// Recycles a segment from 'segments' into 'current' +-(void)recycleSegment; +@end + +@implementation GraphView + +@synthesize segments, current, text; + +// Designated initializer +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + [self commonInit]; + } + return self; +} + +// Designated initializer +-(id)initWithCoder:(NSCoder*)decoder +{ + self = [super initWithCoder:decoder]; + if(self != nil) + { + [self commonInit]; + } + return self; +} + +-(void)commonInit +{ + // Create the text view and add it as a subview. We keep a weak reference + // to that view afterwards for laying out the segment layers. + text = [[GraphTextView alloc] initWithFrame:CGRectMake(0.0, 0.0, 32.0, 112.0)]; + [self addSubview:text]; + [text release]; + + // Create a mutable array to store segments, which is required by -addSegment + segments = [[NSMutableArray alloc] init]; + + // Create a new current segment, which is required by -addX:y:z and other methods. + // This is also a weak reference (we assume that the 'segments' array will keep the strong reference). + current = [self addSegment]; +} + +-(void)dealloc +{ + // Since 'text' and 'current' are weak references, we do not release them here. + // [super dealloc] will take care to release 'text' as a subview, and releasing 'segments' will release 'current'. + [segments release]; + [super dealloc]; +} + +-(void)addX:(UIAccelerationValue)x y:(UIAccelerationValue)y z:(UIAccelerationValue)z +{ + // First, add the new acceleration value to the current segment + if([current addX:x y:y z:z]) + { + // If after doing that we've filled up the current segment, then we need to + // determine the next current segment + [self recycleSegment]; + // And to keep the graph looking continuous, we add the acceleration value to the new segment as well. + [current addX:x y:y z:z]; + } + // After adding a new data point, we need to advance the x-position of all the segment layers by 1 to + // create the illusion that the graph is advancing. + for(GraphViewSegment * s in segments) + { + CGPoint position = s.layer.position; + position.x += 1.0; + s.layer.position = position; + } +} + +// The initial position of a segment that is meant to be displayed on the left side of the graph. +// This positioning is meant so that a few entries must be added to the segment's history before it becomes +// visible to the user. This value could be tweaked a little bit with varying results, but the X coordinate +// should never be larger than 16 (the center of the text view) or the zero values in the segment's history +// will be exposed to the user. +#define kSegmentInitialPosition CGPointMake(14.0, 56.0); + +-(GraphViewSegment*)addSegment +{ + // Create a new segment and add it to the segments array. + GraphViewSegment * segment = [[GraphViewSegment alloc] init]; + // We add it at the front of the array because -recycleSegment expects the oldest segment + // to be at the end of the array. As long as we always insert the youngest segment at the front + // this will be true. + [segments insertObject:segment atIndex:0]; + [segment release]; // this is now a weak reference + + // Ensure that newly added segment layers are placed after the text view's layer so that the text view + // always renders above the segment layer. + [self.layer insertSublayer:segment.layer below:text.layer]; + // Position it properly (see the comment for kSegmentInitialPosition) + segment.layer.position = kSegmentInitialPosition; + + return segment; +} + +-(void)recycleSegment +{ + // We start with the last object in the segments array, as it should either be visible onscreen, + // which indicates that we need more segments, or pushed offscreen which makes it eligable for recycling. + GraphViewSegment * last = [segments lastObject]; + if([last isVisibleInRect:self.layer.bounds]) + { + // The last segment is still visible, so create a new segment, which is now the current segment + current = [self addSegment]; + } + else + { + // The last segment is no longer visible, so we reset it in preperation to be recycled. + [last reset]; + // Position it properly (see the comment for kSegmentInitialPosition) + last.layer.position = kSegmentInitialPosition; + // Move the segment from the last position in the array to the first position in the array + // as it is now the youngest segment. + [segments insertObject:last atIndex:0]; + [segments removeLastObject]; + // And make it our current segment + current = last; + } +} + +// The graph view itself exists only to draw the background and gridlines. All other content is drawn either into +// the GraphTextView or into a layer managed by a GraphViewSegment. +-(void)drawRect:(CGRect)rect +{ + CGContextRef context = UIGraphicsGetCurrentContext(); + // Fill in the background + CGContextSetFillColorWithColor(context, graphBackgroundColor()); + CGContextFillRect(context, self.bounds); + + CGFloat width = self.bounds.size.width; + CGContextTranslateCTM(context, 0.0, 56.0); + + // Draw the grid lines + DrawGridlines(context, 0.0, width); +} + + +// Return an up-to-date value for the graph. +- (NSString *)accessibilityValue +{ + if (segments.count == 0) + { + return nil; + } + + // Let the GraphViewSegment handle its own accessibilityValue; + GraphViewSegment *graphViewSegment = [segments objectAtIndex:0]; + return [graphViewSegment accessibilityValue]; +} + +@end diff --git a/AccelerometerGraph/Info.plist b/AccelerometerGraph/Info.plist new file mode 100644 index 0000000..d07331b --- /dev/null +++ b/AccelerometerGraph/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleVersion + 2.5 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/AccelerometerGraph/MainViewController.h b/AccelerometerGraph/MainViewController.h new file mode 100644 index 0000000..43f318e --- /dev/null +++ b/AccelerometerGraph/MainViewController.h @@ -0,0 +1,72 @@ +/* + File: MainViewController.h + Abstract: Responsible for all UI interactions with the user and the accelerometer + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class GraphView; +@class AccelerometerFilter; + +@interface MainViewController : UIViewController +{ + GraphView *unfiltered; + GraphView *filtered; + UIBarButtonItem *pause; + UILabel *filterLabel; + AccelerometerFilter *filter; + BOOL isPaused, useAdaptive; +} + +@property(nonatomic, retain) IBOutlet GraphView *unfiltered; +@property(nonatomic, retain) IBOutlet GraphView *filtered; +@property(nonatomic, retain) IBOutlet UIBarButtonItem *pause; +@property(nonatomic, retain) IBOutlet UILabel *filterLabel; + +-(IBAction)pauseOrResume:(id)sender; +-(IBAction)filterSelect:(id)sender; +-(IBAction)adaptiveSelect:(id)sender; + +@end \ No newline at end of file diff --git a/AccelerometerGraph/MainViewController.m b/AccelerometerGraph/MainViewController.m new file mode 100644 index 0000000..5dc55e9 --- /dev/null +++ b/AccelerometerGraph/MainViewController.m @@ -0,0 +1,180 @@ +/* + File: MainViewController.m + Abstract: Responsible for all UI interactions with the user and the accelerometer + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MainViewController.h" +#import "GraphView.h" +#import "AccelerometerFilter.h" + +#define kUpdateFrequency 60.0 +#define kLocalizedPause NSLocalizedString(@"Pause","pause taking samples") +#define kLocalizedResume NSLocalizedString(@"Resume","resume taking samples") + +@interface MainViewController() + +// Sets up a new filter. Since the filter's class matters and not a particular instance +// we just pass in the class and -changeFilter: will setup the proper filter. +-(void)changeFilter:(Class)filterClass; + +@end + +@implementation MainViewController + +@synthesize unfiltered, filtered, pause, filterLabel; + +// Implement viewDidLoad to do additional setup after loading the view. +-(void)viewDidLoad +{ + [super viewDidLoad]; + pause.possibleTitles = [NSSet setWithObjects:kLocalizedPause, kLocalizedResume, nil]; + isPaused = NO; + useAdaptive = NO; + [self changeFilter:[LowpassFilter class]]; + [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / kUpdateFrequency]; + [[UIAccelerometer sharedAccelerometer] setDelegate:self]; + + [unfiltered setIsAccessibilityElement:YES]; + [unfiltered setAccessibilityLabel:NSLocalizedString(@"unfilteredGraph", @"")]; + + [filtered setIsAccessibilityElement:YES]; + [filtered setAccessibilityLabel:NSLocalizedString(@"filteredGraph", @"")]; +} + +-(void)viewDidUnload +{ + [super viewDidUnload]; + self.unfiltered = nil; + self.filtered = nil; + self.pause = nil; + self.filterLabel = nil; +} + +// UIAccelerometerDelegate method, called when the device accelerates. +-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration +{ + // Update the accelerometer graph view + if(!isPaused) + { + [filter addAcceleration:acceleration]; + [unfiltered addX:acceleration.x y:acceleration.y z:acceleration.z]; + [filtered addX:filter.x y:filter.y z:filter.z]; + } +} + +-(void)changeFilter:(Class)filterClass +{ + // Ensure that the new filter class is different from the current one... + if(filterClass != [filter class]) + { + // And if it is, release the old one and create a new one. + [filter release]; + filter = [[filterClass alloc] initWithSampleRate:kUpdateFrequency cutoffFrequency:5.0]; + // Set the adaptive flag + filter.adaptive = useAdaptive; + // And update the filterLabel with the new filter name. + filterLabel.text = filter.name; + } +} + +-(IBAction)pauseOrResume:(id)sender +{ + if(isPaused) + { + // If we're paused, then resume and set the title to "Pause" + isPaused = NO; + pause.title = kLocalizedPause; + } + else + { + // If we are not paused, then pause and set the title to "Resume" + isPaused = YES; + pause.title = kLocalizedResume; + } + + // Inform accessibility clients that the pause/resume button has changed. + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); +} + +-(IBAction)filterSelect:(id)sender +{ + if([sender selectedSegmentIndex] == 0) + { + // Index 0 of the segment selects the lowpass filter + [self changeFilter:[LowpassFilter class]]; + } + else + { + // Index 1 of the segment selects the highpass filter + [self changeFilter:[HighpassFilter class]]; + } + + // Inform accessibility clients that the filter has changed. + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); +} + +-(IBAction)adaptiveSelect:(id)sender +{ + // Index 1 is to use the adaptive filter, so if selected then set useAdaptive appropriately + useAdaptive = [sender selectedSegmentIndex] == 1; + // and update our filter and filterLabel + filter.adaptive = useAdaptive; + filterLabel.text = filter.name; + + // Inform accessibility clients that the adaptive selection has changed. + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); +} + +-(void)dealloc +{ + // clean up everything. + [unfiltered release]; + [filtered release]; + [filterLabel release]; + [pause release]; + [super dealloc]; +} + +@end diff --git a/AccelerometerGraph/Prefix.pch b/AccelerometerGraph/Prefix.pch new file mode 100644 index 0000000..a0608dc --- /dev/null +++ b/AccelerometerGraph/Prefix.pch @@ -0,0 +1,51 @@ +/* + +File: Prefix.pch +Abstract: This file is included for support purposes and isn't necessary for +understanding this sample. + +Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + +*/ + +#ifdef __OBJC__ + #import +#endif diff --git a/AccelerometerGraph/ReadMe.txt b/AccelerometerGraph/ReadMe.txt new file mode 100644 index 0000000..3731284 --- /dev/null +++ b/AccelerometerGraph/ReadMe.txt @@ -0,0 +1,82 @@ + +### AccelerometerGraph ### + +=========================================================================== +DESCRIPTION: + +AccelerometerGraph sample application graphs the motion of the device. It demonstrates how to use the UIAccelerometer class and how to use Quartz2D and Core Animation to provide a high performance graph view. It also demonstrates a low-pass filter that you can use to isolate the effects of gravity, and a high-pass filter that you can use to remove the effects of gravity. + +Run this sample on the device to learn how the accelerometer behaves when moving the device. The simulator does not simulate the accelerometer hardware, so you will not see any updates to the graph there. Use the controls provided to pause and resume updates, and to select a low pass or high pass filter, and to enable or disable adaptive filtering. + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST: + +AppDelegate.h/m +The application delegate class, responsible for application events and for bringing up the user interface. + +AccelerometerFilter.h/m +Implements a low and high pass filter with optional adaptive filtering. + +GraphView.h/m +This class is responsible for updating and drawing the accelerometer history of values. This class uses Core Animation directly to control what parts of the graph are updated by drawing and what parts can be updated strictly by animation. + +MainViewController.h/m +The view controller loaded by the application delegate that is responsible for handling user events, selecting the correct filter, and passing accelerometer data through the filter and into the GraphView. + +main.m +Entry point for the application. Creates the application object, sets its delegate, and causes the event loop to start. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 2.5 +- Added CFBundleIconFiles in Info.plist. + +Version 2.4 +- Upgraded project to build with the iOS 4.0 SDK. + +Version 2.1 +- Enhanced the accessibility of the app by effectively using the iPhone Accessibility API. + +Version 2.0 +- Rewrote the GraphView class to drastically improve performance. Implementation is considerably different from previous versions. +- Refactored to use a view controller rather than doing similar work in the AppDelegate. +- Refactored to separate filters from display. +- Can now select either a low-pass or high-pass filter. +- Can now set the filter for an adaptive mode that causes the filter to converge to the new output value much faster + +Version 1.7 +- Updated for and tested with iPhone OS 2.0. First public release. +- Simplified updating of drawing by eliminating the NSTimer previously used to mark the view as needing to be redrawn. In this new version, the view is marked whenever new data arrives from the accelerometer. + +Version 1.6 +- Now use fixed-width buttons in UI. +- Modified update frequency to smooth animations. + +Version 1.5 +- Removed underscore prefixes on ivars to match sample code guidelines. +- Updated for Beta 6. + +Version 1.4 +- Updated for Beta 5. + +Version 1.3 +- Updated build settings. +- Updated ReadMe file and converted it to plain text format for viewing on website. + +Version 1.2 +- Updated ReadMe file. +- Added an icon and a default.png file. + +=========================================================================== +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/AccelerometerGraph/en.lproj/Localizable.strings b/AccelerometerGraph/en.lproj/Localizable.strings new file mode 100644 index 0000000..72ca97c Binary files /dev/null and b/AccelerometerGraph/en.lproj/Localizable.strings differ diff --git a/AccelerometerGraph/en.lproj/MainViewController.xib b/AccelerometerGraph/en.lproj/MainViewController.xib new file mode 100644 index 0000000..aaf0282 --- /dev/null +++ b/AccelerometerGraph/en.lproj/MainViewController.xib @@ -0,0 +1,490 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 266 + {{0, 416}, {320, 44}} + + NO + NO + + YES + + + 5 + + + Pause + 1 + + + + + 5 + + + + + + 258 + {{0, 49}, {320, 112}} + + + 3 + MC41AA + + 2 + + + NO + + + + 258 + {{0, 198}, {320, 112}} + + + NO + + + + 288 + {{20, 20}, {280, 21}} + + NO + YES + NO + Accelerometer Data + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + + + + 288 + {{20, 169}, {280, 21}} + + NO + YES + NO + Lowpass Filter + + + 1 + 1.000000e+01 + + + + 288 + {{20, 318}, {280, 44}} + + + 3 + MC43NSAwAA + + + NO + NO + 2 + 0 + + YES + Low Pass + High Pass + + + YES + + + + + YES + + + + + YES + {0, 0} + {0, 0} + + + YES + + + + + + + 288 + {{20, 365}, {280, 44}} + + + NO + NO + 2 + 0 + + YES + Standard + Adaptive + + + YES + + + + + YES + + + + + YES + {0, 0} + {0, 0} + + + YES + + + + + + {320, 460} + + + 3 + MC43NQA + + + NO + + + + + + YES + + + view + + + + 93 + + + + filterLabel + + + + 94 + + + + filterSelect: + + + 13 + + 95 + + + + adaptiveSelect: + + + 13 + + 96 + + + + unfiltered + + + + 97 + + + + filtered + + + + 98 + + + + pause + + + + 99 + + + + pauseOrResume: + + + + 100 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 14 + + + YES + + + + + + + + + + + + 86 + + + + + 85 + + + + + 45 + + + + + 22 + + + + + 21 + + + + + 44 + + + + + 16 + + + YES + + + + + + + + 26 + + + + + 25 + + + + + 17 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 14.IBEditorWindowLastContentRect + 14.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 21.CustomClassName + 21.IBPluginDependency + 22.CustomClassName + 22.IBPluginDependency + 25.IBPluginDependency + 26.IBPluginDependency + 44.IBPluginDependency + 45.IBPluginDependency + 85.IBPluginDependency + 86.IBPluginDependency + + + YES + MainViewController + UIResponder + {{126, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GraphView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GraphView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 100 + + + + YES + + GraphView + UIView + + IBProjectSource + GraphView.h + + + + MainViewController + UIViewController + + YES + + YES + adaptiveSelect: + filterSelect: + pauseOrResume: + + + YES + id + id + id + + + + YES + + YES + filterLabel + filtered + pause + unfiltered + + + YES + UILabel + GraphView + UIBarButtonItem + GraphView + + + + IBProjectSource + MainViewController.h + + + + + 0 + ../AccelerometerGraph.xcodeproj + 3 + 3.0 + + diff --git a/AccelerometerGraph/en.lproj/MainWindow.xib b/AccelerometerGraph/en.lproj/MainWindow.xib new file mode 100644 index 0000000..a7fc692 --- /dev/null +++ b/AccelerometerGraph/en.lproj/MainWindow.xib @@ -0,0 +1,264 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + MainViewController + + + + + + YES + + + delegate + + + + 5 + + + + window + + + + 6 + + + + viewController + + + + 94 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 4 + + + AppDelegate + + + -2 + + + + + 93 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 4.CustomClassName + 4.IBPluginDependency + 93.CustomClassName + 93.IBEditorWindowLastContentRect + 93.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{68, 269}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MainViewController + {{0, 365}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 94 + + + + YES + + AppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + UIViewController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + GraphView + UIView + + IBProjectSource + GraphView.h + + + + MainViewController + UIViewController + + YES + + YES + adaptiveSelect: + filterSelect: + pauseOrResume: + + + YES + id + id + id + + + + YES + + YES + filterLabel + filtered + pause + unfiltered + + + YES + UILabel + GraphView + UIBarButtonItem + GraphView + + + + IBProjectSource + MainViewController.h + + + + + 0 + ../AccelerometerGraph.xcodeproj + 3 + 3.0 + + diff --git a/AccelerometerGraph/images/Icon-72.png b/AccelerometerGraph/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/AccelerometerGraph/images/Icon-72.png differ diff --git a/AccelerometerGraph/images/Icon-Small-50.png b/AccelerometerGraph/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/AccelerometerGraph/images/Icon-Small-50.png differ diff --git a/AccelerometerGraph/images/Icon-Small.png b/AccelerometerGraph/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/AccelerometerGraph/images/Icon-Small.png differ diff --git a/AccelerometerGraph/images/Icon-Small@2x.png b/AccelerometerGraph/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/AccelerometerGraph/images/Icon-Small@2x.png differ diff --git a/AccelerometerGraph/images/Icon.png b/AccelerometerGraph/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/AccelerometerGraph/images/Icon.png differ diff --git a/AccelerometerGraph/images/Icon@2x.png b/AccelerometerGraph/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/AccelerometerGraph/images/Icon@2x.png differ diff --git a/AccelerometerGraph/images/iTunesArtwork b/AccelerometerGraph/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/AccelerometerGraph/images/iTunesArtwork differ diff --git a/AccelerometerGraph/main.m b/AccelerometerGraph/main.m new file mode 100644 index 0000000..eeaca99 --- /dev/null +++ b/AccelerometerGraph/main.m @@ -0,0 +1,55 @@ +/* + +File: main.m +Abstract: This file includes the calls to create and launch the application. + +Version: 1.7 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return 0; +} diff --git a/Accessory.zip b/Accessory.zip new file mode 100644 index 0000000..f40cf4e Binary files /dev/null and b/Accessory.zip differ diff --git a/Accessory/Accessory.xcodeproj/project.pbxproj b/Accessory/Accessory.xcodeproj/project.pbxproj new file mode 100755 index 0000000..1552530 --- /dev/null +++ b/Accessory/Accessory.xcodeproj/project.pbxproj @@ -0,0 +1,315 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 182A8B4A11D2B15600E156CC /* checked.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4011D2B15600E156CC /* checked.png */; }; + 182A8B4B11D2B15600E156CC /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4111D2B15600E156CC /* Default.png */; }; + 182A8B4C11D2B15600E156CC /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4211D2B15600E156CC /* Icon-72.png */; }; + 182A8B4D11D2B15600E156CC /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4311D2B15600E156CC /* Icon-Small-50.png */; }; + 182A8B4E11D2B15600E156CC /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4411D2B15600E156CC /* Icon-Small.png */; }; + 182A8B4F11D2B15600E156CC /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4511D2B15600E156CC /* Icon-Small@2x.png */; }; + 182A8B5011D2B15600E156CC /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4611D2B15600E156CC /* Icon.png */; }; + 182A8B5111D2B15600E156CC /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4711D2B15600E156CC /* Icon@2x.png */; }; + 182A8B5211D2B15600E156CC /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4811D2B15600E156CC /* iTunesArtwork */; }; + 182A8B5311D2B15600E156CC /* unchecked.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8B4911D2B15600E156CC /* unchecked.png */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF30D9C4D1A00F143AD /* AppDelegate.m */; }; + 531E94300EB775F2004F0ADD /* tableData.plist in Resources */ = {isa = PBXBuildFile; fileRef = 531E942F0EB775F2004F0ADD /* tableData.plist */; }; + 53A7B2750E311095003A40F3 /* MyTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A7B2730E311095003A40F3 /* MyTableViewController.m */; }; + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EACC050DDA319F00908D73 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 182A8B4011D2B15600E156CC /* checked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = checked.png; path = images/checked.png; sourceTree = ""; }; + 182A8B4111D2B15600E156CC /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 182A8B4211D2B15600E156CC /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 182A8B4311D2B15600E156CC /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 182A8B4411D2B15600E156CC /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 182A8B4511D2B15600E156CC /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 182A8B4611D2B15600E156CC /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 182A8B4711D2B15600E156CC /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 182A8B4811D2B15600E156CC /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 182A8B4911D2B15600E156CC /* unchecked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = unchecked.png; path = images/unchecked.png; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* Accessory.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Accessory.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53095FEF0D9C4D0500F143AD /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 531E942F0EB775F2004F0ADD /* tableData.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = tableData.plist; sourceTree = ""; }; + 53A7B2730E311095003A40F3 /* MyTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTableViewController.m; sourceTree = ""; }; + 53A7B2740E311095003A40F3 /* MyTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTableViewController.h; sourceTree = ""; }; + 53EACC060DDA319F00908D73 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 53EC3F710E5C7CBD00214B13 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Accessory.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53EC3F710E5C7CBD00214B13 /* ReadMe.txt */, + 53AF8AEC0D9C50B700726DBA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 182A8B4011D2B15600E156CC /* checked.png */, + 182A8B4111D2B15600E156CC /* Default.png */, + 182A8B4211D2B15600E156CC /* Icon-72.png */, + 182A8B4311D2B15600E156CC /* Icon-Small-50.png */, + 182A8B4411D2B15600E156CC /* Icon-Small.png */, + 182A8B4511D2B15600E156CC /* Icon-Small@2x.png */, + 182A8B4611D2B15600E156CC /* Icon.png */, + 182A8B4711D2B15600E156CC /* Icon@2x.png */, + 182A8B4811D2B15600E156CC /* iTunesArtwork */, + 182A8B4911D2B15600E156CC /* unchecked.png */, + 8D1107310486CEB800E47090 /* Info.plist */, + 531E942F0EB775F2004F0ADD /* tableData.plist */, + 53EACC050DDA319F00908D73 /* MainWindow.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53AF8AEC0D9C50B700726DBA /* Sources */ = { + isa = PBXGroup; + children = ( + 53095FEF0D9C4D0500F143AD /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */, + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */, + 53A7B2740E311095003A40F3 /* MyTableViewController.h */, + 53A7B2730E311095003A40F3 /* MyTableViewController.m */, + ); + name = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Accessory */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Accessory" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Accessory; + productName = IBTest; + productReference = 1D6058910D05DD3D006BFB54 /* Accessory.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Accessory" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Accessory */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */, + 531E94300EB775F2004F0ADD /* tableData.plist in Resources */, + 182A8B4A11D2B15600E156CC /* checked.png in Resources */, + 182A8B4B11D2B15600E156CC /* Default.png in Resources */, + 182A8B4C11D2B15600E156CC /* Icon-72.png in Resources */, + 182A8B4D11D2B15600E156CC /* Icon-Small-50.png in Resources */, + 182A8B4E11D2B15600E156CC /* Icon-Small.png in Resources */, + 182A8B4F11D2B15600E156CC /* Icon-Small@2x.png in Resources */, + 182A8B5011D2B15600E156CC /* Icon.png in Resources */, + 182A8B5111D2B15600E156CC /* Icon@2x.png in Resources */, + 182A8B5211D2B15600E156CC /* iTunesArtwork in Resources */, + 182A8B5311D2B15600E156CC /* unchecked.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */, + 53A7B2750E311095003A40F3 /* MyTableViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53EACC050DDA319F00908D73 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53EACC060DDA319F00908D73 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = Accessory; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = Accessory; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Accessory" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Accessory" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Accessory/AppDelegate.h b/Accessory/AppDelegate.h new file mode 100755 index 0000000..588e5dc --- /dev/null +++ b/Accessory/AppDelegate.h @@ -0,0 +1,59 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for installing our table view controller. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *myNavController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *myNavController; + +@end diff --git a/Accessory/AppDelegate.m b/Accessory/AppDelegate.m new file mode 100755 index 0000000..852d109 --- /dev/null +++ b/Accessory/AppDelegate.m @@ -0,0 +1,72 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for installing our table view controller. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" + +@implementation AppDelegate; + +@synthesize window, myNavController; + + +- (void)dealloc +{ + [myNavController release]; + [window release]; + + [super dealloc]; +} + + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + [window addSubview:myNavController.view]; + + [window makeKeyAndVisible]; +} + +@end diff --git a/Accessory/Info.plist b/Accessory/Info.plist new file mode 100755 index 0000000..c2974b4 --- /dev/null +++ b/Accessory/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + NSMainNibFile + MainWindow + LSRequiresIPhoneOS + + + diff --git a/Accessory/MyTableViewController.h b/Accessory/MyTableViewController.h new file mode 100644 index 0000000..5ec7a44 --- /dev/null +++ b/Accessory/MyTableViewController.h @@ -0,0 +1,56 @@ +/* + File: MyTableViewController.h + Abstract: The main table view controller of this app. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface MyTableViewController : UITableViewController +{ +@private + NSMutableArray *dataArray; +} + +@end diff --git a/Accessory/MyTableViewController.m b/Accessory/MyTableViewController.m new file mode 100644 index 0000000..cc185e1 --- /dev/null +++ b/Accessory/MyTableViewController.m @@ -0,0 +1,162 @@ +/* + File: MyTableViewController.m + Abstract: The main table view controller of this app. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyTableViewController.h" + +@interface MyTableViewController () +@property (nonatomic, retain) NSMutableArray *dataArray; +@end + +@implementation MyTableViewController + +@synthesize dataArray; + +- (void)viewDidLoad +{ + // load our data from a plist file inside our app bundle + NSString *path = [[NSBundle mainBundle] pathForResource:@"tableData" ofType:@"plist"]; + self.dataArray = [NSMutableArray arrayWithContentsOfFile:path]; +} + + +// called after the view controller's view is released and set to nil. +// For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc. +// So release any properties that are loaded in viewDidLoad or can be recreated lazily. +// +- (void)viewDidUnload +{ + self.dataArray = nil; +} + + +- (void)dealloc +{ + [dataArray release]; + [super dealloc]; +} + + +#pragma mark - UITableView delegate methods + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [dataArray count]; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath]; + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kCustomCellID = @"MyCellID"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCustomCellID]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCustomCellID] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + } + + NSMutableDictionary *item = [dataArray objectAtIndex:indexPath.row]; + cell.textLabel.text = [item objectForKey:@"text"]; + + [item setObject:cell forKey:@"cell"]; + + BOOL checked = [[item objectForKey:@"checked"] boolValue]; + UIImage *image = (checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"]; + + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); + button.frame = frame; // match the button's size with the image size + + [button setBackgroundImage:image forState:UIControlStateNormal]; + + // set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet + [button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside]; + cell.backgroundColor = [UIColor clearColor]; + cell.accessoryView = button; + + return cell; +} + + +- (void)checkButtonTapped:(id)sender event:(id)event +{ + NSSet *touches = [event allTouches]; + UITouch *touch = [touches anyObject]; + CGPoint currentTouchPosition = [touch locationInView:self.tableView]; + NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition]; + if (indexPath != nil) + { + [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath]; + } +} + + +- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath +{ + NSMutableDictionary *item = [dataArray objectAtIndex:indexPath.row]; + + BOOL checked = [[item objectForKey:@"checked"] boolValue]; + + [item setObject:[NSNumber numberWithBool:!checked] forKey:@"checked"]; + + UITableViewCell *cell = [item objectForKey:@"cell"]; + UIButton *button = (UIButton *)cell.accessoryView; + + UIImage *newImage = (checked) ? [UIImage imageNamed:@"unchecked.png"] : [UIImage imageNamed:@"checked.png"]; + [button setBackgroundImage:newImage forState:UIControlStateNormal]; +} + +@end + diff --git a/Accessory/Prefix.pch b/Accessory/Prefix.pch new file mode 100755 index 0000000..d48ae3f --- /dev/null +++ b/Accessory/Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'Accessory' target in the 'Accessory' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Accessory/ReadMe.txt b/Accessory/ReadMe.txt new file mode 100644 index 0000000..f32d862 --- /dev/null +++ b/Accessory/ReadMe.txt @@ -0,0 +1,31 @@ +Accessory + +Demonstrates how to implement a custom accessory view for your UITableView in the form of a checkmark button. It shows you how to override the appearance or control of the accessory view, much like that of "UITableViewCellAccessoryDetailDisclosureButton". It implements the custom accessory view by setting the table's "accessoryView" property with a UIButton of type "UIButtonTypeCustom". It can be toggled by selecting the entire table row by implementing UITableView's "didSelectRowAtIndexPath". The green checkmark is trackable (checked/unchecked), and can be toggled independent of table selection. + + +Build Requirements +iOS 4.0 SDK + + +Runtime Requirements +iPhone OS 3.2 or later + + +Using the Sample +Launch the Accessory project using Xcode. + +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. When launched, touch the entire row to make the accessory view appear checked, touch again to uncheck it. Then touch the actual accessory to the right to check and uncheck it as well. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application's delegate to setup its window and content. +MyTableViewController.h/.m - The main UITableViewController controlling the UITableView and its custom accessory view. + + +Changes from Previous Versions +1.0 - First release. +1.1 - Upgraded for 3.0 SDK due to deprecated APIs; in "cellForRowAtIndexPath" it now uses UITableViewCell's initWithStyle. +1.2 - Upgraded project to build with the iOS 4.0 SDK. + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/Accessory/en.lproj/MainWindow.xib b/Accessory/en.lproj/MainWindow.xib new file mode 100644 index 0000000..631ab05 --- /dev/null +++ b/Accessory/en.lproj/MainWindow.xib @@ -0,0 +1,309 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 416} + + + NO + YES + NO + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + + Custom Table Accessory + + + + + + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + delegate + + + + 57 + + + + dataSource + + + + 58 + + + + myNavController + + + + 72 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 60 + + + YES + + + + + + + 62 + + + + + 55 + + + YES + + + + + MyTableViewController + + + 56 + + + + + 64 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 55.CustomClassName + 55.IBEditorWindowLastContentRect + 55.IBPluginDependency + 56.IBPluginDependency + 60.IBEditorWindowLastContentRect + 60.IBPluginDependency + 62.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyTableViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 72 + + + + YES + + AppDelegate + NSObject + + YES + + YES + myNavController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + MyTableViewController + UITableViewController + + IBProjectSource + MyTableViewController.h + + + + + 0 + ../Accessory.xcodeproj + 3 + + diff --git a/Accessory/images/Default.png b/Accessory/images/Default.png new file mode 100644 index 0000000..0389a7a Binary files /dev/null and b/Accessory/images/Default.png differ diff --git a/Accessory/images/Icon-72.png b/Accessory/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/Accessory/images/Icon-72.png differ diff --git a/Accessory/images/Icon-Small-50.png b/Accessory/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/Accessory/images/Icon-Small-50.png differ diff --git a/Accessory/images/Icon-Small.png b/Accessory/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/Accessory/images/Icon-Small.png differ diff --git a/Accessory/images/Icon-Small@2x.png b/Accessory/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/Accessory/images/Icon-Small@2x.png differ diff --git a/Accessory/images/Icon.png b/Accessory/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/Accessory/images/Icon.png differ diff --git a/Accessory/images/Icon@2x.png b/Accessory/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/Accessory/images/Icon@2x.png differ diff --git a/Accessory/images/checked.png b/Accessory/images/checked.png new file mode 100644 index 0000000..716d993 Binary files /dev/null and b/Accessory/images/checked.png differ diff --git a/Accessory/images/iTunesArtwork b/Accessory/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/Accessory/images/iTunesArtwork differ diff --git a/Accessory/images/unchecked.png b/Accessory/images/unchecked.png new file mode 100644 index 0000000..95d9323 Binary files /dev/null and b/Accessory/images/unchecked.png differ diff --git a/Accessory/main.m b/Accessory/main.m new file mode 100755 index 0000000..6926d56 --- /dev/null +++ b/Accessory/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Implementation of the standard main function for iPhone OS applications. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/Accessory/tableData.plist b/Accessory/tableData.plist new file mode 100755 index 0000000..aece749 --- /dev/null +++ b/Accessory/tableData.plist @@ -0,0 +1,43 @@ + + + + + + + text + Mac Pro + checked + + + + text + Mac Mini + checked + + + + text + iMac + checked + + + + text + MacBook + checked + + + + text + MacBook Pro + checked + + + + text + MacBook Air + checked + + + + diff --git a/AddMusic.zip b/AddMusic.zip new file mode 100644 index 0000000..b5ea62d Binary files /dev/null and b/AddMusic.zip differ diff --git a/AddMusic/AddMusic-Info.plist b/AddMusic/AddMusic-Info.plist new file mode 100644 index 0000000..40fbd78 --- /dev/null +++ b/AddMusic/AddMusic-Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarStyle + UIStatusBarStyleOpaqueBlack + + diff --git a/AddMusic/AddMusic.xcodeproj/project.pbxproj b/AddMusic/AddMusic.xcodeproj/project.pbxproj new file mode 100755 index 0000000..4d128b8 --- /dev/null +++ b/AddMusic/AddMusic.xcodeproj/project.pbxproj @@ -0,0 +1,342 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 0A1C086A0FB7876600C7BA1B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0A1C08680FB7876600C7BA1B /* Localizable.strings */; }; + 0A1C08910FB78C0D00C7BA1B /* MusicTableView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A1C088F0FB78C0D00C7BA1B /* MusicTableView.xib */; }; + 0A1C08C20FB7973400C7BA1B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 0A1C08C10FB7973400C7BA1B /* Settings.bundle */; }; + 0A6C6CC00FB396DB00F95575 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A6C6CBF0FB396DB00F95575 /* Default.png */; }; + 0A735D530FACBA430057280A /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A735D520FACBA430057280A /* MainViewController.m */; }; + 0A735D630FACBAAC0057280A /* no_artwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A735D610FACBAAC0057280A /* no_artwork.png */; }; + 0AA441400FB2865E006FAACB /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = 0AA4413F0FB2865E006FAACB /* background.png */; }; + 0AA6AE310FB773F6008185AA /* MainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6AE2B0FB773F6008185AA /* MainView.xib */; }; + 0AA6AE320FB773F6008185AA /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6AE2D0FB773F6008185AA /* MainWindow.xib */; }; + 0AB904010FB4D1A5004C88C3 /* sound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 0AB904000FB4D1A5004C88C3 /* sound.caf */; }; + 0AB9044B0FB4E0CB004C88C3 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 0AB9044A0FB4E0CB004C88C3 /* ReadMe.txt */; }; + 0ADFA0840FABA7250020C909 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ADFA0830FABA7250020C909 /* AudioToolbox.framework */; }; + 0ADFA09E0FABA9DF0020C909 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ADFA09D0FABA9DF0020C909 /* AVFoundation.framework */; }; + 1D3623260D0F684500981E51 /* AddMusicAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AddMusicAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 580748730FAA6E1600373EAF /* MusicTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 580748710FAA6E1600373EAF /* MusicTableViewController.m */; }; + 58D3B0100F9FE329006F1B20 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58D3B00F0F9FE329006F1B20 /* MediaPlayer.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0A1C08690FB7876600C7BA1B /* en */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; name = en; path = Resources/en.lproj/Localizable.strings; sourceTree = ""; }; + 0A1C08900FB78C0D00C7BA1B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/MusicTableView.xib; sourceTree = ""; }; + 0A1C08C10FB7973400C7BA1B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Settings.bundle; path = Resources/Settings.bundle; sourceTree = ""; }; + 0A6C6CBF0FB396DB00F95575 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Default.png; sourceTree = ""; }; + 0A735D510FACBA430057280A /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 0A735D520FACBA430057280A /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 0A735D610FACBAAC0057280A /* no_artwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = no_artwork.png; path = Resources/no_artwork.png; sourceTree = ""; }; + 0A735D7A0FACBB490057280A /* AddMusic-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AddMusic-Info.plist"; sourceTree = ""; }; + 0AA4413F0FB2865E006FAACB /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = Resources/background.png; sourceTree = ""; }; + 0AA6AE2C0FB773F6008185AA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/MainView.xib; sourceTree = ""; }; + 0AA6AE2E0FB773F6008185AA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/MainWindow.xib; sourceTree = ""; }; + 0AB904000FB4D1A5004C88C3 /* sound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = sound.caf; path = Resources/sound.caf; sourceTree = ""; }; + 0AB9044A0FB4E0CB004C88C3 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; wrapsLines = 1; }; + 0ADFA0830FABA7250020C909 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 0ADFA09D0FABA9DF0020C909 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AddMusicAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddMusicAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AddMusicAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddMusicAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* AddMusic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AddMusic.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* AddMusic_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddMusic_Prefix.pch; sourceTree = ""; }; + 580748700FAA6E1600373EAF /* MusicTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicTableViewController.h; sourceTree = ""; }; + 580748710FAA6E1600373EAF /* MusicTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicTableViewController.m; sourceTree = ""; }; + 58D3B00F0F9FE329006F1B20 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 58D3B0100F9FE329006F1B20 /* MediaPlayer.framework in Frameworks */, + 0ADFA0840FABA7250020C909 /* AudioToolbox.framework in Frameworks */, + 0ADFA09E0FABA9DF0020C909 /* AVFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AddMusicAppDelegate.h */, + 1D3623250D0F684500981E51 /* AddMusicAppDelegate.m */, + 0A735D510FACBA430057280A /* MainViewController.h */, + 0A735D520FACBA430057280A /* MainViewController.m */, + 580748700FAA6E1600373EAF /* MusicTableViewController.h */, + 580748710FAA6E1600373EAF /* MusicTableViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* AddMusic.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 0AB9044A0FB4E0CB004C88C3 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* AddMusic_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 0A6C6CBF0FB396DB00F95575 /* Default.png */, + 0AA4413F0FB2865E006FAACB /* background.png */, + 0A735D610FACBAAC0057280A /* no_artwork.png */, + 0AB904000FB4D1A5004C88C3 /* sound.caf */, + 0AA6AE2D0FB773F6008185AA /* MainWindow.xib */, + 0AA6AE2B0FB773F6008185AA /* MainView.xib */, + 0A1C088F0FB78C0D00C7BA1B /* MusicTableView.xib */, + 0A1C08C10FB7973400C7BA1B /* Settings.bundle */, + 0A1C08680FB7876600C7BA1B /* Localizable.strings */, + 0A735D7A0FACBB490057280A /* AddMusic-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0ADFA09D0FABA9DF0020C909 /* AVFoundation.framework */, + 0ADFA0830FABA7250020C909 /* AudioToolbox.framework */, + 58D3B00F0F9FE329006F1B20 /* MediaPlayer.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* AddMusic */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AddMusic" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AddMusic; + productName = AddMusic; + productReference = 1D6058910D05DD3D006BFB54 /* AddMusic.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AddMusic" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* AddMusic */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A735D630FACBAAC0057280A /* no_artwork.png in Resources */, + 0AA441400FB2865E006FAACB /* background.png in Resources */, + 0A6C6CC00FB396DB00F95575 /* Default.png in Resources */, + 0AB904010FB4D1A5004C88C3 /* sound.caf in Resources */, + 0AB9044B0FB4E0CB004C88C3 /* ReadMe.txt in Resources */, + 0AA6AE310FB773F6008185AA /* MainView.xib in Resources */, + 0AA6AE320FB773F6008185AA /* MainWindow.xib in Resources */, + 0A1C086A0FB7876600C7BA1B /* Localizable.strings in Resources */, + 0A1C08910FB78C0D00C7BA1B /* MusicTableView.xib in Resources */, + 0A1C08C20FB7973400C7BA1B /* Settings.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AddMusicAppDelegate.m in Sources */, + 580748730FAA6E1600373EAF /* MusicTableViewController.m in Sources */, + 0A735D530FACBA430057280A /* MainViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 0A1C08680FB7876600C7BA1B /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 0A1C08690FB7876600C7BA1B /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 0A1C088F0FB78C0D00C7BA1B /* MusicTableView.xib */ = { + isa = PBXVariantGroup; + children = ( + 0A1C08900FB78C0D00C7BA1B /* en */, + ); + name = MusicTableView.xib; + sourceTree = ""; + }; + 0AA6AE2B0FB773F6008185AA /* MainView.xib */ = { + isa = PBXVariantGroup; + children = ( + 0AA6AE2C0FB773F6008185AA /* en */, + ); + name = MainView.xib; + sourceTree = ""; + }; + 0AA6AE2D0FB773F6008185AA /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 0AA6AE2E0FB773F6008185AA /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AddMusic_Prefix.pch; + INFOPLIST_FILE = "AddMusic-Info.plist"; + PRODUCT_NAME = AddMusic; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AddMusic_Prefix.pch; + INFOPLIST_FILE = "AddMusic-Info.plist"; + PRODUCT_NAME = AddMusic; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos3.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AddMusic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AddMusic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/AddMusic/AddMusic_Prefix.pch b/AddMusic/AddMusic_Prefix.pch new file mode 100644 index 0000000..29b2db2 --- /dev/null +++ b/AddMusic/AddMusic_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'AddMusic' target in the 'AddMusic' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/AddMusic/Classes/AddMusicAppDelegate.h b/AddMusic/Classes/AddMusicAppDelegate.h new file mode 100644 index 0000000..225641d --- /dev/null +++ b/AddMusic/Classes/AddMusicAppDelegate.h @@ -0,0 +1,63 @@ +/* + File: AddMusicAppDelegate.h +Abstract: Application delegate class for AddMusic. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + + +#import + +@class MainViewController; + +@interface AddMusicAppDelegate : NSObject { + + UIWindow *window; + IBOutlet MainViewController *mainViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet MainViewController *mainViewController; + +@end + diff --git a/AddMusic/Classes/AddMusicAppDelegate.m b/AddMusic/Classes/AddMusicAppDelegate.m new file mode 100644 index 0000000..493dd05 --- /dev/null +++ b/AddMusic/Classes/AddMusicAppDelegate.m @@ -0,0 +1,71 @@ +/* + File: AddMusicAppDelegate.m +Abstract: Application delegate class for AddMusic. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + + +#import "AddMusicAppDelegate.h" +#import "MainViewController.h" + +@implementation AddMusicAppDelegate + +@synthesize window, mainViewController; + + +- (void) applicationDidFinishLaunching: (UIApplication *) application { + + [window addSubview: [mainViewController view]]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + + [window release]; + [super dealloc]; +} + + +@end diff --git a/AddMusic/Classes/MainViewController.h b/AddMusic/Classes/MainViewController.h new file mode 100644 index 0000000..6abd35c --- /dev/null +++ b/AddMusic/Classes/MainViewController.h @@ -0,0 +1,107 @@ +/* + File: MainViewController.h +Abstract: View controller class for AddMusic. Sets up user interface, responds +to and manages user interaction. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#define PLAYER_TYPE_PREF_KEY @"player_type_preference" +#define AUDIO_TYPE_PREF_KEY @"audio_technology_preference" + +#import +#import +#import +#import +#import "MusicTableViewController.h" +#import "AddMusicAppDelegate.h" + +@interface MainViewController : UIViewController { + + AddMusicAppDelegate *applicationDelegate; + IBOutlet UIBarButtonItem *artworkItem; + IBOutlet UINavigationBar *navigationBar; + IBOutlet UILabel *nowPlayingLabel; + BOOL playedMusicOnce; + + AVAudioPlayer *appSoundPlayer; + NSURL *soundFileURL; + IBOutlet UIButton *appSoundButton; + IBOutlet UIButton *addOrShowMusicButton; + BOOL interruptedOnPlayback; + BOOL playing ; + + UIBarButtonItem *playBarButton; + UIBarButtonItem *pauseBarButton; + MPMusicPlayerController *musicPlayer; + MPMediaItemCollection *userMediaItemCollection; + UIImage *noArtworkImage; + NSTimer *backgroundColorTimer; +} + +@property (nonatomic, retain) UIBarButtonItem *artworkItem; +@property (nonatomic, retain) UINavigationBar *navigationBar; +@property (nonatomic, retain) UILabel *nowPlayingLabel; +@property (readwrite) BOOL playedMusicOnce; + +@property (nonatomic, retain) UIBarButtonItem *playBarButton; +@property (nonatomic, retain) UIBarButtonItem *pauseBarButton; +@property (nonatomic, retain) MPMediaItemCollection *userMediaItemCollection; +@property (nonatomic, retain) MPMusicPlayerController *musicPlayer; +@property (nonatomic, retain) UIImage *noArtworkImage; +@property (nonatomic, retain) NSTimer *backgroundColorTimer; + +@property (nonatomic, retain) AVAudioPlayer *appSoundPlayer; +@property (nonatomic, retain) NSURL *soundFileURL; +@property (nonatomic, retain) IBOutlet UIButton *appSoundButton; +@property (nonatomic, retain) IBOutlet UIButton *addOrShowMusicButton; +@property (readwrite) BOOL interruptedOnPlayback; +@property (readwrite) BOOL playing; + +- (IBAction) playOrPauseMusic: (id) sender; +- (IBAction) AddMusicOrShowMusic: (id) sender; +- (IBAction) playAppSound: (id) sender; + +- (BOOL) useiPodPlayer; + +@end diff --git a/AddMusic/Classes/MainViewController.m b/AddMusic/Classes/MainViewController.m new file mode 100644 index 0000000..89bba36 --- /dev/null +++ b/AddMusic/Classes/MainViewController.m @@ -0,0 +1,713 @@ +/* + File: MainViewController.m +Abstract: View controller class for AddMusic. Sets up user interface, responds +to and manages user interaction. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + + +#import "MainViewController.h" +#import + +#pragma mark Audio session callbacks_______________________ + +// Audio session callback function for responding to audio route changes. If playing +// back application audio when the headset is unplugged, this callback pauses +// playback and displays an alert that allows the user to resume or stop playback. +// +// The system takes care of iPod audio pausing during route changes--this callback +// is not involved with pausing playback of iPod audio. +void audioRouteChangeListenerCallback ( + void *inUserData, + AudioSessionPropertyID inPropertyID, + UInt32 inPropertyValueSize, + const void *inPropertyValue +) { + + // ensure that this callback was invoked for a route change + if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; + + // This callback, being outside the implementation block, needs a reference to the + // MainViewController object, which it receives in the inUserData parameter. + // You provide this reference when registering this callback (see the call to + // AudioSessionAddPropertyListener). + MainViewController *controller = (MainViewController *) inUserData; + + // if application sound is not playing, there's nothing to do, so return. + if (controller.appSoundPlayer.playing == 0 ) { + + NSLog (@"Audio route change while application audio is stopped."); + return; + + } else { + + // Determines the reason for the route change, to ensure that it is not + // because of a category change. + CFDictionaryRef routeChangeDictionary = inPropertyValue; + + CFNumberRef routeChangeReasonRef = + CFDictionaryGetValue ( + routeChangeDictionary, + CFSTR (kAudioSession_AudioRouteChangeKey_Reason) + ); + + SInt32 routeChangeReason; + + CFNumberGetValue ( + routeChangeReasonRef, + kCFNumberSInt32Type, + &routeChangeReason + ); + + // "Old device unavailable" indicates that a headset was unplugged, or that the + // device was removed from a dock connector that supports audio output. This is + // the recommended test for when to pause audio. + if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) { + + [controller.appSoundPlayer pause]; + NSLog (@"Output device removed, so application audio was paused."); + + UIAlertView *routeChangeAlertView = + [[UIAlertView alloc] initWithTitle: NSLocalizedString (@"Playback Paused", @"Title for audio hardware route-changed alert view") + message: NSLocalizedString (@"Audio output was changed", @"Explanation for route-changed alert view") + delegate: controller + cancelButtonTitle: NSLocalizedString (@"StopPlaybackAfterRouteChange", @"Stop button title") + otherButtonTitles: NSLocalizedString (@"ResumePlaybackAfterRouteChange", @"Play button title"), nil]; + [routeChangeAlertView show]; + // release takes place in alertView:clickedButtonAtIndex: method + + } else { + + NSLog (@"A route change occurred that does not require pausing of application audio."); + } + } +} + + + +@implementation MainViewController + +@synthesize artworkItem; // the now-playing media item's artwork image, displayed in the Navigation bar +@synthesize userMediaItemCollection; // the media item collection created by the user, using the media item picker +@synthesize playBarButton; // the button for invoking Play on the music player +@synthesize pauseBarButton; // the button for invoking Pause on the music player +@synthesize musicPlayer; // the music player, which plays media items from the iPod library +@synthesize navigationBar; // the application's Navigation bar +@synthesize noArtworkImage; // an image to display when a media item has no associated artwork +@synthesize backgroundColorTimer; // a timer for changing the background color -- represents an application that is + // doing something else while iPod music is playing +@synthesize nowPlayingLabel; // descriptive text shown on the main screen about the now-playing media item +@synthesize appSoundButton; // the button to invoke playback for the application sound +@synthesize addOrShowMusicButton; // the button for invoking the media item picker. if the user has already + // specified a media item collection, the title changes to "Show Music" and + // the button invokes a table view that shows the specified collection +@synthesize appSoundPlayer; // An AVAudioPlayer object for playing application sound +@synthesize soundFileURL; // The path to the application sound +@synthesize interruptedOnPlayback; // A flag indicating whether or not the application was interrupted during + // application audio playback +@synthesize playedMusicOnce; // A flag indicating if the user has played iPod library music at least one time + // since application launch. +@synthesize playing; // An application that responds to interruptions must keep track of its playing/ + // not-playing state. + +#pragma mark Music control________________________________ + +// A toggle control for playing or pausing iPod library music playback, invoked +// when the user taps the 'playBarButton' in the Navigation bar. +- (IBAction) playOrPauseMusic: (id)sender { + + MPMusicPlaybackState playbackState = [musicPlayer playbackState]; + + if (playbackState == MPMusicPlaybackStateStopped || playbackState == MPMusicPlaybackStatePaused) { + [musicPlayer play]; + } else if (playbackState == MPMusicPlaybackStatePlaying) { + [musicPlayer pause]; + } +} + +// If there is no selected media item collection, display the media item picker. If there's +// already a selected collection, display the list of selected songs. +- (IBAction) AddMusicOrShowMusic: (id) sender { + + // if the user has already chosen some music, display that list + if (userMediaItemCollection) { + + MusicTableViewController *controller = [[MusicTableViewController alloc] initWithNibName: @"MusicTableView" bundle: nil]; + controller.delegate = self; + + controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical; + + [self presentModalViewController: controller animated: YES]; + [controller release]; + + // else, if no music is chosen yet, display the media item picker + } else { + + MPMediaPickerController *picker = + [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic]; + + picker.delegate = self; + picker.allowsPickingMultipleItems = YES; + picker.prompt = NSLocalizedString (@"Add songs to play", "Prompt in media item picker"); + + // The media item picker uses the default UI style, so it needs a default-style + // status bar to match it visually + [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleDefault animated: YES]; + + [self presentModalViewController: picker animated: YES]; + [picker release]; + } +} + + +// Invoked by the delegate of the media item picker when the user is finished picking music. +// The delegate is either this class or the table view controller, depending on the +// state of the application. +- (void) updatePlayerQueueWithMediaCollection: (MPMediaItemCollection *) mediaItemCollection { + + // Configure the music player, but only if the user chose at least one song to play + if (mediaItemCollection) { + + // If there's no playback queue yet... + if (userMediaItemCollection == nil) { + + // apply the new media item collection as a playback queue for the music player + [self setUserMediaItemCollection: mediaItemCollection]; + [musicPlayer setQueueWithItemCollection: userMediaItemCollection]; + [self setPlayedMusicOnce: YES]; + [musicPlayer play]; + + // Obtain the music player's state so it can then be + // restored after updating the playback queue. + } else { + + // Take note of whether or not the music player is playing. If it is + // it needs to be started again at the end of this method. + BOOL wasPlaying = NO; + if (musicPlayer.playbackState == MPMusicPlaybackStatePlaying) { + wasPlaying = YES; + } + + // Save the now-playing item and its current playback time. + MPMediaItem *nowPlayingItem = musicPlayer.nowPlayingItem; + NSTimeInterval currentPlaybackTime = musicPlayer.currentPlaybackTime; + + // Combine the previously-existing media item collection with the new one + NSMutableArray *combinedMediaItems = [[userMediaItemCollection items] mutableCopy]; + NSArray *newMediaItems = [mediaItemCollection items]; + [combinedMediaItems addObjectsFromArray: newMediaItems]; + + [self setUserMediaItemCollection: [MPMediaItemCollection collectionWithItems: (NSArray *) combinedMediaItems]]; + [combinedMediaItems release]; + + // Apply the new media item collection as a playback queue for the music player. + [musicPlayer setQueueWithItemCollection: userMediaItemCollection]; + + // Restore the now-playing item and its current playback time. + musicPlayer.nowPlayingItem = nowPlayingItem; + musicPlayer.currentPlaybackTime = currentPlaybackTime; + + // If the music player was playing, get it playing again. + if (wasPlaying) { + [musicPlayer play]; + } + } + + // Finally, because the music player now has a playback queue, ensure that + // the music play/pause button in the Navigation bar is enabled. + navigationBar.topItem.leftBarButtonItem.enabled = YES; + + [addOrShowMusicButton setTitle: NSLocalizedString (@"Show Music", @"Alternate title for 'Add Music' button, after user has chosen some music") + forState: UIControlStateNormal]; + } +} + +// If the music player was paused, leave it paused. If it was playing, it will continue to +// play on its own. The music player state is "stopped" only if the previous list of songs +// had finished or if this is the first time the user has chosen songs after app +// launch--in which case, invoke play. +- (void) restorePlaybackState { + + if (musicPlayer.playbackState == MPMusicPlaybackStateStopped && userMediaItemCollection) { + + [addOrShowMusicButton setTitle: NSLocalizedString (@"Show Music", @"Alternate title for 'Add Music' button, after user has chosen some music") + forState: UIControlStateNormal]; + + if (playedMusicOnce == NO) { + + [self setPlayedMusicOnce: YES]; + [musicPlayer play]; + } + } + +} + + + +#pragma mark Media item picker delegate methods________ + +// Invoked when the user taps the Done button in the media item picker after having chosen +// one or more media items to play. +- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection { + + // Dismiss the media item picker. + [self dismissModalViewControllerAnimated: YES]; + + // Apply the chosen songs to the music player's queue. + [self updatePlayerQueueWithMediaCollection: mediaItemCollection]; + + [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated: YES]; +} + +// Invoked when the user taps the Done button in the media item picker having chosen zero +// media items to play +- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker { + + [self dismissModalViewControllerAnimated: YES]; + + [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated: YES]; +} + + + +#pragma mark Music notification handlers__________________ + +// When the now-playing item changes, update the media item artwork and the now-playing label. +- (void) handle_NowPlayingItemChanged: (id) notification { + + MPMediaItem *currentItem = [musicPlayer nowPlayingItem]; + + // Assume that there is no artwork for the media item. + UIImage *artworkImage = noArtworkImage; + + // Get the artwork from the current media item, if it has artwork. + MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork]; + + // Obtain a UIImage object from the MPMediaItemArtwork object + if (artwork) { + artworkImage = [artwork imageWithSize: CGSizeMake (30, 30)]; + } + + // Obtain a UIButton object and set its background to the UIImage object + UIButton *artworkView = [[UIButton alloc] initWithFrame: CGRectMake (0, 0, 30, 30)]; + [artworkView setBackgroundImage: artworkImage forState: UIControlStateNormal]; + + // Obtain a UIBarButtonItem object and initialize it with the UIButton object + UIBarButtonItem *newArtworkItem = [[UIBarButtonItem alloc] initWithCustomView: artworkView]; + [self setArtworkItem: newArtworkItem]; + [newArtworkItem release]; + + [artworkItem setEnabled: NO]; + + // Display the new media item artwork + [navigationBar.topItem setRightBarButtonItem: artworkItem animated: YES]; + + // Display the artist and song name for the now-playing media item + [nowPlayingLabel setText: [ + NSString stringWithFormat: @"%@ %@ %@ %@", + NSLocalizedString (@"Now Playing:", @"Label for introducing the now-playing song title and artist"), + [currentItem valueForProperty: MPMediaItemPropertyTitle], + NSLocalizedString (@"by", @"Article between song name and artist name"), + [currentItem valueForProperty: MPMediaItemPropertyArtist]]]; + + if (musicPlayer.playbackState == MPMusicPlaybackStateStopped) { + // Provide a suitable prompt to the user now that their chosen music has + // finished playing. + [nowPlayingLabel setText: [ + NSString stringWithFormat: @"%@", + NSLocalizedString (@"Music-ended Instructions", @"Label for prompting user to play music again after it has stopped")]]; + + } +} + +// When the playback state changes, set the play/pause button in the Navigation bar +// appropriately. +- (void) handle_PlaybackStateChanged: (id) notification { + + MPMusicPlaybackState playbackState = [musicPlayer playbackState]; + + if (playbackState == MPMusicPlaybackStatePaused) { + + navigationBar.topItem.leftBarButtonItem = playBarButton; + + } else if (playbackState == MPMusicPlaybackStatePlaying) { + + navigationBar.topItem.leftBarButtonItem = pauseBarButton; + + } else if (playbackState == MPMusicPlaybackStateStopped) { + + navigationBar.topItem.leftBarButtonItem = playBarButton; + + // Even though stopped, invoking 'stop' ensures that the music player will play + // its queue from the start. + [musicPlayer stop]; + + } +} + +- (void) handle_iPodLibraryChanged: (id) notification { + + // Implement this method to update cached collections of media items when the + // user performs a sync while your application is running. This sample performs + // no explicit media queries, so there is nothing to update. +} + + + +#pragma mark Application playback control_________________ + +- (IBAction) playAppSound: (id) sender { + + [appSoundPlayer play]; + playing = YES; + [appSoundButton setEnabled: NO]; +} + +// delegate method for the audio route change alert view; follows the protocol specified +// in the UIAlertViewDelegate protocol. +- (void) alertView: routeChangeAlertView clickedButtonAtIndex: buttonIndex { + + if ((NSInteger) buttonIndex == 1) { + [appSoundPlayer play]; + } else { + [appSoundPlayer setCurrentTime: 0]; + [appSoundButton setEnabled: YES]; + } + + [routeChangeAlertView release]; +} + + + +#pragma mark AV Foundation delegate methods____________ + +- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) appSoundPlayer successfully: (BOOL) flag { + + playing = NO; + [appSoundButton setEnabled: YES]; +} + +- (void) audioPlayerBeginInterruption: player { + + NSLog (@"Interrupted. The system has paused audio playback."); + + if (playing) { + + playing = NO; + interruptedOnPlayback = YES; + } +} + +- (void) audioPlayerEndInterruption: player { + + NSLog (@"Interruption ended. Resuming audio playback."); + + // Reactivates the audio session, whether or not audio was playing + // when the interruption arrived. + [[AVAudioSession sharedInstance] setActive: YES error: nil]; + + if (interruptedOnPlayback) { + + [appSoundPlayer prepareToPlay]; + [appSoundPlayer play]; + playing = YES; + interruptedOnPlayback = NO; + } +} + + + +#pragma mark Table view delegate methods________________ + +// Invoked when the user taps the Done button in the table view. +- (void) musicTableViewControllerDidFinish: (MusicTableViewController *) controller { + + [self dismissModalViewControllerAnimated: YES]; + [self restorePlaybackState]; +} + + + +#pragma mark Application setup____________________________ + +#if TARGET_IPHONE_SIMULATOR +#warning *** Simulator mode: iPod library access works only when running on a device. +#endif + +- (void) setupApplicationAudio { + + // Gets the file system path to the sound to play. + NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: @"sound" + ofType: @"caf"]; + + // Converts the sound's file path to an NSURL object + NSURL *newURL = [[NSURL alloc] initFileURLWithPath: soundFilePath]; + self.soundFileURL = newURL; + [newURL release]; + + // Registers this class as the delegate of the audio session. + [[AVAudioSession sharedInstance] setDelegate: self]; + + // The AmbientSound category allows application audio to mix with Media Player + // audio. The category also indicates that application audio should stop playing + // if the Ring/Siilent switch is set to "silent" or the screen locks. + [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil]; +/* + // Use this code instead to allow the app sound to continue to play when the screen is locked. + [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil]; + + UInt32 doSetProperty = 0; + AudioSessionSetProperty ( + kAudioSessionProperty_OverrideCategoryMixWithOthers, + sizeof (doSetProperty), + &doSetProperty + ); +*/ + + // Registers the audio route change listener callback function + AudioSessionAddPropertyListener ( + kAudioSessionProperty_AudioRouteChange, + audioRouteChangeListenerCallback, + self + ); + + // Activates the audio session. + + NSError *activationError = nil; + [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; + + // Instantiates the AVAudioPlayer object, initializing it with the sound + AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error: nil]; + self.appSoundPlayer = newPlayer; + [newPlayer release]; + + // "Preparing to play" attaches to the audio hardware and ensures that playback + // starts quickly when the user taps Play + [appSoundPlayer prepareToPlay]; + [appSoundPlayer setVolume: 1.0]; + [appSoundPlayer setDelegate: self]; +} + + +// To learn about notifications, see "Notifications" in Cocoa Fundamentals Guide. +- (void) registerForMediaPlayerNotifications { + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter addObserver: self + selector: @selector (handle_NowPlayingItemChanged:) + name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification + object: musicPlayer]; + + [notificationCenter addObserver: self + selector: @selector (handle_PlaybackStateChanged:) + name: MPMusicPlayerControllerPlaybackStateDidChangeNotification + object: musicPlayer]; + +/* + // This sample doesn't use libray change notifications; this code is here to show how + // it's done if you need it. + [notificationCenter addObserver: self + selector: @selector (handle_iPodLibraryChanged:) + name: MPMediaLibraryDidChangeNotification + object: musicPlayer]; + + [[MPMediaLibrary defaultMediaLibrary] beginGeneratingLibraryChangeNotifications]; +*/ + + [musicPlayer beginGeneratingPlaybackNotifications]; +} + + +// To learn about the Settings bundle and user preferences, see User Defaults Programming Topics +// for Cocoa and "The Settings Bundle" in iPhone Application Programming Guide + +// Returns whether or not to use the iPod music player instead of the application music player. +- (BOOL) useiPodPlayer { + + if ([[NSUserDefaults standardUserDefaults] boolForKey: PLAYER_TYPE_PREF_KEY]) { + return YES; + } else { + return NO; + } +} + +// Configure the application. +- (void) viewDidLoad { + + [super viewDidLoad]; + + [self setupApplicationAudio]; + + [self setPlayedMusicOnce: NO]; + + [self setNoArtworkImage: [UIImage imageNamed: @"no_artwork.png"]]; + + [self setPlayBarButton: [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPlay + target: self + action: @selector (playOrPauseMusic:)]]; + + [self setPauseBarButton: [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPause + target: self + action: @selector (playOrPauseMusic:)]]; + + [addOrShowMusicButton setTitle: NSLocalizedString (@"Add Music", @"Title for 'Add Music' button, before user has chosen some music") + forState: UIControlStateNormal]; + + [appSoundButton setTitle: NSLocalizedString (@"Play App Sound", @"Title for 'Play App Sound' button") + forState: UIControlStateNormal]; + + [nowPlayingLabel setText: NSLocalizedString (@"Instructions", @"Brief instructions to user, shown at launch")]; + + // Instantiate the music player. If you specied the iPod music player in the Settings app, + // honor the current state of the built-in iPod app. + if ([self useiPodPlayer]) { + + [self setMusicPlayer: [MPMusicPlayerController iPodMusicPlayer]]; + + if ([musicPlayer nowPlayingItem]) { + + navigationBar.topItem.leftBarButtonItem.enabled = YES; + + // Update the UI to reflect the now-playing item. + [self handle_NowPlayingItemChanged: nil]; + + if ([musicPlayer playbackState] == MPMusicPlaybackStatePaused) { + navigationBar.topItem.leftBarButtonItem = playBarButton; + } + } + + } else { + + [self setMusicPlayer: [MPMusicPlayerController applicationMusicPlayer]]; + + // By default, an application music player takes on the shuffle and repeat modes + // of the built-in iPod app. Here they are both turned off. + [musicPlayer setShuffleMode: MPMusicShuffleModeOff]; + [musicPlayer setRepeatMode: MPMusicRepeatModeNone]; + } + + [self registerForMediaPlayerNotifications]; + + // Configure a timer to change the background color. The changing color represents an + // application that is doing something else while iPod music is playing. + [self setBackgroundColorTimer: [NSTimer scheduledTimerWithTimeInterval: 3.5 + target: self + selector: @selector (updateBackgroundColor) + userInfo: nil + repeats: YES]]; +} + +// Invoked by the backgroundColorTimer. +- (void) updateBackgroundColor { + + [UIView beginAnimations: nil context: nil]; + [UIView setAnimationDuration: 3.0]; + + CGFloat redLevel = rand() / (float) RAND_MAX; + CGFloat greenLevel = rand() / (float) RAND_MAX; + CGFloat blueLevel = rand() / (float) RAND_MAX; + + self.view.backgroundColor = [UIColor colorWithRed: redLevel + green: greenLevel + blue: blueLevel + alpha: 1.0]; + [UIView commitAnimations]; +} + +#pragma mark Application state management_____________ + +- (void) didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void) viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + +/* + // This sample doesn't use libray change notifications; this code is here to show how + // it's done if you need it. + [[NSNotificationCenter defaultCenter] removeObserver: self + name: MPMediaLibraryDidChangeNotification + object: musicPlayer]; + + [[MPMediaLibrary defaultMediaLibrary] endGeneratingLibraryChangeNotifications]; + +*/ + [[NSNotificationCenter defaultCenter] removeObserver: self + name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification + object: musicPlayer]; + + [[NSNotificationCenter defaultCenter] removeObserver: self + name: MPMusicPlayerControllerPlaybackStateDidChangeNotification + object: musicPlayer]; + + [musicPlayer endGeneratingPlaybackNotifications]; + [musicPlayer release]; + + [artworkItem release]; + [backgroundColorTimer invalidate]; + [backgroundColorTimer release]; + [navigationBar release]; + [noArtworkImage release]; + [nowPlayingLabel release]; + [pauseBarButton release]; + [playBarButton release]; + [soundFileURL release]; + [userMediaItemCollection release]; + + [super dealloc]; +} + + +@end diff --git a/AddMusic/Classes/MusicTableViewController.h b/AddMusic/Classes/MusicTableViewController.h new file mode 100644 index 0000000..4a53799 --- /dev/null +++ b/AddMusic/Classes/MusicTableViewController.h @@ -0,0 +1,79 @@ +/* + File: MusicTableViewController.h +Abstract: Table view controller class for AddMusic. Shows the list +of music chosen by the user. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import + +@protocol MusicTableViewControllerDelegate; // forward declaration + + +@interface MusicTableViewController : UIViewController { + + id delegate; + IBOutlet UITableView *mediaItemCollectionTable; + IBOutlet UIBarButtonItem *addMusicButton; +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, retain) UITableView *mediaItemCollectionTable; +@property (nonatomic, retain) UIBarButtonItem *addMusicButton; + +- (IBAction) showMediaPicker: (id) sender; +- (IBAction) doneShowingMusicList: (id) sender; + +@end + + + +@protocol MusicTableViewControllerDelegate + +// implemented in MainViewController.m +- (void) musicTableViewControllerDidFinish: (MusicTableViewController *) controller; +- (void) updatePlayerQueueWithMediaCollection: (MPMediaItemCollection *) mediaItemCollection; + +@end + diff --git a/AddMusic/Classes/MusicTableViewController.m b/AddMusic/Classes/MusicTableViewController.m new file mode 100644 index 0000000..0793793 --- /dev/null +++ b/AddMusic/Classes/MusicTableViewController.m @@ -0,0 +1,185 @@ +/* + File: MusicTableViewController.m +Abstract: Table view controller class for AddMusic. Shows the list +of music chosen by the user. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + + +#import "MusicTableViewController.h" +#import "MainViewController.h" + +@implementation MusicTableViewController + +static NSString *kCellIdentifier = @"Cell"; + +@synthesize delegate; // The main view controller is the delegate for this class. +@synthesize mediaItemCollectionTable; // The table shown in this class's view. +@synthesize addMusicButton; // The button for invoking the media item picker. Setting the title + // programmatically supports localization. + + +// Configures the table view. +- (void) viewDidLoad { + + [super viewDidLoad]; + + [self.addMusicButton setTitle: NSLocalizedString (@"AddMusicFromTableView", @"Add button shown on table view for invoking the media item picker")]; + + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; +} + + +// When the user taps Done, invokes the delegate's method that dismisses the table view. +- (IBAction) doneShowingMusicList: (id) sender { + + [self.delegate musicTableViewControllerDidFinish: self]; +} + + +// Configures and displays the media item picker. +- (IBAction) showMediaPicker: (id) sender { + + MPMediaPickerController *picker = + [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio]; + + picker.delegate = self; + picker.allowsPickingMultipleItems = YES; + picker.prompt = NSLocalizedString (@"AddSongsPrompt", @"Prompt to user to choose some songs to play"); + + [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleDefault animated:YES]; + + [self presentModalViewController: picker animated: YES]; + [picker release]; +} + + +// Responds to the user tapping Done after choosing music. +- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection { + + [self dismissModalViewControllerAnimated: YES]; + [self.delegate updatePlayerQueueWithMediaCollection: mediaItemCollection]; + [self.mediaItemCollectionTable reloadData]; + + [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated:YES]; +} + + +// Responds to the user tapping done having chosen no music. +- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker { + + [self dismissModalViewControllerAnimated: YES]; + + [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated:YES]; +} + + + +#pragma mark Table view methods________________________ + +// To learn about using table views, see the TableViewSuite sample code +// and Table View Programming Guide for iPhone OS. + +- (NSInteger) tableView: (UITableView *) table numberOfRowsInSection: (NSInteger)section { + + MainViewController *mainViewController = (MainViewController *) self.delegate; + MPMediaItemCollection *currentQueue = mainViewController.userMediaItemCollection; + return [currentQueue.items count]; +} + +- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath { + + NSInteger row = [indexPath row]; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: kCellIdentifier]; + + if (cell == nil) { + + cell = [[[UITableViewCell alloc] initWithFrame: CGRectZero + reuseIdentifier: kCellIdentifier] autorelease]; + } + + MainViewController *mainViewController = (MainViewController *) self.delegate; + MPMediaItemCollection *currentQueue = mainViewController.userMediaItemCollection; + MPMediaItem *anItem = (MPMediaItem *)[currentQueue.items objectAtIndex: row]; + + if (anItem) { + cell.textLabel.text = [anItem valueForProperty:MPMediaItemPropertyTitle]; + } + + [tableView deselectRowAtIndexPath: indexPath animated: YES]; + + return cell; +} + +// To conform to the Human Interface Guidelines, selections should not be persistent -- +// deselect the row after it has been selected. +- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath { + + [tableView deselectRowAtIndexPath: indexPath animated: YES]; +} + +#pragma mark Application state management_____________ +// Standard methods for managing application state. +- (void)didReceiveMemoryWarning { + + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + + [super dealloc]; +} + + +@end diff --git a/AddMusic/ReadMe.txt b/AddMusic/ReadMe.txt new file mode 100644 index 0000000..7706c66 --- /dev/null +++ b/AddMusic/ReadMe.txt @@ -0,0 +1,92 @@ +AddMusic + +========================================================================= +DESCRIPTION: + +AddMusic demonstrates basic use of iPod library access, part of the Media Player framework. Use iPod library access to play songs, audio books, and audio podcasts that are synced from a user's desktop iTunes library. This sample uses the Media Player framework's built-in user interface for choosing music. + +AddMusic also demonstrates how to mix application audio with iPod library audio. The sample includes code that configures application audio behavior using the AVAudioSession class and Audio Session Services. + +The sample's Settings bundle lets you configure one runtime option using the built-in Settings application. You can specify that AddMusic use the iPod music player, which shares state with the built-in iPod application; or the application music player, whose state is independent of the built-in iPod application. + +The sample includes code to handle interruptions and audio hardware route changes for application audio. The system handles these things automatically for sounds played by the application using iPod library access. + +To test interruption behavior, use the built-in Clock application. Set an alarm that will sound during playback. At the time the alarm will sound, ensure that iPod audio or application audio (or both) is playing, depending on which behavior you want to test. When the alarm sounds, dismiss it. + +To test audio hardware route change behavior, plug in or unplug a headset during playback. There's an alert that appears only when application audio is playing and you unplug the headset. When only iPod audio is playing and you unplug the headset, the system pauses iPod playback. + +The sample is internationalized. See the Localized.strings file in the project's Resources/en.lproj folder. + +AddMusic shows how to: + + * Instantiate the iPod music player and the application music player. + * Display and dismiss the media item picker. + * Get media items chosen by the user. + * Set a music player's playback queue. + * Display metadata of music chosen by the user, including song title, artist name, and artwork. + * Register for, and handle, music player notifications. + +As part of showing how to mix application sound with iPod library sound, this sample application also shows how to: + + * Play audio using AV Foundation + * Configure and use the application's audio session + +AddMusic does not demonstrate how to perform media queries. + + +========================================================================= +RELATED INFORMATION: + +iPod Library Access Guide, September 2009 +Media Player Framework Reference, September 2009 +Core Audio Overview, November 2008 +Audio Session Programming Guide, September 2009 +AV Foundation Framework Reference, September 2009 + + +========================================================================= +BUILD REQUIREMENTS: + +Mac OS X v10.5.7, Xcode 3.1, iPhone OS 3.0 + + +========================================================================= +RUNTIME REQUIREMENTS: + +iPhone: iPhone OS 3.0 +iPod library access is not functional in the Simulator. + + +========================================================================= +PACKAGING LIST: + +AddMusicAppDelegate.h +AddMusicAppDelegate.m + +The AddMusicAppDelegate class defines the application delegate object, responsible for instantiating the main controller object (defined in the MainViewController class) and adding the application's main view to the application window. + + +MainViewController.h +MainViewController.m + +The MainViewController class defines the controller object for the application. The object helps set up the user interface, responds to and manages user interaction, responds to changes in the state of the muaic player, handles interruptions to the application's audio session, and handles various housekeeping duties. + + +MusicTableViewController.h +MusicTableViewController.m + +The MusicTableViewController class defines the controller object for a table that displays titles of media items chosen by the user. It provides no manipulation of the media items. + + +========================================================================= +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.1.1. Minor changes. + +Version 1.1. Improved the audio hardware route change callback function. Improved text of ReadMe file. + +Version 1.0. First version. + + +========================================================================= +Copyright (C) 2009 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/AddMusic/Resources/Default.png b/AddMusic/Resources/Default.png new file mode 100644 index 0000000..bfd728c Binary files /dev/null and b/AddMusic/Resources/Default.png differ diff --git a/AddMusic/Resources/Settings.bundle/Root.plist b/AddMusic/Resources/Settings.bundle/Root.plist new file mode 100644 index 0000000..b675481 --- /dev/null +++ b/AddMusic/Resources/Settings.bundle/Root.plist @@ -0,0 +1,27 @@ + + + + + StringsTable + Root + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Configuration + + + Type + PSToggleSwitchSpecifier + Title + Use iPodPlayer + Key + player_type_preference + DefaultValue + + + + + diff --git a/AddMusic/Resources/Settings.bundle/en.lproj/Root.strings b/AddMusic/Resources/Settings.bundle/en.lproj/Root.strings new file mode 100644 index 0000000..8cd87b9 Binary files /dev/null and b/AddMusic/Resources/Settings.bundle/en.lproj/Root.strings differ diff --git a/AddMusic/Resources/background.png b/AddMusic/Resources/background.png new file mode 100644 index 0000000..905c69c Binary files /dev/null and b/AddMusic/Resources/background.png differ diff --git a/AddMusic/Resources/en.lproj/Localizable.strings b/AddMusic/Resources/en.lproj/Localizable.strings new file mode 100644 index 0000000..b9ca741 Binary files /dev/null and b/AddMusic/Resources/en.lproj/Localizable.strings differ diff --git a/AddMusic/Resources/en.lproj/MainView.xib b/AddMusic/Resources/en.lproj/MainView.xib new file mode 100644 index 0000000..167dd3a --- /dev/null +++ b/AddMusic/Resources/en.lproj/MainView.xib @@ -0,0 +1,453 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 256 + {320, 460} + + NO + YES + 4 + YES + {{0, 0}, {0, 0}} + + NSImage + background.png + + + + + 290 + {320, 44} + + NO + NO + 1 + + YES + + + AddMusic + + NO + 1 + 18 + + + + + + + 292 + {{20, 390}, {130, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.300000e+01 + 16 + + 1 + + 3 + MQA + + + 3 + MC43NQA + + 2 + + + + 1 + MCAwIDAAA + + + 3 + MC41AA + + + + + 292 + {{169, 390}, {130, 37}} + + NO + NO + 0 + 0 + + 1 + + + 3 + MC43NQA + + + + + + + + 292 + {{19, 210}, {280, 41}} + + NO + YES + NO + Your Application Here + + Helvetica-Bold + 1.900000e+01 + 16 + + + + 1 + 1.000000e+01 + 1 + + + + 292 + {{0, 439}, {320, 21}} + + + 3 + MCAwLjc2OTk5OTk4AA + + YES + NO + + + Helvetica-Bold + 1.200000e+01 + 16 + + + 1 + MC45OTQ4OTc5NiAwLjk5NDg5Nzk2IDAuOTk0ODk3OTYAA + + + + 1 + MC43OTU5MTgzNSAwLjc5NTkxODM1IDAuNzk1OTE4MzUgMC45MjAwMDAwMgA + + 1 + NO + 1.000000e+01 + NO + + + {320, 460} + + + 3 + MQA + + + + + + + + YES + + + view + + + + 13 + + + + navigationBar + + + + 19 + + + + playAppSound: + + + 7 + + 47 + + + + playOrPauseMusic: + + + + 48 + + + + addOrShowMusicButton + + + + 53 + + + + appSoundButton + + + + 54 + + + + AddMusicOrShowMusic: + + + 7 + + 57 + + + + nowPlayingLabel + + + + 58 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 4 + + + YES + + + + + + 6 + + + YES + + + + + + 25 + + + + + 41 + + + + + 43 + + + + + 46 + + + + + 50 + + + + + 56 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 25.IBPluginDependency + 4.IBPluginDependency + 41.IBPluginDependency + 43.IBPluginDependency + 46.IBPluginDependency + 50.IBPluginDependency + 6.IBPluginDependency + + + YES + MainViewController + UIResponder + {{477, 276}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 58 + + + + YES + + MainViewController + UIViewController + + YES + + YES + AddMusicOrShowMusic: + playAppSound: + playOrPauseMusic: + + + YES + id + id + id + + + + YES + + YES + addOrShowMusicButton + appSoundButton + artworkItem + navigationBar + nowPlayingLabel + + + YES + UIButton + UIButton + UIBarButtonItem + UINavigationBar + UILabel + + + + IBProjectSource + Classes/MainViewController.h + + + + + 0 + ../../AddMusic.xcodeproj + 3 + 3.0 + + diff --git a/AddMusic/Resources/en.lproj/MainWindow.xib b/AddMusic/Resources/en.lproj/MainWindow.xib new file mode 100644 index 0000000..9b00a43 --- /dev/null +++ b/AddMusic/Resources/en.lproj/MainWindow.xib @@ -0,0 +1,243 @@ + + + + 768 + 9J56 + 677 + 949.46 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + MainView + + + + + + YES + + + window + + + + 5 + + + + mainViewController + + + + 18 + + + + delegate + + + + 19 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 15 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 15.CustomClassName + 15.IBEditorWindowLastContentRect + 15.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + MainViewController + {{0, 1385}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{273, 314}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AddMusicAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 19 + + + + YES + + AddMusicAppDelegate + NSObject + + YES + + YES + mainViewController + window + + + YES + MainViewController + UIWindow + + + + IBProjectSource + Classes/AddMusicAppDelegate.h + + + + AddMusicAppDelegate + NSObject + + IBUserSource + + + + + MainViewController + UIViewController + + YES + + YES + imageView + nowPlayingItem + playbackItem + + + YES + UIImageView + UIBarButtonItem + UIBarButtonItem + + + + IBProjectSource + MainViewController.h + + + + + 0 + AddMusic.xcodeproj + 3 + 3.0 + + diff --git a/AddMusic/Resources/en.lproj/MusicTableView.xib b/AddMusic/Resources/en.lproj/MusicTableView.xib new file mode 100644 index 0000000..8c0668e --- /dev/null +++ b/AddMusic/Resources/en.lproj/MusicTableView.xib @@ -0,0 +1,319 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {{0, 44}, {320, 416}} + + + 3 + MQA + + NO + YES + NO + NO + NO + 1 + 0 + 4.400000e+01 + 2.200000e+01 + 2.200000e+01 + + + + 290 + {320, 44} + + NO + NO + 1 + + YES + + + Music + + 2 + 0 + + + Add + 1 + + + + + + {320, 460} + + + 1 + MCAwIDAAA + + + + + + + YES + + + view + + + + 3 + + + + dataSource + + + + 13 + + + + delegate + + + + 14 + + + + doneShowingMusicList: + + + + 18 + + + + showMediaPicker: + + + + 19 + + + + mediaItemCollectionTable + + + + 20 + + + + addMusicButton + + + + 21 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 4 + + + YES + + + + + + 5 + + + YES + + + + + + + 6 + + + + + 8 + + + + + 10 + + + YES + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 10.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + 6.IBPluginDependency + 8.IBPluginDependency + + + YES + MusicTableViewController + UIResponder + {{479, 253}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 21 + + + + YES + + MusicTableViewController + UIViewController + + YES + + YES + doneShowingMusicList: + showMediaPicker: + + + YES + id + id + + + + YES + + YES + addMusicButton + delegate + mediaItemCollectionTable + + + YES + UIBarButtonItem + id + UITableView + + + + IBProjectSource + Classes/MusicTableViewController.h + + + + + 0 + ../../AddMusic.xcodeproj + 3 + 3.0 + + diff --git a/AddMusic/Resources/no_artwork.png b/AddMusic/Resources/no_artwork.png new file mode 100644 index 0000000..923adac Binary files /dev/null and b/AddMusic/Resources/no_artwork.png differ diff --git a/AddMusic/Resources/sound.caf b/AddMusic/Resources/sound.caf new file mode 100644 index 0000000..ffc5a60 Binary files /dev/null and b/AddMusic/Resources/sound.caf differ diff --git a/AddMusic/main.m b/AddMusic/main.m new file mode 100644 index 0000000..8deb314 --- /dev/null +++ b/AddMusic/main.m @@ -0,0 +1,57 @@ +/* + File: main.m +Abstract: main.m file for AddMusic. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/AdvancedTableViewCells.zip b/AdvancedTableViewCells.zip new file mode 100644 index 0000000..4614394 Binary files /dev/null and b/AdvancedTableViewCells.zip differ diff --git a/AdvancedTableViewCells/AdvancedTableViewCells-Info.plist b/AdvancedTableViewCells/AdvancedTableViewCells-Info.plist new file mode 100644 index 0000000..062da18 --- /dev/null +++ b/AdvancedTableViewCells/AdvancedTableViewCells-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.5 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/AdvancedTableViewCells/AdvancedTableViewCells.xcodeproj/project.pbxproj b/AdvancedTableViewCells/AdvancedTableViewCells.xcodeproj/project.pbxproj new file mode 100755 index 0000000..806bd86 --- /dev/null +++ b/AdvancedTableViewCells/AdvancedTableViewCells.xcodeproj/project.pbxproj @@ -0,0 +1,425 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1811EE0411D015E20068DA4C /* Baseball.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF311D015E20068DA4C /* Baseball.png */; }; + 1811EE0511D015E20068DA4C /* Blocks.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF411D015E20068DA4C /* Blocks.png */; }; + 1811EE0611D015E20068DA4C /* Checkers.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF511D015E20068DA4C /* Checkers.png */; }; + 1811EE0711D015E20068DA4C /* DarkBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF611D015E20068DA4C /* DarkBackground.png */; }; + 1811EE0811D015E20068DA4C /* Dinner.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF711D015E20068DA4C /* Dinner.png */; }; + 1811EE0911D015E20068DA4C /* Football.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF811D015E20068DA4C /* Football.png */; }; + 1811EE0A11D015E20068DA4C /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDF911D015E20068DA4C /* Icon-72.png */; }; + 1811EE0B11D015E20068DA4C /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDFA11D015E20068DA4C /* Icon-Small-50.png */; }; + 1811EE0C11D015E20068DA4C /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDFB11D015E20068DA4C /* Icon-Small.png */; }; + 1811EE0D11D015E20068DA4C /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDFC11D015E20068DA4C /* Icon-Small@2x.png */; }; + 1811EE0E11D015E20068DA4C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDFD11D015E20068DA4C /* Icon.png */; }; + 1811EE0F11D015E20068DA4C /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EDFE11D015E20068DA4C /* Icon@2x.png */; }; + 1811EE1111D015E20068DA4C /* LightBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EE0011D015E20068DA4C /* LightBackground.png */; }; + 1811EE1211D015E20068DA4C /* MathGraph.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EE0111D015E20068DA4C /* MathGraph.png */; }; + 1811EE1311D015E20068DA4C /* StarsBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EE0211D015E20068DA4C /* StarsBackground.png */; }; + 1811EE1411D015E20068DA4C /* StarsForeground.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EE0311D015E20068DA4C /* StarsForeground.png */; }; + 1D3623260D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + 53B50ADA11A58B200015105A /* IndividualSubviewsBasedApplicationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53B50AD411A58B200015105A /* IndividualSubviewsBasedApplicationCell.xib */; }; + 53B50ADB11A58B200015105A /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53B50AD611A58B200015105A /* MainWindow.xib */; }; + 53B50ADC11A58B200015105A /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53B50AD811A58B200015105A /* RootViewController.xib */; }; + 969234680FBCCE850009907C /* ApplicationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 969234670FBCCE850009907C /* ApplicationCell.m */; }; + 969234720FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 969234710FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.m */; }; + 969234750FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 969234740FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.m */; }; + 969234870FBD35720009907C /* RatingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 969234860FBD35720009907C /* RatingView.m */; }; + 96B2D9290FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 96B2D9280FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.m */; }; + 96B7E9350FCA18E3001F1DF9 /* Data.plist in Resources */ = {isa = PBXBuildFile; fileRef = 96B7E9340FCA18E3001F1DF9 /* Data.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1811EDF311D015E20068DA4C /* Baseball.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Baseball.png; path = images/Baseball.png; sourceTree = ""; }; + 1811EDF411D015E20068DA4C /* Blocks.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Blocks.png; path = images/Blocks.png; sourceTree = ""; }; + 1811EDF511D015E20068DA4C /* Checkers.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Checkers.png; path = images/Checkers.png; sourceTree = ""; }; + 1811EDF611D015E20068DA4C /* DarkBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DarkBackground.png; path = images/DarkBackground.png; sourceTree = ""; }; + 1811EDF711D015E20068DA4C /* Dinner.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Dinner.png; path = images/Dinner.png; sourceTree = ""; }; + 1811EDF811D015E20068DA4C /* Football.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Football.png; path = images/Football.png; sourceTree = ""; }; + 1811EDF911D015E20068DA4C /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 1811EDFA11D015E20068DA4C /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 1811EDFB11D015E20068DA4C /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 1811EDFC11D015E20068DA4C /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 1811EDFD11D015E20068DA4C /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 1811EDFE11D015E20068DA4C /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 1811EE0011D015E20068DA4C /* LightBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LightBackground.png; path = images/LightBackground.png; sourceTree = ""; }; + 1811EE0111D015E20068DA4C /* MathGraph.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MathGraph.png; path = images/MathGraph.png; sourceTree = ""; }; + 1811EE0211D015E20068DA4C /* StarsBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = StarsBackground.png; path = images/StarsBackground.png; sourceTree = ""; }; + 1811EE0311D015E20068DA4C /* StarsForeground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = StarsForeground.png; path = images/StarsForeground.png; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedTableViewCellsAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AdvancedTableViewCellsAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* AdvancedTableViewCells.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdvancedTableViewCells.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2812E2171036105C0074E44A /* AdvancedTableViewCells_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedTableViewCells_Prefix.pch; sourceTree = ""; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53B50AD511A58B200015105A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/IndividualSubviewsBasedApplicationCell.xib; sourceTree = ""; }; + 53B50AD711A58B200015105A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 53B50AD911A58B200015105A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* AdvancedTableViewCells-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AdvancedTableViewCells-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + 963ED3160FE80AB800ACBB2D /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 969234660FBCCE850009907C /* ApplicationCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationCell.h; sourceTree = ""; }; + 969234670FBCCE850009907C /* ApplicationCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ApplicationCell.m; sourceTree = ""; }; + 969234700FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndividualSubviewsBasedApplicationCell.h; sourceTree = ""; }; + 969234710FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IndividualSubviewsBasedApplicationCell.m; sourceTree = ""; }; + 969234730FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompositeSubviewBasedApplicationCell.h; sourceTree = ""; }; + 969234740FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CompositeSubviewBasedApplicationCell.m; sourceTree = ""; }; + 969234850FBD35720009907C /* RatingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RatingView.h; sourceTree = ""; }; + 969234860FBD35720009907C /* RatingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RatingView.m; sourceTree = ""; }; + 96B2D9270FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridSubviewBasedApplicationCell.h; sourceTree = ""; }; + 96B2D9280FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridSubviewBasedApplicationCell.m; sourceTree = ""; }; + 96B7E9340FCA18E3001F1DF9 /* Data.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Data.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + 1D3623240D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.h */, + 1D3623250D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.m */, + 96B2D92A0FD9E69D00AD6042 /* Cells */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* AdvancedTableViewCells.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 963ED3160FE80AB800ACBB2D /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 2812E2171036105C0074E44A /* AdvancedTableViewCells_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 1811EDF311D015E20068DA4C /* Baseball.png */, + 1811EDF411D015E20068DA4C /* Blocks.png */, + 1811EDF511D015E20068DA4C /* Checkers.png */, + 1811EDF611D015E20068DA4C /* DarkBackground.png */, + 1811EDF711D015E20068DA4C /* Dinner.png */, + 1811EDF811D015E20068DA4C /* Football.png */, + 1811EDF911D015E20068DA4C /* Icon-72.png */, + 1811EDFA11D015E20068DA4C /* Icon-Small-50.png */, + 1811EDFB11D015E20068DA4C /* Icon-Small.png */, + 1811EDFC11D015E20068DA4C /* Icon-Small@2x.png */, + 1811EDFD11D015E20068DA4C /* Icon.png */, + 1811EDFE11D015E20068DA4C /* Icon@2x.png */, + 1811EE0011D015E20068DA4C /* LightBackground.png */, + 1811EE0111D015E20068DA4C /* MathGraph.png */, + 1811EE0211D015E20068DA4C /* StarsBackground.png */, + 1811EE0311D015E20068DA4C /* StarsForeground.png */, + 53B50AD411A58B200015105A /* IndividualSubviewsBasedApplicationCell.xib */, + 53B50AD611A58B200015105A /* MainWindow.xib */, + 53B50AD811A58B200015105A /* RootViewController.xib */, + 8D1107310486CEB800E47090 /* AdvancedTableViewCells-Info.plist */, + 96B7E9340FCA18E3001F1DF9 /* Data.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 96B2D92A0FD9E69D00AD6042 /* Cells */ = { + isa = PBXGroup; + children = ( + 969234660FBCCE850009907C /* ApplicationCell.h */, + 969234670FBCCE850009907C /* ApplicationCell.m */, + 96B2D92C0FD9E6C800AD6042 /* Individual Subviews */, + 96B2D92D0FD9E6E600AD6042 /* Composite Subview */, + 96B2D92E0FD9E6F800AD6042 /* Hybrid */, + ); + name = Cells; + sourceTree = ""; + }; + 96B2D92C0FD9E6C800AD6042 /* Individual Subviews */ = { + isa = PBXGroup; + children = ( + 969234700FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.h */, + 969234710FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.m */, + 969234850FBD35720009907C /* RatingView.h */, + 969234860FBD35720009907C /* RatingView.m */, + ); + name = "Individual Subviews"; + sourceTree = ""; + }; + 96B2D92D0FD9E6E600AD6042 /* Composite Subview */ = { + isa = PBXGroup; + children = ( + 969234730FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.h */, + 969234740FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.m */, + ); + name = "Composite Subview"; + sourceTree = ""; + }; + 96B2D92E0FD9E6F800AD6042 /* Hybrid */ = { + isa = PBXGroup; + children = ( + 96B2D9270FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.h */, + 96B2D9280FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.m */, + ); + name = Hybrid; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* AdvancedTableViewCells */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AdvancedTableViewCells" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AdvancedTableViewCells; + productName = AdvancedTableViewCells; + productReference = 1D6058910D05DD3D006BFB54 /* AdvancedTableViewCells.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AdvancedTableViewCells" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* AdvancedTableViewCells */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96B7E9350FCA18E3001F1DF9 /* Data.plist in Resources */, + 53B50ADA11A58B200015105A /* IndividualSubviewsBasedApplicationCell.xib in Resources */, + 53B50ADB11A58B200015105A /* MainWindow.xib in Resources */, + 53B50ADC11A58B200015105A /* RootViewController.xib in Resources */, + 1811EE0411D015E20068DA4C /* Baseball.png in Resources */, + 1811EE0511D015E20068DA4C /* Blocks.png in Resources */, + 1811EE0611D015E20068DA4C /* Checkers.png in Resources */, + 1811EE0711D015E20068DA4C /* DarkBackground.png in Resources */, + 1811EE0811D015E20068DA4C /* Dinner.png in Resources */, + 1811EE0911D015E20068DA4C /* Football.png in Resources */, + 1811EE0A11D015E20068DA4C /* Icon-72.png in Resources */, + 1811EE0B11D015E20068DA4C /* Icon-Small-50.png in Resources */, + 1811EE0C11D015E20068DA4C /* Icon-Small.png in Resources */, + 1811EE0D11D015E20068DA4C /* Icon-Small@2x.png in Resources */, + 1811EE0E11D015E20068DA4C /* Icon.png in Resources */, + 1811EE0F11D015E20068DA4C /* Icon@2x.png in Resources */, + 1811EE1111D015E20068DA4C /* LightBackground.png in Resources */, + 1811EE1211D015E20068DA4C /* MathGraph.png in Resources */, + 1811EE1311D015E20068DA4C /* StarsBackground.png in Resources */, + 1811EE1411D015E20068DA4C /* StarsForeground.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AdvancedTableViewCellsAppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + 969234680FBCCE850009907C /* ApplicationCell.m in Sources */, + 969234720FBCD3680009907C /* IndividualSubviewsBasedApplicationCell.m in Sources */, + 969234750FBCD37D0009907C /* CompositeSubviewBasedApplicationCell.m in Sources */, + 969234870FBD35720009907C /* RatingView.m in Sources */, + 96B2D9290FD9E69200AD6042 /* HybridSubviewBasedApplicationCell.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53B50AD411A58B200015105A /* IndividualSubviewsBasedApplicationCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 53B50AD511A58B200015105A /* en */, + ); + name = IndividualSubviewsBasedApplicationCell.xib; + sourceTree = ""; + }; + 53B50AD611A58B200015105A /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53B50AD711A58B200015105A /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 53B50AD811A58B200015105A /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 53B50AD911A58B200015105A /* en */, + ); + name = RootViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AdvancedTableViewCells_Prefix.pch; + INFOPLIST_FILE = "AdvancedTableViewCells-Info.plist"; + PRODUCT_NAME = AdvancedTableViewCells; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AdvancedTableViewCells_Prefix.pch; + INFOPLIST_FILE = "AdvancedTableViewCells-Info.plist"; + PRODUCT_NAME = AdvancedTableViewCells; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AdvancedTableViewCells" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AdvancedTableViewCells" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/AdvancedTableViewCells/AdvancedTableViewCells_Prefix.pch b/AdvancedTableViewCells/AdvancedTableViewCells_Prefix.pch new file mode 100644 index 0000000..ad711c6 --- /dev/null +++ b/AdvancedTableViewCells/AdvancedTableViewCells_Prefix.pch @@ -0,0 +1,53 @@ +/* + File: AdvancedTableViewCells_Prefix.pch + Abstract: The precompiled header for this sample application. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/AdvancedTableViewCells/Classes/AdvancedTableViewCellsAppDelegate.h b/AdvancedTableViewCells/Classes/AdvancedTableViewCellsAppDelegate.h new file mode 100644 index 0000000..b0e89b9 --- /dev/null +++ b/AdvancedTableViewCells/Classes/AdvancedTableViewCellsAppDelegate.h @@ -0,0 +1,58 @@ +/* + File: AdvancedTableViewCellsAppDelegate.h + Abstract: The application's delegate to setup its window and content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +@interface AdvancedTableViewCellsAppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +@end + diff --git a/AdvancedTableViewCells/Classes/AdvancedTableViewCellsAppDelegate.m b/AdvancedTableViewCells/Classes/AdvancedTableViewCellsAppDelegate.m new file mode 100644 index 0000000..3954785 --- /dev/null +++ b/AdvancedTableViewCells/Classes/AdvancedTableViewCellsAppDelegate.m @@ -0,0 +1,79 @@ +/* + File: AdvancedTableViewCellsAppDelegate.m + Abstract: The application's delegate to setup its window and content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "AdvancedTableViewCellsAppDelegate.h" +#import "RootViewController.h" + + +@implementation AdvancedTableViewCellsAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc +{ + [navigationController release]; + [window release]; + [super dealloc]; +} + +@end + diff --git a/AdvancedTableViewCells/Classes/ApplicationCell.h b/AdvancedTableViewCells/Classes/ApplicationCell.h new file mode 100644 index 0000000..800aaf0 --- /dev/null +++ b/AdvancedTableViewCells/Classes/ApplicationCell.h @@ -0,0 +1,72 @@ +/* + File: ApplicationCell.h + Abstract: The abstract superclass of the three cell classes used to display the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@interface ApplicationCell : UITableViewCell +{ + BOOL useDarkBackground; + + UIImage *icon; + NSString *publisher; + NSString *name; + float rating; + NSInteger numRatings; + NSString *price; +} + +@property BOOL useDarkBackground; + +@property(retain) UIImage *icon; +@property(retain) NSString *publisher; +@property(retain) NSString *name; +@property float rating; +@property NSInteger numRatings; +@property(retain) NSString *price; + +@end diff --git a/AdvancedTableViewCells/Classes/ApplicationCell.m b/AdvancedTableViewCells/Classes/ApplicationCell.m new file mode 100644 index 0000000..606857c --- /dev/null +++ b/AdvancedTableViewCells/Classes/ApplicationCell.m @@ -0,0 +1,78 @@ +/* + File: ApplicationCell.m + Abstract: The abstract superclass of the three cell classes used to display the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "ApplicationCell.h" + +@implementation ApplicationCell + +@synthesize useDarkBackground, icon, publisher, name, rating, numRatings, price; + +- (void)setUseDarkBackground:(BOOL)flag +{ + if (flag != useDarkBackground || !self.backgroundView) + { + useDarkBackground = flag; + + NSString *backgroundImagePath = [[NSBundle mainBundle] pathForResource:useDarkBackground ? @"DarkBackground" : @"LightBackground" ofType:@"png"]; + UIImage *backgroundImage = [[UIImage imageWithContentsOfFile:backgroundImagePath] stretchableImageWithLeftCapWidth:0.0 topCapHeight:1.0]; + self.backgroundView = [[[UIImageView alloc] initWithImage:backgroundImage] autorelease]; + self.backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.backgroundView.frame = self.bounds; + } +} + +- (void)dealloc +{ + [icon release]; + [publisher release]; + [name release]; + [price release]; + + [super dealloc]; +} + +@end diff --git a/AdvancedTableViewCells/Classes/CompositeSubviewBasedApplicationCell.h b/AdvancedTableViewCells/Classes/CompositeSubviewBasedApplicationCell.h new file mode 100644 index 0000000..2bad9fa --- /dev/null +++ b/AdvancedTableViewCells/Classes/CompositeSubviewBasedApplicationCell.h @@ -0,0 +1,56 @@ +/* + File: CompositeSubviewBasedApplicationCell.h + Abstract: The subclass of ApplicationCell that uses a single view to draw the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ApplicationCell.h" + +@interface CompositeSubviewBasedApplicationCell : ApplicationCell +{ + UIView *cellContentView; +} + +@end diff --git a/AdvancedTableViewCells/Classes/CompositeSubviewBasedApplicationCell.m b/AdvancedTableViewCells/Classes/CompositeSubviewBasedApplicationCell.m new file mode 100644 index 0000000..16040fc --- /dev/null +++ b/AdvancedTableViewCells/Classes/CompositeSubviewBasedApplicationCell.m @@ -0,0 +1,151 @@ +/* + File: CompositeSubviewBasedApplicationCell.m + Abstract: The subclass of ApplicationCell that uses a single view to draw the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "CompositeSubviewBasedApplicationCell.h" + +#define MAX_RATING 5.0 + +@interface CompositeSubviewBasedApplicationCellContentView : UIView +{ + ApplicationCell *_cell; + BOOL _highlighted; +} + +@end + +@implementation CompositeSubviewBasedApplicationCellContentView + +- (id)initWithFrame:(CGRect)frame cell:(ApplicationCell *)cell +{ + if (self = [super initWithFrame:frame]) + { + _cell = cell; + + self.opaque = YES; + self.backgroundColor = _cell.backgroundColor; + } + + return self; +} + +- (void)drawRect:(CGRect)rect +{ + [_cell.icon drawAtPoint:CGPointMake(11.0, 5.0)]; + + _highlighted ? [[UIColor whiteColor] set] : [[UIColor blackColor] set]; + [_cell.name drawAtPoint:CGPointMake(81.0, 22.0) withFont:[UIFont boldSystemFontOfSize:17.0]]; + + _highlighted ? [[UIColor whiteColor] set] : [[UIColor colorWithWhite:0.23 alpha:1.0] set]; + [_cell.publisher drawAtPoint:CGPointMake(81.0, 8.0) withFont:[UIFont boldSystemFontOfSize:11.0]]; + + [[NSString stringWithFormat:@"%d Ratings", _cell.numRatings] drawAtPoint:CGPointMake(157.0, 46.0) withFont:[UIFont systemFontOfSize:11.0]]; + + CGSize priceSize = [_cell.price sizeWithFont:[UIFont boldSystemFontOfSize:11.0]]; + [_cell.price drawAtPoint:CGPointMake(self.bounds.size.width - priceSize.width - 8.0, 28.0) withFont:[UIFont boldSystemFontOfSize:11.0]]; + + CGPoint ratingImageOrigin = CGPointMake(81.0, 45.0); + UIImage *ratingBackgroundImage = [UIImage imageNamed:@"StarsBackground.png"]; + [ratingBackgroundImage drawAtPoint:ratingImageOrigin]; + UIImage *ratingForegroundImage = [UIImage imageNamed:@"StarsForeground.png"]; + UIRectClip(CGRectMake(ratingImageOrigin.x, ratingImageOrigin.y, ratingForegroundImage.size.width * (_cell.rating / MAX_RATING), ratingForegroundImage.size.height)); + [ratingForegroundImage drawAtPoint:ratingImageOrigin]; +} + +- (void)setHighlighted:(BOOL)highlighted +{ + _highlighted = highlighted; + [self setNeedsDisplay]; +} + +- (BOOL)isHighlighted +{ + return _highlighted; +} + +@end + +#pragma mark - + +@implementation CompositeSubviewBasedApplicationCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) + { + cellContentView = [[CompositeSubviewBasedApplicationCellContentView alloc] initWithFrame:CGRectInset(self.contentView.bounds, 0.0, 1.0) cell:self]; + cellContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + cellContentView.contentMode = UIViewContentModeRedraw; + [self.contentView addSubview:cellContentView]; + } + + return self; +} + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + + [UIView setAnimationsEnabled:NO]; + CGSize contentSize = cellContentView.bounds.size; + cellContentView.contentStretch = CGRectMake(225.0 / contentSize.width, 0.0, (contentSize.width - 260.0) / contentSize.width, 1.0); + [UIView setAnimationsEnabled:YES]; +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + cellContentView.backgroundColor = backgroundColor; +} + +- (void)dealloc +{ + [cellContentView release]; + + [super dealloc]; +} + +@end diff --git a/AdvancedTableViewCells/Classes/HybridSubviewBasedApplicationCell.h b/AdvancedTableViewCells/Classes/HybridSubviewBasedApplicationCell.h new file mode 100644 index 0000000..9d90906 --- /dev/null +++ b/AdvancedTableViewCells/Classes/HybridSubviewBasedApplicationCell.h @@ -0,0 +1,57 @@ +/* + File: HybridSubviewBasedApplicationCell.h + Abstract: The subclass of ApplicationCell that uses a single view to draw most of the content and a separate label to render the rest of the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "ApplicationCell.h" + + +@interface HybridSubviewBasedApplicationCell : ApplicationCell +{ + UIView *cellContentView; + UILabel *priceLabel; +} + +@end diff --git a/AdvancedTableViewCells/Classes/HybridSubviewBasedApplicationCell.m b/AdvancedTableViewCells/Classes/HybridSubviewBasedApplicationCell.m new file mode 100644 index 0000000..96b63ee --- /dev/null +++ b/AdvancedTableViewCells/Classes/HybridSubviewBasedApplicationCell.m @@ -0,0 +1,155 @@ +/* + File: HybridSubviewBasedApplicationCell.m + Abstract: The subclass of ApplicationCell that uses a single view to draw most of the content and a separate label to render the rest of the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "HybridSubviewBasedApplicationCell.h" + +#define MAX_RATING 5.0 + +@interface HybridSubviewBasedApplicationCellContentView : UIView +{ + ApplicationCell *_cell; + BOOL _highlighted; +} + +@end + +@implementation HybridSubviewBasedApplicationCellContentView + +- (id)initWithFrame:(CGRect)frame cell:(ApplicationCell *)cell +{ + if (self = [super initWithFrame:frame]) + { + _cell = cell; + + self.opaque = YES; + self.backgroundColor = _cell.backgroundColor; + } + + return self; +} + +- (void)drawRect:(CGRect)rect +{ + [_cell.icon drawAtPoint:CGPointMake(11.0, 5.0)]; + + _highlighted ? [[UIColor whiteColor] set] : [[UIColor blackColor] set]; + [_cell.name drawAtPoint:CGPointMake(81.0, 22.0) withFont:[UIFont boldSystemFontOfSize:17.0]]; + + _highlighted ? [[UIColor whiteColor] set] : [[UIColor colorWithWhite:0.23 alpha:1.0] set]; + [_cell.publisher drawAtPoint:CGPointMake(81.0, 8.0) withFont:[UIFont boldSystemFontOfSize:11.0]]; + + [[NSString stringWithFormat:@"%d Ratings", _cell.numRatings] drawAtPoint:CGPointMake(157.0, 46.0) withFont:[UIFont systemFontOfSize:11.0]]; + + CGPoint ratingImageOrigin = CGPointMake(81.0, 45.0); + UIImage *ratingBackgroundImage = [UIImage imageNamed:@"StarsBackground.png"]; + [ratingBackgroundImage drawAtPoint:ratingImageOrigin]; + UIImage *ratingForegroundImage = [UIImage imageNamed:@"StarsForeground.png"]; + UIRectClip(CGRectMake(ratingImageOrigin.x, ratingImageOrigin.y, ratingForegroundImage.size.width * (_cell.rating / MAX_RATING), ratingForegroundImage.size.height)); + [ratingForegroundImage drawAtPoint:ratingImageOrigin]; +} + +- (void)setHighlighted:(BOOL)highlighted +{ + _highlighted = highlighted; + [self setNeedsDisplay]; +} + +- (BOOL)isHighlighted +{ + return _highlighted; +} + +@end + + +#pragma mark - + +@implementation HybridSubviewBasedApplicationCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) + { + cellContentView = [[HybridSubviewBasedApplicationCellContentView alloc] initWithFrame:CGRectInset(self.contentView.bounds, 0.0, 1.0) cell:self]; + cellContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + cellContentView.contentMode = UIViewContentModeLeft; + [self.contentView addSubview:cellContentView]; + + priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.contentView.bounds.size.width - 64.0, 25.0, 56.0, 21.0)]; + priceLabel.textAlignment = UITextAlignmentRight; + priceLabel.font = [UIFont boldSystemFontOfSize:11.0]; + priceLabel.textColor = [UIColor colorWithWhite:0.23 alpha:1.0]; + priceLabel.highlightedTextColor = [UIColor whiteColor]; + priceLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + [self.contentView addSubview:priceLabel]; + } + + return self; +} + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + cellContentView.backgroundColor = backgroundColor; + priceLabel.backgroundColor = backgroundColor; +} + +- (void)setPrice:(NSString *)newPrice +{ + [super setPrice:newPrice]; + priceLabel.text = newPrice; +} + +- (void)dealloc +{ + [cellContentView release]; + [priceLabel release]; + + [super dealloc]; +} + +@end diff --git a/AdvancedTableViewCells/Classes/IndividualSubviewsBasedApplicationCell.h b/AdvancedTableViewCells/Classes/IndividualSubviewsBasedApplicationCell.h new file mode 100644 index 0000000..ebb8710 --- /dev/null +++ b/AdvancedTableViewCells/Classes/IndividualSubviewsBasedApplicationCell.h @@ -0,0 +1,62 @@ +/* + File: IndividualSubviewsBasedApplicationCell.h + Abstract: The subclass of ApplicationCell that uses individual subviews to display the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ApplicationCell.h" +#import "RatingView.h" + +@interface IndividualSubviewsBasedApplicationCell : ApplicationCell +{ + IBOutlet UIImageView *iconView; + IBOutlet UILabel *publisherLabel; + IBOutlet UILabel *nameLabel; + IBOutlet RatingView *ratingView; + IBOutlet UILabel *numRatingsLabel; + IBOutlet UILabel *priceLabel; +} + +@end diff --git a/AdvancedTableViewCells/Classes/IndividualSubviewsBasedApplicationCell.m b/AdvancedTableViewCells/Classes/IndividualSubviewsBasedApplicationCell.m new file mode 100644 index 0000000..21dff3b --- /dev/null +++ b/AdvancedTableViewCells/Classes/IndividualSubviewsBasedApplicationCell.m @@ -0,0 +1,113 @@ +/* + File: IndividualSubviewsBasedApplicationCell.m + Abstract: The subclass of ApplicationCell that uses individual subviews to display the content. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "IndividualSubviewsBasedApplicationCell.h" + + +@implementation IndividualSubviewsBasedApplicationCell + +- (void)setBackgroundColor:(UIColor *)backgroundColor +{ + [super setBackgroundColor:backgroundColor]; + + iconView.backgroundColor = backgroundColor; + publisherLabel.backgroundColor = backgroundColor; + nameLabel.backgroundColor = backgroundColor; + ratingView.backgroundColor = backgroundColor; + numRatingsLabel.backgroundColor = backgroundColor; + priceLabel.backgroundColor = backgroundColor; +} + +- (void)setIcon:(UIImage *)newIcon +{ + [super setIcon:newIcon]; + iconView.image = newIcon; +} + +- (void)setPublisher:(NSString *)newPublisher +{ + [super setPublisher:newPublisher]; + publisherLabel.text = newPublisher; +} + +- (void)setRating:(float)newRating +{ + [super setRating:newRating]; + ratingView.rating = newRating; +} + +- (void)setNumRatings:(NSInteger)newNumRatings +{ + [super setNumRatings:newNumRatings]; + numRatingsLabel.text = [NSString stringWithFormat:@"%d Ratings", newNumRatings]; +} + +- (void)setName:(NSString *)newName +{ + [super setName:newName]; + nameLabel.text = newName; +} + +- (void)setPrice:(NSString *)newPrice +{ + [super setPrice:newPrice]; + priceLabel.text = newPrice; +} + +- (void)dealloc +{ + [iconView release]; + [publisherLabel release]; + [nameLabel release]; + [ratingView release]; + [numRatingsLabel release]; + [priceLabel release]; + + [super dealloc]; +} + +@end diff --git a/AdvancedTableViewCells/Classes/RatingView.h b/AdvancedTableViewCells/Classes/RatingView.h new file mode 100644 index 0000000..8ad2c20 --- /dev/null +++ b/AdvancedTableViewCells/Classes/RatingView.h @@ -0,0 +1,59 @@ +/* + File: RatingView.h + Abstract: The view used by the IndividualSubviewBasedApplicationCell to display the rating. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface RatingView : UIView +{ + float rating; + UIImageView *backgroundImageView; + UIImageView *foregroundImageView; +} + +@property float rating; + +@end diff --git a/AdvancedTableViewCells/Classes/RatingView.m b/AdvancedTableViewCells/Classes/RatingView.m new file mode 100644 index 0000000..b4a3d61 --- /dev/null +++ b/AdvancedTableViewCells/Classes/RatingView.m @@ -0,0 +1,104 @@ +/* + File: RatingView.m + Abstract: The view used by the IndividualSubviewBasedApplicationCell to display the rating. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "RatingView.h" + +#define MAX_RATING 5.0 + +@implementation RatingView + +- (void)_commonInit +{ + backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"StarsBackground.png"]]; + backgroundImageView.contentMode = UIViewContentModeLeft; + [self addSubview:backgroundImageView]; + + foregroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"StarsForeground.png"]]; + foregroundImageView.contentMode = UIViewContentModeLeft; + foregroundImageView.clipsToBounds = YES; + [self addSubview:foregroundImageView]; +} + +- (id)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) + { + [self _commonInit]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)coder +{ + if (self = [super initWithCoder:coder]) + { + [self _commonInit]; + } + + return self; +} + +- (void)setRating:(float)newRating +{ + rating = newRating; + foregroundImageView.frame = CGRectMake(0.0, 0.0, backgroundImageView.frame.size.width * (rating / MAX_RATING), foregroundImageView.bounds.size.height); +} + +- (float)rating +{ + return rating; +} + +- (void)dealloc +{ + [backgroundImageView release]; + [foregroundImageView release]; + + [super dealloc]; +} + +@end diff --git a/AdvancedTableViewCells/Classes/RootViewController.h b/AdvancedTableViewCells/Classes/RootViewController.h new file mode 100644 index 0000000..5407b09 --- /dev/null +++ b/AdvancedTableViewCells/Classes/RootViewController.h @@ -0,0 +1,65 @@ +/* + File: RootViewController.h + Abstract: The main UITableViewController. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ApplicationCell.h" + +@interface RootViewController : UITableViewController +{ + ApplicationCell *tmpCell; + NSArray *data; + + // referring to our xib-based UITableViewCell ('IndividualSubviewsBasedApplicationCell') + UINib *cellNib; +} + +@property (nonatomic, retain) IBOutlet ApplicationCell *tmpCell; +@property (nonatomic, retain) NSArray *data; + +@property (nonatomic, retain) UINib *cellNib; + +@end diff --git a/AdvancedTableViewCells/Classes/RootViewController.m b/AdvancedTableViewCells/Classes/RootViewController.m new file mode 100644 index 0000000..d9389f6 --- /dev/null +++ b/AdvancedTableViewCells/Classes/RootViewController.m @@ -0,0 +1,193 @@ +/* + File: RootViewController.m + Abstract: The main UITableViewController. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "CompositeSubviewBasedApplicationCell.h" +#import "HybridSubviewBasedApplicationCell.h" + + +// Define one of the following macros to 1 to control which type of cell will be used. +#define USE_INDIVIDUAL_SUBVIEWS_CELL 1 // use a xib file defining the cell +#define USE_COMPOSITE_SUBVIEW_CELL 0 // use a single view to draw all the content +#define USE_HYBRID_CELL 0 // use a single view to draw most of the content + separate label to render the rest of the content + + +/* + Predefined colors to alternate the background color of each cell row by row + (see tableView:cellForRowAtIndexPath: and tableView:willDisplayCell:forRowAtIndexPath:). + */ +#define DARK_BACKGROUND [UIColor colorWithRed:151.0/255.0 green:152.0/255.0 blue:155.0/255.0 alpha:1.0] +#define LIGHT_BACKGROUND [UIColor colorWithRed:172.0/255.0 green:173.0/255.0 blue:175.0/255.0 alpha:1.0] + + +@implementation RootViewController + +@synthesize tmpCell, data, cellNib; + + +#pragma mark - +#pragma mark View controller methods + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.navigationController.navigationBar.tintColor = [UIColor darkGrayColor]; + + // Configure the table view. + self.tableView.rowHeight = 73.0; + self.tableView.backgroundColor = DARK_BACKGROUND; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + + // Load the data. + NSString *dataPath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"]; + self.data = [NSArray arrayWithContentsOfFile:dataPath]; + + // create our UINib instance which will later help us load and instanciate the + // UITableViewCells's UI via a xib file. + // + // Note: + // The UINib classe provides better performance in situations where you want to create multiple + // copies of a nib file’s contents. The normal nib-loading process involves reading the nib file + // from disk and then instantiating the objects it contains. However, with the UINib class, the + // nib file is read from disk once and the contents are stored in memory. + // Because they are in memory, creating successive sets of objects takes less time because it + // does not require accessing the disk. + // + self.cellNib = [UINib nibWithNibName:@"IndividualSubviewsBasedApplicationCell" bundle:nil]; +} + +- (void)viewDidUnload +{ + [super viewDidLoad]; + + self.data = nil; + self.tmpCell = nil; + self.cellNib = nil; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation +{ + return YES; +} + + +#pragma mark - +#pragma mark Table view methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [data count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"ApplicationCell"; + + ApplicationCell *cell = (ApplicationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + + if (cell == nil) + { +#if USE_INDIVIDUAL_SUBVIEWS_CELL + [self.cellNib instantiateWithOwner:self options:nil]; + cell = tmpCell; + self.tmpCell = nil; + +#elif USE_COMPOSITE_SUBVIEW_CELL + cell = [[[CompositeSubviewBasedApplicationCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:CellIdentifier] autorelease]; + +#elif USE_HYBRID_CELL + cell = [[[HybridSubviewBasedApplicationCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:CellIdentifier] autorelease]; +#endif + } + + // Display dark and light background in alternate rows -- see tableView:willDisplayCell:forRowAtIndexPath:. + cell.useDarkBackground = (indexPath.row % 2 == 0); + + // Configure the data for the cell. + NSDictionary *dataItem = [data objectAtIndex:indexPath.row]; + cell.icon = [UIImage imageNamed:[dataItem objectForKey:@"Icon"]]; + cell.publisher = [dataItem objectForKey:@"Publisher"]; + cell.name = [dataItem objectForKey:@"Name"]; + cell.numRatings = [[dataItem objectForKey:@"NumRatings"] intValue]; + cell.rating = [[dataItem objectForKey:@"Rating"] floatValue]; + cell.price = [dataItem objectForKey:@"Price"]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath +{ + cell.backgroundColor = ((ApplicationCell *)cell).useDarkBackground ? DARK_BACKGROUND : LIGHT_BACKGROUND; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc +{ + [data release]; + [tmpCell release]; + [cellNib release]; + + [super dealloc]; +} + +@end \ No newline at end of file diff --git a/AdvancedTableViewCells/Data.plist b/AdvancedTableViewCells/Data.plist new file mode 100644 index 0000000..b379d0a --- /dev/null +++ b/AdvancedTableViewCells/Data.plist @@ -0,0 +1,90 @@ + + + + + + Publisher + Super Sportz, Inc. + Name + Baseball + NumRatings + 106 + Rating + 3.5 + Price + $2.98 + Icon + Baseball.png + + + Publisher + General Specifics, Inc. + Name + Blocks + NumRatings + 114 + Rating + 4.5 + Price + $0.99 + Icon + Blocks.png + + + Publisher + Gameitoids, Inc. + Name + Checkers + NumRatings + 87 + Rating + 4 + Price + Free + Icon + Checkers.png + + + Publisher + Foodies, Inc. + Name + Dinner + NumRatings + 254 + Rating + 3 + Price + $4.98 + Icon + Dinner.png + + + Publisher + Super Sportz, Inc. + Name + Football + NumRatings + 422 + Rating + 3 + Price + $1.99 + Icon + Football.png + + + Publisher + Math Nutz + Name + MathGraph + NumRatings + 45 + Rating + 4 + Price + $0.99 + Icon + MathGraph.png + + + diff --git a/AdvancedTableViewCells/ReadMe.txt b/AdvancedTableViewCells/ReadMe.txt new file mode 100644 index 0000000..2db252c --- /dev/null +++ b/AdvancedTableViewCells/ReadMe.txt @@ -0,0 +1,64 @@ +AdvancedTableViewCells +====================== + +Demonstrates several different ways to handle complex UITableViewCells. + +IndividualSubviewsBasedApplicationCell is a cell designed in Interface Builder to display the contents of a cell using individual subviews (image views, labels, etc.) + +CompositeSubviewBasedApplicationCell is a cell that uses a custom view to draw all of the components of the cell. + +HybridSubviewBasedApplicationCell is a cell that uses a custom view to draw most of the components of the cell while using separate views to handle components that need to animate separately from the rest of the content. + + +Build Requirements +------------------ +iOS 4.2 SDK + + +Runtime Requirements +-------------------- +iOS 3.2 SDK or later + + +Using the Sample +---------------- +Open the RootViewController.m and configure which of the above three cells you wish to use using the macros at the top of the file. + + +Packaging List +-------------- +AdvancedTableViewCellsAppDelegate.{h,m} + - The application's delegate to setup its window and content. + +RootViewController.{h,m} +- The main UITableViewController. + +ApplicationCell.{h,m} +- The abstract superclass of the three cell classes described above. + +IndividualSubviewBasedApplicationCell.{h,m} +- The subclass of ApplicationCell that uses individual subviews to display the content. + +CompositeSubviewBasedApplicationCell.{h,m} +- The subclass of ApplicationCell that uses a single view to draw the content. + +HybridSubviewBasedApplicationCell.{h,m} +- The subclass of ApplicationCell that uses a single view to draw most of the content and a separate label to render the rest of the content. + +RatingView.{h,m} +- The view used by the IndividualSubviewBasedApplicationCell to display the rating. + + +Changes from Previous Versions +1.0 - First release +1.2 - Added reuse identifier to cell loaded from nib, added localized folder for nibs. +1.3 - Upgraded project to build with the iOS 4.0 SDK. +1.4 - Added CFBundleIconFiles in Info.plist. +1.5 - Upgraded to support iOS 4.2 SDK, now using UINib class to help load and instantiate xib-based table view cells. + + +Feedback and Bug Reports +Please send all feedback about this sample by connecting to the Contact ADC page. +Please submit any bug reports about this sample to the Bug Reporting page. + +Copyright (C) 2009-2011, Apple Inc. \ No newline at end of file diff --git a/AdvancedTableViewCells/en.lproj/IndividualSubviewsBasedApplicationCell.xib b/AdvancedTableViewCells/en.lproj/IndividualSubviewsBasedApplicationCell.xib new file mode 100644 index 0000000..3a4451e --- /dev/null +++ b/AdvancedTableViewCells/en.lproj/IndividualSubviewsBasedApplicationCell.xib @@ -0,0 +1,451 @@ + + + + 768 + 10B504 + 753 + 1038.2 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 75 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 292 + + YES + + + 256 + + YES + + + 292 + {{11, 6}, {60, 60}} + + NO + NO + 4 + NO + IBCocoaTouchFramework + + + + 292 + {{81, 8}, {168, 15}} + + NO + YES + NO + IBCocoaTouchFramework + Publisher + + Helvetica-Bold + 11 + 16 + + + 2 + MC4yMjc0NTEgMC4yMjc0NTEgMC4yMjc0NTEAA + + + 3 + MQA + + 1 + 10 + + + + 297 + {{257, 25}, {35, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Price + + + 2 + MC4yMjc0NTEgMC4yMjc0NTEgMC4yMjc0NTEAA + + + 1 + 10 + 2 + + + + 292 + {{157, 46}, {92, 15}} + + NO + YES + NO + IBCocoaTouchFramework + %d Ratings + + Helvetica + 11 + 16 + + + 2 + MC4yMjc0NTEgMC4yMjc0NTEgMC4yMjc0NTEAA + + + 1 + 10 + + + + 292 + {{81, 23}, {168, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Application Name + + Helvetica-Bold + 17 + 16 + + + 1 + MCAwIDAAA + + + 1 + 10 + + + + 292 + {{81, 46}, {70, 16}} + + + 3 + MQA + + 2 + + + NO + IBCocoaTouchFramework + + + {300, 73} + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 73} + + 1 + MSAxIDEAA + + NO + IBCocoaTouchFramework + 1 + + ApplicationCell + + + + + YES + + + iconView + + + + 17 + + + + publisherLabel + + + + 18 + + + + nameLabel + + + + 19 + + + + ratingView + + + + 20 + + + + numRatingsLabel + + + + 21 + + + + priceLabel + + + + 22 + + + + tmpCell + + + + 23 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + 6.IBPluginDependency + 7.CustomClassName + 7.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + RootViewController + UIResponder + IndividualSubviewsBasedApplicationCell + {{145, 394}, {320, 73}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RatingView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 23 + + + + YES + + ApplicationCell + UITableViewCell + + IBProjectSource + Classes/ApplicationCell.h + + + + IndividualSubviewsBasedApplicationCell + ApplicationCell + + YES + + YES + iconView + nameLabel + numRatingsLabel + priceLabel + publisherLabel + ratingView + + + YES + UIImageView + UILabel + UILabel + UILabel + UILabel + RatingView + + + + IBProjectSource + Classes/IndividualSubviewsBasedApplicationCell.h + + + + RatingView + UIView + + IBProjectSource + Classes/RatingView.h + + + + RootViewController + UITableViewController + + tmpCell + ApplicationCell + + + IBProjectSource + Classes/RootViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + AdvancedTableViewCells.xcodeproj + 3 + 75 + + diff --git a/AdvancedTableViewCells/en.lproj/MainWindow.xib b/AdvancedTableViewCells/en.lproj/MainWindow.xib new file mode 100644 index 0000000..c84ed68 --- /dev/null +++ b/AdvancedTableViewCells/en.lproj/MainWindow.xib @@ -0,0 +1,536 @@ + + + + 768 + 10A432 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + Advanced Table View Cells + + + RootViewController + + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + AdvancedTable View Cells App Delegate + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AdvancedTableViewCellsAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{312, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 15 + + + + YES + + AdvancedTableViewCellsAppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + Classes/AdvancedTableViewCellsAppDelegate.h + + + + ApplicationCell + UITableViewCell + + IBProjectSource + Classes/ApplicationCell.h + + + + RootViewController + UITableViewController + + tmpCell + ApplicationCell + + + IBProjectSource + Classes/RootViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableViewCell + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITableViewCell.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + AdvancedTableViewCells.xcodeproj + 3 + 3.0 + + diff --git a/AdvancedTableViewCells/en.lproj/RootViewController.xib b/AdvancedTableViewCells/en.lproj/RootViewController.xib new file mode 100644 index 0000000..741cd2e --- /dev/null +++ b/AdvancedTableViewCells/en.lproj/RootViewController.xib @@ -0,0 +1,192 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + {320, 416} + + + 3 + MQA + + NO + YES + NO + + + NO + + NO + 1 + 0 + YES + 4.400000e+01 + 2.200000e+01 + 2.200000e+01 + + + + + YES + + + tableView + + + + 10 + + + + view + + + + 11 + + + + dataSource + + + + 12 + + + + delegate + + + + 13 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 9 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + RootViewController + UIResponder + {{236, 337}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 13 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + RootViewController + UITableViewController + + tableView + UITableView + + + IBUserSource + + + + + + 0 + App Store Demo.xcodeproj + 3 + + diff --git a/AdvancedTableViewCells/images/Baseball.png b/AdvancedTableViewCells/images/Baseball.png new file mode 100644 index 0000000..83b2f48 Binary files /dev/null and b/AdvancedTableViewCells/images/Baseball.png differ diff --git a/AdvancedTableViewCells/images/Blocks.png b/AdvancedTableViewCells/images/Blocks.png new file mode 100644 index 0000000..eea3060 Binary files /dev/null and b/AdvancedTableViewCells/images/Blocks.png differ diff --git a/AdvancedTableViewCells/images/Checkers.png b/AdvancedTableViewCells/images/Checkers.png new file mode 100644 index 0000000..1cc39e4 Binary files /dev/null and b/AdvancedTableViewCells/images/Checkers.png differ diff --git a/AdvancedTableViewCells/images/DarkBackground.png b/AdvancedTableViewCells/images/DarkBackground.png new file mode 100644 index 0000000..fb83cee Binary files /dev/null and b/AdvancedTableViewCells/images/DarkBackground.png differ diff --git a/AdvancedTableViewCells/images/Dinner.png b/AdvancedTableViewCells/images/Dinner.png new file mode 100644 index 0000000..7f6464e Binary files /dev/null and b/AdvancedTableViewCells/images/Dinner.png differ diff --git a/AdvancedTableViewCells/images/Football.png b/AdvancedTableViewCells/images/Football.png new file mode 100644 index 0000000..8875be1 Binary files /dev/null and b/AdvancedTableViewCells/images/Football.png differ diff --git a/AdvancedTableViewCells/images/Icon-72.png b/AdvancedTableViewCells/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/AdvancedTableViewCells/images/Icon-72.png differ diff --git a/AdvancedTableViewCells/images/Icon-Small-50.png b/AdvancedTableViewCells/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/AdvancedTableViewCells/images/Icon-Small-50.png differ diff --git a/AdvancedTableViewCells/images/Icon-Small.png b/AdvancedTableViewCells/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/AdvancedTableViewCells/images/Icon-Small.png differ diff --git a/AdvancedTableViewCells/images/Icon-Small@2x.png b/AdvancedTableViewCells/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/AdvancedTableViewCells/images/Icon-Small@2x.png differ diff --git a/AdvancedTableViewCells/images/Icon.png b/AdvancedTableViewCells/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/AdvancedTableViewCells/images/Icon.png differ diff --git a/AdvancedTableViewCells/images/Icon@2x.png b/AdvancedTableViewCells/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/AdvancedTableViewCells/images/Icon@2x.png differ diff --git a/AdvancedTableViewCells/images/LightBackground.png b/AdvancedTableViewCells/images/LightBackground.png new file mode 100644 index 0000000..956cc26 Binary files /dev/null and b/AdvancedTableViewCells/images/LightBackground.png differ diff --git a/AdvancedTableViewCells/images/MathGraph.png b/AdvancedTableViewCells/images/MathGraph.png new file mode 100644 index 0000000..a2a27ca Binary files /dev/null and b/AdvancedTableViewCells/images/MathGraph.png differ diff --git a/AdvancedTableViewCells/images/StarsBackground.png b/AdvancedTableViewCells/images/StarsBackground.png new file mode 100644 index 0000000..911beb5 Binary files /dev/null and b/AdvancedTableViewCells/images/StarsBackground.png differ diff --git a/AdvancedTableViewCells/images/StarsForeground.png b/AdvancedTableViewCells/images/StarsForeground.png new file mode 100644 index 0000000..04a898c Binary files /dev/null and b/AdvancedTableViewCells/images/StarsForeground.png differ diff --git a/AdvancedTableViewCells/images/iTunesArtwork b/AdvancedTableViewCells/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/AdvancedTableViewCells/images/iTunesArtwork differ diff --git a/AdvancedTableViewCells/main.m b/AdvancedTableViewCells/main.m new file mode 100644 index 0000000..25ab748 --- /dev/null +++ b/AdvancedTableViewCells/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2011 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/AppPrefs.zip b/AppPrefs.zip new file mode 100644 index 0000000..f6d824b Binary files /dev/null and b/AppPrefs.zip differ diff --git a/AppPrefs/AppDelegate.h b/AppPrefs/AppDelegate.h new file mode 100755 index 0000000..d075969 --- /dev/null +++ b/AppPrefs/AppDelegate.h @@ -0,0 +1,82 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +enum textColors +{ + blue = 1, + red, + green +}; + +enum backgroundColors +{ + blackBackColor = 1, + whiteBackColor, + blueBackColor, + patternBackColor +}; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navigationController; + + NSString *firstName; + NSString *lastName; + NSInteger backgroundColor; + NSInteger textColor; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +@property (nonatomic, retain) NSString *firstName; +@property (nonatomic, retain) NSString *lastName; +@property (nonatomic, assign) NSInteger backgroundColor; +@property (nonatomic, assign) NSInteger textColor; + +@end diff --git a/AppPrefs/AppDelegate.m b/AppPrefs/AppDelegate.m new file mode 100755 index 0000000..0d2b9fe --- /dev/null +++ b/AppPrefs/AppDelegate.m @@ -0,0 +1,161 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" + +NSString *kFirstNameKey = @"firstNameKey"; +NSString *kLastNameKey = @"lastNameKey"; +NSString *kNameColorKey = @"nameColorKey"; +NSString *kBackgroundColorKey = @"backgroundColorKey"; + + +@implementation AppDelegate + +@synthesize window, navigationController, firstName, lastName, backgroundColor, textColor; + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSUserDefaultsDidChangeNotification + object:nil]; + + [navigationController release]; + [firstName release]; + [lastName release]; + [window release]; + + [super dealloc]; +} + +- (void)setupByPreferences +{ + NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kFirstNameKey]; + if (testValue == nil) + { + // no default values have been set, create them here based on what's in our Settings bundle info + // + NSString *pathStr = [[NSBundle mainBundle] bundlePath]; + NSString *settingsBundlePath = [pathStr stringByAppendingPathComponent:@"Settings.bundle"]; + NSString *finalPath = [settingsBundlePath stringByAppendingPathComponent:@"Root.plist"]; + + NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:finalPath]; + NSArray *prefSpecifierArray = [settingsDict objectForKey:@"PreferenceSpecifiers"]; + + NSString *firstNameDefault = nil; + NSString *lastNameDefault = nil; + NSNumber *nameColorDefault = nil; + NSNumber *backgroundColorDefault = nil; + + NSDictionary *prefItem; + for (prefItem in prefSpecifierArray) + { + NSString *keyValueStr = [prefItem objectForKey:@"Key"]; + id defaultValue = [prefItem objectForKey:@"DefaultValue"]; + + if ([keyValueStr isEqualToString:kFirstNameKey]) + { + firstNameDefault = defaultValue; + } + else if ([keyValueStr isEqualToString:kLastNameKey]) + { + lastNameDefault = defaultValue; + } + else if ([keyValueStr isEqualToString:kNameColorKey]) + { + nameColorDefault = defaultValue; + } + else if ([keyValueStr isEqualToString:kBackgroundColorKey]) + { + backgroundColorDefault = defaultValue; + } + } + + // since no default values have been set (i.e. no preferences file created), create it here + NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: + firstNameDefault, kFirstNameKey, + lastNameDefault, kLastNameKey, + nameColorDefault, kNameColorKey, + backgroundColorDefault, kBackgroundColorKey, + nil]; + + [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; + [[NSUserDefaults standardUserDefaults] synchronize]; + } + + // we're ready to go, so lastly set the key preference values + firstName = [[NSUserDefaults standardUserDefaults] stringForKey:kFirstNameKey]; + lastName = [[NSUserDefaults standardUserDefaults] stringForKey:kLastNameKey]; + textColor = [[NSUserDefaults standardUserDefaults] integerForKey:kNameColorKey]; + backgroundColor = [[NSUserDefaults standardUserDefaults] integerForKey:kBackgroundColorKey]; +} + +// we are being notified that our preferences have changed (user changed them in the Settings app) +// so read in the changes and update our UI. +// +- (void)defaultsChanged:(NSNotification *)notif +{ + [self setupByPreferences]; + UITableView *tableView = ((UITableViewController *)self.navigationController.visibleViewController).tableView; + [tableView reloadData]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + [window addSubview:[navigationController view]]; + + // listen for changes to our preferences when the Settings app does so, + // when we are resumed from the backround, this will give us a chance to update our UI + // + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(defaultsChanged:) + name:NSUserDefaultsDidChangeNotification + object:nil]; + + [self setupByPreferences]; +} + +@end diff --git a/AppPrefs/AppPrefs.xcodeproj/project.pbxproj b/AppPrefs/AppPrefs.xcodeproj/project.pbxproj new file mode 100755 index 0000000..cef720c --- /dev/null +++ b/AppPrefs/AppPrefs.xcodeproj/project.pbxproj @@ -0,0 +1,306 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 53228BA10DCBBF8300B1FFFD /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53228B9F0DCBBF8300B1FFFD /* MainWindow.xib */; }; + 5389AD590F8D6C50009A9F1D /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5389AD580F8D6C50009A9F1D /* Settings.bundle */; }; + 539494A811D5665D0048D0D7 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 539494A511D5665D0048D0D7 /* Icon-72.png */; }; + 539494A911D5665D0048D0D7 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 539494A611D5665D0048D0D7 /* Icon-Small-50.png */; }; + 539494AA11D5665D0048D0D7 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 539494A711D5665D0048D0D7 /* iTunesArtwork */; }; + 53AE91170DBE72EB00E479DE /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53AE91150DBE72EB00E479DE /* MyViewController.m */; }; + 53CFC03F0D62589300422A0E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53CFC03D0D62589300422A0E /* AppDelegate.m */; }; + 53E3ED1311C92D81000743A0 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E3ED0E11C92D81000743A0 /* Icon-Small.png */; }; + 53E3ED1411C92D81000743A0 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E3ED0F11C92D81000743A0 /* Icon-Small@2x.png */; }; + 53E3ED1511C92D81000743A0 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E3ED1011C92D81000743A0 /* Icon.png */; }; + 53E3ED1611C92D81000743A0 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E3ED1111C92D81000743A0 /* Icon@2x.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* AppPrefs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppPrefs.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53228BA00DCBBF8300B1FFFD /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 5389AD580F8D6C50009A9F1D /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; + 539494A511D5665D0048D0D7 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 539494A611D5665D0048D0D7 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 539494A711D5665D0048D0D7 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 53A246AB0DCBC56A00CDC6C8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 53AE91150DBE72EB00E479DE /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 53AE91160DBE72EB00E479DE /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 53CFC0300D62587800422A0E /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53CFC03D0D62589300422A0E /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 53CFC03E0D62589300422A0E /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53E3ED0E11C92D81000743A0 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 53E3ED0F11C92D81000743A0 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 53E3ED1011C92D81000743A0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 53E3ED1111C92D81000743A0 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* AppPrefs.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Toolbar */ = { + isa = PBXGroup; + children = ( + 53A246AB0DCBC56A00CDC6C8 /* ReadMe.txt */, + 29B97315FDCFA39411CA2CEA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 5389AD580F8D6C50009A9F1D /* Settings.bundle */, + ); + name = Toolbar; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Sources */ = { + isa = PBXGroup; + children = ( + 53CFC0300D62587800422A0E /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 53CFC03E0D62589300422A0E /* AppDelegate.h */, + 53CFC03D0D62589300422A0E /* AppDelegate.m */, + 53AE91160DBE72EB00E479DE /* MyViewController.h */, + 53AE91150DBE72EB00E479DE /* MyViewController.m */, + ); + name = Sources; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 53E3ED0D11C92D81000743A0 /* images */, + 53228B9F0DCBBF8300B1FFFD /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53E3ED0D11C92D81000743A0 /* images */ = { + isa = PBXGroup; + children = ( + 539494A511D5665D0048D0D7 /* Icon-72.png */, + 539494A611D5665D0048D0D7 /* Icon-Small-50.png */, + 53E3ED0E11C92D81000743A0 /* Icon-Small.png */, + 53E3ED0F11C92D81000743A0 /* Icon-Small@2x.png */, + 53E3ED1011C92D81000743A0 /* Icon.png */, + 53E3ED1111C92D81000743A0 /* Icon@2x.png */, + 539494A711D5665D0048D0D7 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* AppPrefs */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AppPrefs" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppPrefs; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* AppPrefs.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AppPrefs" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* Toolbar */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* AppPrefs */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53228BA10DCBBF8300B1FFFD /* MainWindow.xib in Resources */, + 5389AD590F8D6C50009A9F1D /* Settings.bundle in Resources */, + 53E3ED1311C92D81000743A0 /* Icon-Small.png in Resources */, + 53E3ED1411C92D81000743A0 /* Icon-Small@2x.png in Resources */, + 53E3ED1511C92D81000743A0 /* Icon.png in Resources */, + 53E3ED1611C92D81000743A0 /* Icon@2x.png in Resources */, + 539494A811D5665D0048D0D7 /* Icon-72.png in Resources */, + 539494A911D5665D0048D0D7 /* Icon-Small-50.png in Resources */, + 539494AA11D5665D0048D0D7 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 53CFC03F0D62589300422A0E /* AppDelegate.m in Sources */, + 53AE91170DBE72EB00E479DE /* MyViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53228B9F0DCBBF8300B1FFFD /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53228BA00DCBBF8300B1FFFD /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = AppPrefs; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = AppPrefs; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AppPrefs" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "AppPrefs" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/AppPrefs/Info.plist b/AppPrefs/Info.plist new file mode 100755 index 0000000..158de1e --- /dev/null +++ b/AppPrefs/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.5 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/AppPrefs/MyViewController.h b/AppPrefs/MyViewController.h new file mode 100644 index 0000000..5bb381c --- /dev/null +++ b/AppPrefs/MyViewController.h @@ -0,0 +1,61 @@ +/* + File: MyViewController.h + Abstract: The main table view controller of this app. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface MyViewController : UITableViewController +{ + UIView *instructionsView; + UIBarButtonItem *doneButton; + UIBarButtonItem *flipButton; +} + +@property (nonatomic, retain) IBOutlet UIView *instructionsView; +@property (nonatomic, retain) IBOutlet UIBarButtonItem *doneButton; +@property (nonatomic, retain) UIBarButtonItem *flipButton; + +- (void)flipAction:(id)sender; + +@end \ No newline at end of file diff --git a/AppPrefs/MyViewController.m b/AppPrefs/MyViewController.m new file mode 100644 index 0000000..58be8b2 --- /dev/null +++ b/AppPrefs/MyViewController.m @@ -0,0 +1,190 @@ +/* + File: MyViewController.m + Abstract: The main table view controller of this app. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyViewController.h" +#import "AppDelegate.h" + +@implementation MyViewController + +@synthesize instructionsView, flipButton, doneButton; + +- (void)dealloc +{ + [instructionsView release]; + [flipButton release]; + [doneButton release]; + + // unregister for this notification + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidFinishLaunchingNotification object:nil]; + + [super dealloc]; +} + +- (void)viewDidLoad +{ + // watch when the app has finished launching so we can update our preference settings and apply them to the UI + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSettings:) + name:UIApplicationDidFinishLaunchingNotification object:nil]; + + // add our custom flip button as the nav bar's custom right view + UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; + [infoButton addTarget:self action:@selector(flipAction:) forControlEvents:UIControlEventTouchUpInside]; + flipButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + self.navigationItem.rightBarButtonItem = flipButton; + + // note: the app hasn't finished launching, so we setup the background color later in "updateSettings" +} + +- (void)viewDidUnload +{ + self.instructionsView = nil; + self.doneButton = nil; + self.flipButton = nil; +} + +// this is called when the app finishes launching (i.e. UIApplicationDidFinishLaunchingNotification) +// +- (void)updateSettings:(NSNotification *)notif +{ + // now change the app view's background color + AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + switch ([appDelegate backgroundColor]) + { + case blackBackColor: + self.tableView.backgroundColor = [UIColor blackColor]; + break; + + case whiteBackColor: + self.tableView.backgroundColor = [UIColor whiteColor]; + break; + + case blueBackColor: + self.tableView.backgroundColor = [UIColor blueColor]; + break; + + case patternBackColor: + self.tableView.backgroundColor = [UIColor groupTableViewBackgroundColor]; + break; + } +} + + +#pragma mark - Flip screen + +- (void)flipAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.75]; + + [UIView setAnimationTransition:([self.tableView superview] ? + UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) + forView:self.tableView cache:YES]; + + if ([instructionsView superview]) + [instructionsView removeFromSuperview]; + else + [self.tableView addSubview:instructionsView]; + + [UIView commitAnimations]; + + // adjust our done/info buttons accordingly + if ([instructionsView superview] == self.tableView) + self.navigationItem.rightBarButtonItem = doneButton; + else + self.navigationItem.rightBarButtonItem = flipButton; +} + + +#pragma mark - UITableViewDataSource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return 1; +} + +// to determine which UITableViewCell to be used on a given row. +// +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString *kCellIdentifier = @"MyIdentifier"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + + AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + + // ask our app delegate for the preferred string values and text color + NSString *firstNameStr = appDelegate.firstName; + NSString *lastNameStr = appDelegate.lastName; + cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", firstNameStr, lastNameStr]; + + switch ([appDelegate textColor]) + { + case blue: + cell.textLabel.textColor = [UIColor blueColor]; + break; + + case green: + cell.textLabel.textColor = [UIColor greenColor]; + break; + + case red: + cell.textLabel.textColor = [UIColor redColor]; + break; + } + + return cell; +} + +@end + diff --git a/AppPrefs/Prefix.pch b/AppPrefs/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/AppPrefs/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/AppPrefs/ReadMe.txt b/AppPrefs/ReadMe.txt new file mode 100644 index 0000000..8d6710b --- /dev/null +++ b/AppPrefs/ReadMe.txt @@ -0,0 +1,60 @@ +AppPrefs + +Demonstrates how to display your app's preferences or settings in the "Settings" system application. +A settings bundle, included in your application’s bundle directory, contains the information needed by +the Settings application to display your preferences and make it possible for the user to modify them. +It then saves any configured values in the defaults database so that your application can retrieve them at runtime. + +This sample offers an Xcode project already pre-configured to build your Settings bundle as a target. +To customize your settings UI, change the Root.plist file. + +This sample also shows how to dynamically update it's UI when its settings are changed while the app is in the background via "NSUserDefaultsDidChangeNotification". + + +Build Requirements +iOS 4.0 SDK + + +Runtime Requirements +iPhone OS 3.2 or later. + + +Using the Sample +Launch the AppPrefs project using Xcode. +Make sure the project's current target is set to "AppPrefs". +Build and run the "AppPrefs" target. + +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to +the appropriate Device setting. When launched notice the text, its color and the view's background color. +Quit the application and launch "Settings". At the end of the settings list you will find a section +for "AppPrefs". From there you can set the first and last name, its color and the app's background color. +Quit Settings and return to AppPrefs and notice the settings have changed. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application' delegate to setup its window and content. +MyViewController.h/.m - The main UIViewController containing the app's user interface. +Root.plist - The scheme file for your settings bundle. + + +Further Information +For more information on extending the Settings application, refer to the "iPhone Application Programming Guide". + + +Changes from Previous Versions +1.0 - First release + +1.1 - Updated for and tested with iPhone OS 2.0. First public release. + +1.2 - Updated Read Me + +1.3 - More use of nibs, upgraded for 3.0 SDK due to deprecated APIs; +in "cellForRowAtIndexPath" it now uses UITableViewCell's initWithStyle; +Settings.bundle no longer builds as a separate Xcode target. + +1.4 - Upgraded project to build with the iOS 4 SDK, fixed static analyzer warning. added support for "NSUserDefaultsDidChangeNotification". + +1.5 - Deployment target set to iPhone OS 3.2. + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/AppPrefs/Settings.bundle/Root.plist b/AppPrefs/Settings.bundle/Root.plist new file mode 100644 index 0000000..44d106b --- /dev/null +++ b/AppPrefs/Settings.bundle/Root.plist @@ -0,0 +1,93 @@ + + + + + StringsTable + Root + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Name + + + + DefaultValue + Joe + Key + firstNameKey + Title + First + Type + PSTextFieldSpecifier + + + DefaultValue + Smith + Key + lastNameKey + Title + Last + Type + PSTextFieldSpecifier + + + + Type + PSGroupSpecifier + Title + Colors + + + + DefaultValue + 1 + Key + nameColorKey + Title + TextColor + Titles + + Blue + Red + Green + + Type + PSMultiValueSpecifier + Values + + 1 + 2 + 3 + + + + + DefaultValue + 1 + Key + backgroundColorKey + Title + BackgroundColor + Titles + + Black + White + Blue + Pattern + + Type + PSMultiValueSpecifier + Values + + 1 + 2 + 3 + 4 + + + + + diff --git a/AppPrefs/Settings.bundle/en.lproj/Root.strings b/AppPrefs/Settings.bundle/en.lproj/Root.strings new file mode 100644 index 0000000..e248a3e Binary files /dev/null and b/AppPrefs/Settings.bundle/en.lproj/Root.strings differ diff --git a/AppPrefs/en.lproj/MainWindow.xib b/AppPrefs/en.lproj/MainWindow.xib new file mode 100644 index 0000000..4fd4da0 --- /dev/null +++ b/AppPrefs/en.lproj/MainWindow.xib @@ -0,0 +1,472 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 436} + + NO + YES + NO + NO + 1 + 1 + 1 + YES + 4.400000e+01 + 1.000000e+01 + 1.000000e+01 + + + + AppPrefs + + + + + + + + + 268 + + YES + + + 268 + {{20, 20}, {280, 86}} + + NO + YES + NO + VGhpcyBzYW1wbGUgZGVtb25zdHJhdGVzIGhvdyB0byBkaXNwbGF5IHlvdXIgYXBwJ3MgcHJlZmVyZW5j +ZXMgb3Igc2V0dGluZ3MgaW4gdGhlICJTZXR0aW5ncyIgc3lzdGVtIGFwcGxpY2F0aW9uLg + + 1 + MCAwIDAAA + + + 1 + NO + 1.400000e+01 + 16 + 0 + + + + 268 + {{20, 114}, {280, 220}} + + NO + YES + NO + QSBzZXR0aW5ncyBidW5kbGUsIGluY2x1ZGVkIGluIHRoaXMgYXBwbGljYXRpb27igJlzIGJ1bmRsZSwg +Y29udGFpbnMgdGhlIGluZm9ybWF0aW9uIG5lZWRlZCBieSB0aGUgU2V0dGluZ3MgYXBwbGljYXRpb24g +dG8gZGlzcGxheSB5b3VyIHByZWZlcmVuY2VzIGFuZCBtYWtlIGl0IHBvc3NpYmxlIGZvciB0aGUgdXNl +ciB0byBtb2RpZnkgdGhlbS4gSXQgdGhlbiBzYXZlcyBhbnkgY29uZmlndXJlZCB2YWx1ZXMgaW4gdGhl +IGRlZmF1bHRzIGRhdGFiYXNlIHNvIHRoYXQgeW91ciBhcHBsaWNhdGlvbiBjYW4gcmV0cmlldmUgdGhl +bSBhdCBydW50aW1lLiAKA + + + 1 + 1.000000e+01 + 10 + 0 + + + + 268 + {{20, 342}, {280, 51}} + + NO + YES + NO + T3BlbiAiU2V0dGluZ3MiIHRvIGNoYW5nZSB0aGVzZSBwcmVmZXJlbmNlIHZhbHVlcy4 + + + 1 + 1.000000e+01 + 4 + 0 + + + {320, 460} + + 3 + MQA + + 2 + + + NO + + + 2 + 0 + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 10 + + + + navigationController + + + + 31 + + + + dataSource + + + + 72 + + + + delegate + + + + 73 + + + + doneButton + + + + 75 + + + + flipAction: + + + + 76 + + + + instructionsView + + + + 77 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + 22 + + + YES + + + + + + + -2 + + + + + 39 + + + + + 40 + + + YES + + + + + + InstructionsView + + + 46 + + + + + 49 + + + + + 47 + + + + + 63 + + + YES + + + + + + + 64 + + + + + 67 + + + + + 74 + + + DoneButton + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 22.IBEditorWindowLastContentRect + 22.IBPluginDependency + 22.IBViewEditorWindowController.showingLayoutRectangles + 3.CustomClassName + 3.IBPluginDependency + 40.IBEditorWindowLastContentRect + 40.IBPluginDependency + 40.IBViewEditorWindowController.showingLayoutRectangles + 46.IBPluginDependency + 47.IBPluginDependency + 49.IBPluginDependency + 63.CustomClassName + 63.IBPluginDependency + 64.IBPluginDependency + 74.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + {{462, 456}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{300, 129}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 77 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + MyViewController + UITableViewController + + flipAction: + id + + + YES + + YES + doneButton + instructionsView + + + YES + UIBarButtonItem + UIView + + + + IBProjectSource + MyViewController.h + + + + + 0 + ../AppPrefs.xcodeproj + 3 + + diff --git a/AppPrefs/images/Icon-72.png b/AppPrefs/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/AppPrefs/images/Icon-72.png differ diff --git a/AppPrefs/images/Icon-Small-50.png b/AppPrefs/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/AppPrefs/images/Icon-Small-50.png differ diff --git a/AppPrefs/images/Icon-Small.png b/AppPrefs/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/AppPrefs/images/Icon-Small.png differ diff --git a/AppPrefs/images/Icon-Small@2x.png b/AppPrefs/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/AppPrefs/images/Icon-Small@2x.png differ diff --git a/AppPrefs/images/Icon.png b/AppPrefs/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/AppPrefs/images/Icon.png differ diff --git a/AppPrefs/images/Icon@2x.png b/AppPrefs/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/AppPrefs/images/Icon@2x.png differ diff --git a/AppPrefs/images/iTunesArtwork b/AppPrefs/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/AppPrefs/images/iTunesArtwork differ diff --git a/AppPrefs/main.m b/AppPrefs/main.m new file mode 100755 index 0000000..91235ce --- /dev/null +++ b/AppPrefs/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/BatteryStatus.zip b/BatteryStatus.zip new file mode 100644 index 0000000..9ddd2e9 Binary files /dev/null and b/BatteryStatus.zip differ diff --git a/BatteryStatus/BatteryStatus-Info.plist b/BatteryStatus/BatteryStatus-Info.plist new file mode 100644 index 0000000..d327fa1 --- /dev/null +++ b/BatteryStatus/BatteryStatus-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/BatteryStatus/BatteryStatus.xcodeproj/project.pbxproj b/BatteryStatus/BatteryStatus.xcodeproj/project.pbxproj new file mode 100755 index 0000000..aefb07f --- /dev/null +++ b/BatteryStatus/BatteryStatus.xcodeproj/project.pbxproj @@ -0,0 +1,340 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* BatteryStatusAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* BatteryStatusAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + BF063B2A11CC0764009EDACA /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF063B2911CC0764009EDACA /* RootViewController.xib */; }; + BF063B2C11CC0775009EDACA /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF063B2B11CC0775009EDACA /* MainWindow.xib */; }; + BF063B2E11CC0788009EDACA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = BF063B2D11CC0788009EDACA /* Localizable.strings */; }; + BF063B5411CC0E11009EDACA /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = BF063B5311CC0E11009EDACA /* Default.png */; }; + BFCF57B411E64EB40029502F /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57AD11E64EB40029502F /* Icon-72.png */; }; + BFCF57B511E64EB40029502F /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57AE11E64EB40029502F /* Icon-Small-50.png */; }; + BFCF57B611E64EB40029502F /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57AF11E64EB40029502F /* Icon-Small.png */; }; + BFCF57B711E64EB40029502F /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57B011E64EB40029502F /* Icon-Small@2x.png */; }; + BFCF57B811E64EB40029502F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57B111E64EB40029502F /* Icon.png */; }; + BFCF57B911E64EB40029502F /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57B211E64EB40029502F /* Icon@2x.png */; }; + BFCF57BA11E64EB40029502F /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = BFCF57B311E64EB40029502F /* iTunesArtwork */; }; + BFF610020FA65306002D9B9F /* StatusClear.png in Resources */ = {isa = PBXBuildFile; fileRef = BFF610010FA65306002D9B9F /* StatusClear.png */; }; + BFF610040FA6530B002D9B9F /* StatusGreen.png in Resources */ = {isa = PBXBuildFile; fileRef = BFF610030FA6530B002D9B9F /* StatusGreen.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* BatteryStatusAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BatteryStatusAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* BatteryStatusAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BatteryStatusAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* BatteryStatus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BatteryStatus.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2899E55F0DE3E45000AC0155 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/RootViewController.xib; sourceTree = ""; }; + 28A0AAE50D9B0CCF005BE974 /* BatteryStatus_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BatteryStatus_Prefix.pch; sourceTree = ""; }; + 28AD735F0D9D9599002E5188 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainWindow.xib; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* BatteryStatus-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "BatteryStatus-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + BF063B5311CC0E11009EDACA /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + BF2EDBA60FAB665000164327 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + BF9318A00F828F7300FC4594 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; + BFCF57AD11E64EB40029502F /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + BFCF57AE11E64EB40029502F /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + BFCF57AF11E64EB40029502F /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + BFCF57B011E64EB40029502F /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + BFCF57B111E64EB40029502F /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + BFCF57B211E64EB40029502F /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + BFCF57B311E64EB40029502F /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + BFF610010FA65306002D9B9F /* StatusClear.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = StatusClear.png; sourceTree = ""; }; + BFF610030FA6530B002D9B9F /* StatusGreen.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = StatusGreen.png; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + 1D3623240D0F684500981E51 /* BatteryStatusAppDelegate.h */, + 1D3623250D0F684500981E51 /* BatteryStatusAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* BatteryStatus.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + BF2EDBA60FAB665000164327 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* BatteryStatus_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + BF063B2911CC0764009EDACA /* RootViewController.xib */, + BF063B2B11CC0775009EDACA /* MainWindow.xib */, + BF063B2D11CC0788009EDACA /* Localizable.strings */, + 8D1107310486CEB800E47090 /* BatteryStatus-Info.plist */, + BFF610010FA65306002D9B9F /* StatusClear.png */, + BFF610030FA6530B002D9B9F /* StatusGreen.png */, + BF063B5311CC0E11009EDACA /* Default.png */, + BFCF57AC11E64EB40029502F /* images */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + BFCF57AC11E64EB40029502F /* images */ = { + isa = PBXGroup; + children = ( + BFCF57AD11E64EB40029502F /* Icon-72.png */, + BFCF57AE11E64EB40029502F /* Icon-Small-50.png */, + BFCF57AF11E64EB40029502F /* Icon-Small.png */, + BFCF57B011E64EB40029502F /* Icon-Small@2x.png */, + BFCF57B111E64EB40029502F /* Icon.png */, + BFCF57B211E64EB40029502F /* Icon@2x.png */, + BFCF57B311E64EB40029502F /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* BatteryStatus */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "BatteryStatus" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BatteryStatus; + productName = BatteryStatus; + productReference = 1D6058910D05DD3D006BFB54 /* BatteryStatus.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "BatteryStatus" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* BatteryStatus */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF063B2C11CC0775009EDACA /* MainWindow.xib in Resources */, + BF063B2A11CC0764009EDACA /* RootViewController.xib in Resources */, + BF063B2E11CC0788009EDACA /* Localizable.strings in Resources */, + BFF610020FA65306002D9B9F /* StatusClear.png in Resources */, + BFF610040FA6530B002D9B9F /* StatusGreen.png in Resources */, + BF063B5411CC0E11009EDACA /* Default.png in Resources */, + BFCF57B411E64EB40029502F /* Icon-72.png in Resources */, + BFCF57B511E64EB40029502F /* Icon-Small-50.png in Resources */, + BFCF57B611E64EB40029502F /* Icon-Small.png in Resources */, + BFCF57B711E64EB40029502F /* Icon-Small@2x.png in Resources */, + BFCF57B811E64EB40029502F /* Icon.png in Resources */, + BFCF57B911E64EB40029502F /* Icon@2x.png in Resources */, + BFCF57BA11E64EB40029502F /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* BatteryStatusAppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + BF063B2911CC0764009EDACA /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 2899E55F0DE3E45000AC0155 /* English */, + ); + name = RootViewController.xib; + sourceTree = ""; + }; + BF063B2B11CC0775009EDACA /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 28AD735F0D9D9599002E5188 /* English */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + BF063B2D11CC0788009EDACA /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + BF9318A00F828F7300FC4594 /* English */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = BatteryStatus_Prefix.pch; + INFOPLIST_FILE = "BatteryStatus-Info.plist"; + PRODUCT_NAME = BatteryStatus; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = BatteryStatus_Prefix.pch; + INFOPLIST_FILE = "BatteryStatus-Info.plist"; + PRODUCT_NAME = BatteryStatus; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "BatteryStatus" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "BatteryStatus" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/BatteryStatus/BatteryStatus_Prefix.pch b/BatteryStatus/BatteryStatus_Prefix.pch new file mode 100644 index 0000000..3c9b5df --- /dev/null +++ b/BatteryStatus/BatteryStatus_Prefix.pch @@ -0,0 +1,51 @@ +/* + File: BatteryStatus_Prefix.pch + Abstract: Prefix file for the BatteryStatus sample. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/BatteryStatus/Classes/BatteryStatusAppDelegate.h b/BatteryStatus/Classes/BatteryStatusAppDelegate.h new file mode 100644 index 0000000..4b6f6c1 --- /dev/null +++ b/BatteryStatus/Classes/BatteryStatusAppDelegate.h @@ -0,0 +1,58 @@ +/* + File: BatteryStatusAppDelegate.h + Abstract: Delegate of the BatteryStatus application that presents the initial window. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +@interface BatteryStatusAppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +@end + diff --git a/BatteryStatus/Classes/BatteryStatusAppDelegate.m b/BatteryStatus/Classes/BatteryStatusAppDelegate.m new file mode 100644 index 0000000..11203a3 --- /dev/null +++ b/BatteryStatus/Classes/BatteryStatusAppDelegate.m @@ -0,0 +1,86 @@ +/* + File: BatteryStatusAppDelegate.m + Abstract: Delegate of the BatteryStatus application that presents the initial window. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "BatteryStatusAppDelegate.h" +#import "RootViewController.h" + + +@implementation BatteryStatusAppDelegate + +@synthesize window; +@synthesize navigationController; + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after app launch + + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; + +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Save data if appropriate +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/BatteryStatus/Classes/RootViewController.h b/BatteryStatus/Classes/RootViewController.h new file mode 100644 index 0000000..6fc8787 --- /dev/null +++ b/BatteryStatus/Classes/RootViewController.h @@ -0,0 +1,58 @@ +/* + File: RootViewController.h + Abstract: Controller for initial window. Receives battery status change notifications. Queries the + battery status and presents it in a UITableView. Enables and disables battery status updates. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +@interface RootViewController : UITableViewController +{ +@private + /* private formatter instance that we'll re-use */ + NSNumberFormatter *numberFormatter; +} + +@property (nonatomic, retain, readonly) NSNumberFormatter *numberFormatter; + +@end diff --git a/BatteryStatus/Classes/RootViewController.m b/BatteryStatus/Classes/RootViewController.m new file mode 100644 index 0000000..c9dbe0f --- /dev/null +++ b/BatteryStatus/Classes/RootViewController.m @@ -0,0 +1,293 @@ +/* + File: RootViewController.m + Abstract: Controller for initial window. Receives battery status change notifications. Queries the + battery status and presents it in a UITableView. Enables and disables battery status updates. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "RootViewController.h" + +@implementation RootViewController + +enum ControlTableSections +{ + kMonitoringSection = 0, + kLevelSection, + kBatteryStateSection +}; + +- (void)dealloc +{ + [numberFormatter release]; + [super dealloc]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // This title will appear in the navigation bar + self.title = NSLocalizedString(@"Battery Status", @""); + + // Register for battery level and state change notifications. + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(batteryLevelDidChange:) + name:UIDeviceBatteryLevelDidChangeNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(batteryStateDidChange:) + name:UIDeviceBatteryStateDidChangeNotification object:nil]; +} + +- (void)didReceiveMemoryWarning +{ + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload +{ + // Release anything that can be recreated in viewDidLoad or on demand. + // e.g. self.myOutlet = nil; +} + +- (NSNumberFormatter *)numberFormatter +{ + if (numberFormatter == nil) + { + numberFormatter = [[NSNumberFormatter alloc] init]; + [numberFormatter setNumberStyle:NSNumberFormatterPercentStyle]; + [numberFormatter setMaximumFractionDigits:1]; + } + return numberFormatter; +} + +#pragma mark - Switch action handler + +- (void)switchAction:(id)sender +{ + if ([sender isOn]) + { + [UIDevice currentDevice].batteryMonitoringEnabled = YES; + // The UI will be updated as a result of the first notification. + } + else { + [UIDevice currentDevice].batteryMonitoringEnabled = NO; + [self.tableView reloadData]; + } +} + +#pragma mark - Battery notifications + +- (void)batteryLevelDidChange:(NSNotification *)notification +{ + [self.tableView reloadData]; +} + + +- (void)batteryStateDidChange:(NSNotification *)notification +{ + [self.tableView reloadData]; +} + + +#pragma mark - UITableView delegates + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 3; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + NSString *title = nil; + switch (section) + { + case kBatteryStateSection: + { + title = NSLocalizedString(@"Battery State", @""); + break; + } + } + return title; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + NSInteger rowCount = 1; + + if (section == kBatteryStateSection) + { + rowCount = 4; + } + + return rowCount; +} + +static NSInteger kLevelTag = 2; + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kMonitoringCellIdentifier = @"Monitoring"; + static NSString *kLevelCellIdentifier = @"Level"; + static NSString *kStateCellIdentifier = @"State"; + + UITableViewCell *cell = nil; + + switch (indexPath.section) + { + case kMonitoringSection: + { + cell = [tableView dequeueReusableCellWithIdentifier:kMonitoringCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kMonitoringCellIdentifier] autorelease]; + cell.textLabel.text = NSLocalizedString(@"Monitoring", @""); + + UISwitch *switchCtl = [[[UISwitch alloc] initWithFrame:CGRectMake(197, 8, 94, 27)] autorelease]; + [switchCtl addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged]; + switchCtl.backgroundColor = [UIColor clearColor]; + + [cell.contentView addSubview:switchCtl]; + } + + break; + } + + case kLevelSection: + { + cell = [tableView dequeueReusableCellWithIdentifier:kLevelCellIdentifier]; + UILabel *levelLabel = nil; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kLevelCellIdentifier] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.text = NSLocalizedString(@"Level", @""); + + levelLabel = [[[UILabel alloc] initWithFrame:CGRectMake(171, 11, 120, 21)] autorelease]; + levelLabel.tag = kLevelTag; + levelLabel.textAlignment = UITextAlignmentRight; + [cell.contentView addSubview:levelLabel]; + levelLabel.backgroundColor = [UIColor clearColor]; + } + else { + levelLabel = (UILabel *) [cell.contentView viewWithTag:kLevelTag]; + } + + float batteryLevel = [UIDevice currentDevice].batteryLevel; + if (batteryLevel < 0.0) + { + // -1.0 means battery state is UIDeviceBatteryStateUnknown + levelLabel.text = NSLocalizedString(@"Unknown", @""); + } + else { + NSNumber *levelObj = [NSNumber numberWithFloat:batteryLevel]; + + // Using the numberFormatter property lazily creates that object the + // first time it's used. + levelLabel.text = [self.numberFormatter stringFromNumber:levelObj]; + } + break; + } + + case kBatteryStateSection: + { + cell = [tableView dequeueReusableCellWithIdentifier:kStateCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kStateCellIdentifier] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + + cell.accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"StatusClear.png"]] autorelease]; + } + + switch (indexPath.row) + { + case 0: + { + cell.textLabel.text = NSLocalizedString(@"Unknown", @""); + break; + } + case 1: + { + cell.textLabel.text = NSLocalizedString(@"Unplugged", @""); + break; + } + case 2: + { + cell.textLabel.text = NSLocalizedString(@"Charging", @""); + break; + } + case 3: + { + cell.textLabel.text = NSLocalizedString(@"Full", @""); + break; + } + } + + UIImageView *statusImageView = (UIImageView *) cell.accessoryView; + if (indexPath.row + UIDeviceBatteryStateUnknown == [UIDevice currentDevice].batteryState) + { + statusImageView.image = [UIImage imageNamed:@"StatusGreen.png"]; + } + else { + statusImageView.image = [UIImage imageNamed:@"StatusClear.png"]; + } + + break; + } + } + + // Set attributes common to all cell types. + cell.selectionStyle = UITableViewCellSelectionStyleNone; + + return cell; +} + + +@end + diff --git a/BatteryStatus/Default.png b/BatteryStatus/Default.png new file mode 100644 index 0000000..d70d619 Binary files /dev/null and b/BatteryStatus/Default.png differ diff --git a/BatteryStatus/English.lproj/Localizable.strings b/BatteryStatus/English.lproj/Localizable.strings new file mode 100644 index 0000000..f01aaf9 Binary files /dev/null and b/BatteryStatus/English.lproj/Localizable.strings differ diff --git a/BatteryStatus/English.lproj/MainWindow.xib b/BatteryStatus/English.lproj/MainWindow.xib new file mode 100644 index 0000000..e336be0 --- /dev/null +++ b/BatteryStatus/English.lproj/MainWindow.xib @@ -0,0 +1,267 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + Battery Status + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + + + RootViewController + + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + BatteryStatusAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 15 + + + + YES + + BatteryStatusAppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + Classes/BatteryStatusAppDelegate.h + + + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + + 0 + BatteryStatus.xcodeproj + 3 + + diff --git a/BatteryStatus/English.lproj/RootViewController.xib b/BatteryStatus/English.lproj/RootViewController.xib new file mode 100644 index 0000000..392ec23 --- /dev/null +++ b/BatteryStatus/English.lproj/RootViewController.xib @@ -0,0 +1,197 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + {320, 416} + + NO + YES + NO + + + NO + + NO + NO + NO + NO + NO + NO + NO + 1 + 1 + 0 + 4.400000e+01 + 1.000000e+01 + 1.000000e+01 + + + + + YES + + + dataSource + + + + 12 + + + + delegate + + + + 13 + + + + tableView + + + + 14 + + + + view + + + + 15 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 9 + + + YES + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + RootViewController + UIResponder + {{409, 337}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 18 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + RootViewController + UITableViewController + + tableView + UITableView + + + IBUserSource + + + + + + 0 + BatteryStatus.xcodeproj + 3 + + diff --git a/BatteryStatus/ReadMe.txt b/BatteryStatus/ReadMe.txt new file mode 100644 index 0000000..8f845dc --- /dev/null +++ b/BatteryStatus/ReadMe.txt @@ -0,0 +1,43 @@ +### BatteryStatus ### + +================================================================================ +DESCRIPTION: + +Demonstrates the use of the battery status properties and notifications provided via the iPhone OS SDK. + +Testing: + +The sample is only useful when run on a device. The simulator always returns unknown battery status. + + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +BatteryStatusAppDelegate +Delegate of the main application that presents the initial window. + +RootViewController +Controller for initial window. Receives battery status change notifications. Queries the +battery status and presents it in a UITableView. Enables and disables battery status updates. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.1 + Updated for iOS 4. + +Version 1.0 + First release. + + +Copyright (c) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/BatteryStatus/StatusClear.png b/BatteryStatus/StatusClear.png new file mode 100644 index 0000000..a50ca8c Binary files /dev/null and b/BatteryStatus/StatusClear.png differ diff --git a/BatteryStatus/StatusGreen.png b/BatteryStatus/StatusGreen.png new file mode 100644 index 0000000..171a054 Binary files /dev/null and b/BatteryStatus/StatusGreen.png differ diff --git a/BatteryStatus/images/Icon-72.png b/BatteryStatus/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/BatteryStatus/images/Icon-72.png differ diff --git a/BatteryStatus/images/Icon-Small-50.png b/BatteryStatus/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/BatteryStatus/images/Icon-Small-50.png differ diff --git a/BatteryStatus/images/Icon-Small.png b/BatteryStatus/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/BatteryStatus/images/Icon-Small.png differ diff --git a/BatteryStatus/images/Icon-Small@2x.png b/BatteryStatus/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/BatteryStatus/images/Icon-Small@2x.png differ diff --git a/BatteryStatus/images/Icon.png b/BatteryStatus/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/BatteryStatus/images/Icon.png differ diff --git a/BatteryStatus/images/Icon@2x.png b/BatteryStatus/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/BatteryStatus/images/Icon@2x.png differ diff --git a/BatteryStatus/images/iTunesArtwork b/BatteryStatus/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/BatteryStatus/images/iTunesArtwork differ diff --git a/BatteryStatus/main.m b/BatteryStatus/main.m new file mode 100644 index 0000000..201f3aa --- /dev/null +++ b/BatteryStatus/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main application file for BatteryStatus. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/BonjourWeb.zip b/BonjourWeb.zip new file mode 100644 index 0000000..35a35b4 Binary files /dev/null and b/BonjourWeb.zip differ diff --git a/BonjourWeb/BonjourSupport/BonjourBrowser.h b/BonjourWeb/BonjourSupport/BonjourBrowser.h new file mode 100644 index 0000000..3c8ee97 --- /dev/null +++ b/BonjourWeb/BonjourSupport/BonjourBrowser.h @@ -0,0 +1,92 @@ +/* + + File: BonjourBrowser.h +Abstract: A subclass of UINavigationController that handles the UI needed for a user to +browse for Bonjour services. + It contains list view controllers for domains and service instances. + It allows the user to add their own domains. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import "BrowserViewController.h" +#import "DomainViewController.h" + +@class BonjourBrowser; + +@protocol BonjourBrowserDelegate +@required +// This method will be invoked when the user selects one of the service instances from the list. +// The ref parameter will be the selected (already resolved) instance or nil if the user taps the 'Cancel' button (if shown). +- (void) bonjourBrowser:(BonjourBrowser*)browser didResolveInstance:(NSNetService*)ref; +@end + +@interface BonjourBrowser : UINavigationController { + id __delegate; // because UINavigationContoller also has a _delegate + DomainViewController* _dvc; + BrowserViewController* _bvc; + NSString* _type; + NSString* _domain; + BOOL _showDisclosureIndicators; + NSString* _searchingForServicesString; + BOOL _showCancelButton; + BOOL _showTitleInNavigationBar; +} + +@property(nonatomic, assign) id delegate; +@property(nonatomic, copy, readwrite) NSString* searchingForServicesString; // The string to show when there are no services currently found (but updates are still ongoing) +@property(nonatomic, assign, readwrite) BOOL showTitleInNavigationBar; // If YES, the title of this object will be shown in the navigation bar + + +- (id) initForType:(NSString*)type // The Bonjour service type to browse for, e.g. @"_http._tcp" + inDomain:(NSString*)domain // The initial domain to browse in (pass nil to start in domains list) + customDomains:(NSMutableArray*)customDomains // An array of domains specified by the user + showDisclosureIndicators:(BOOL)showDisclosureIndicators // Whether to show discolsure indicators on service instance table cells + // e.g. if you want to push a view controller onto this navigation controller + showCancelButton:(BOOL)showCancelButton; // Whether to show a cancel button as the right navigation item + // Pass YES if you are modally showing this BonjourBrowser +@end + diff --git a/BonjourWeb/BonjourSupport/BonjourBrowser.m b/BonjourWeb/BonjourSupport/BonjourBrowser.m new file mode 100644 index 0000000..18676b6 --- /dev/null +++ b/BonjourWeb/BonjourSupport/BonjourBrowser.m @@ -0,0 +1,205 @@ +/* + + File: BonjourBrowser.m +Abstract: A subclass of UINavigationController that handles the UI needed for a user to +browse for Bonjour services. +It contains list view controllers for domains and service instances. +It allows the user to add their own domains. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "BonjourBrowser.h" +#import "BrowserViewController.h" +#import "DomainViewController.h" + + +@interface BonjourBrowser () +@property(nonatomic, retain, readwrite) BrowserViewController* bvc; +@property(nonatomic, retain, readwrite) DomainViewController* dvc; +@property(nonatomic, retain, readwrite) NSString* type; +@property(nonatomic, retain, readwrite) NSString* domain; +@property(nonatomic, assign, readwrite) BOOL showDisclosureIndicators; +@property(nonatomic, assign, readwrite) BOOL showCancelButton; +- (void) setupBrowser; +@end + + +@implementation BonjourBrowser + + +@synthesize bvc = _bvc; +@synthesize dvc = _dvc; +@synthesize type = _type; +@synthesize domain = _domain; +@synthesize showDisclosureIndicators = _showDisclosureIndicators; +@synthesize showCancelButton = _showCancelButton; + + +- (id) initForType:(NSString*)type inDomain:(NSString*)domain + customDomains:(NSMutableArray*)customDomains + showDisclosureIndicators:(BOOL)showDisclosureIndicators + showCancelButton:(BOOL)showCancelButton { + + // Create some strings that will be used in the DomainViewController. + NSString *domainsTitle = NSLocalizedString(@"Domains", @"Domains title"); + NSString *domainLabel = NSLocalizedString(@"Added Domains", @"Added Domains label"); + NSString *addDomainTitle = NSLocalizedString(@"Add Domain", @"Add Domain title"); + NSString *searchingForServicesString = NSLocalizedString(@"Searching for services", @"Searching for services string"); + + // Initialize the DomainViewController, which uses a NSNetServiceBrowser to look for Bonjour domains. + DomainViewController* dvc = [[DomainViewController alloc] initWithTitle:domainsTitle showDisclosureIndicators:YES customsTitle:domainLabel customs:customDomains addDomainTitle:addDomainTitle showCancelButton:showCancelButton]; + + if (dvc && (self = [super initWithRootViewController:dvc])) { + self.type = type; + self.showDisclosureIndicators = showDisclosureIndicators; + self.showCancelButton = showCancelButton; + self.searchingForServicesString = searchingForServicesString; + self.dvc = dvc; + [self.dvc setDelegate:self]; + [self.dvc searchForBrowsableDomains]; // Tells the DomainViewController's NSNetServiceBrowser to start a search for domains that are browsable via Bonjour and the computer's network configuration. + + if ([domain length]) { + self.domain = domain; + [self setupBrowser]; // Initiate a search for Bonjour services of the type self.type. + [self pushViewController:self.bvc animated:NO]; + } + } + + [dvc release]; + + return self; +} + +- (NSString*) searchingForServicesString { + return _searchingForServicesString; +} + +// This property holds a string that displays the status of the service search to the user. +- (void) setSearchingForServicesString:(NSString*)searchingForServicesString { + if (_searchingForServicesString != searchingForServicesString) { + [_searchingForServicesString release]; + _searchingForServicesString = [searchingForServicesString copy]; + + if (self.bvc) { + self.bvc.searchingForServicesString = _searchingForServicesString; + } + } +} + +- (void) setDelegate:(id)delegate { + __delegate = delegate; + super.delegate = delegate; +} + + +- (id) delegate { + assert(__delegate == super.delegate); + return __delegate; +} + + +- (BOOL) showTitleInNavigationBar { + return _showTitleInNavigationBar; +} + + +- (void) setShowTitleInNavigationBar:(BOOL)show { + _showTitleInNavigationBar = show; + if (show) { + self.bvc.navigationItem.prompt = self.title; + self.dvc.navigationItem.prompt = self.title; + } else { + self.bvc.navigationItem.prompt = nil; + self.dvc.navigationItem.prompt = nil; + } +} + + +- (void) browserViewController:(BrowserViewController*)bvc didResolveInstance:(NSNetService*)service { + assert(bvc == self.bvc); + [self.delegate bonjourBrowser:self didResolveInstance:service]; +} + +// Create a BrowserViewController, which manages a NSNetServiceBrowser configured to look for Bonjour services. +- (void) setupBrowser { + BrowserViewController* aBvc = [[BrowserViewController alloc] initWithTitle:self.domain showDisclosureIndicators:self.showDisclosureIndicators showCancelButton:self.showCancelButton]; + aBvc.searchingForServicesString = self.searchingForServicesString; + aBvc.delegate = self; + // Calls -[NSNetServiceBrowser searchForServicesOfType:inDomain:]. + [aBvc searchForServicesOfType:self.type inDomain:self.domain]; + + // Store the BrowerViewController in an instance variable. + self.bvc = aBvc; + [aBvc release]; + if (self.showTitleInNavigationBar) + self.bvc.navigationItem.prompt = self.title; +} + +// This method will be invoked when the user selects one of the domains from the list. +// The domain parameter will be the selected domain or nil if the user taps the 'Cancel' button (if shown). +- (void) domainViewController:(DomainViewController*)dvc didSelectDomain:(NSString*)domain { + if (!domain) { + // Cancel + [self.delegate bonjourBrowser:self didResolveInstance:nil]; + return; + } + + self.domain = domain; + [self setupBrowser]; + [self pushViewController:self.bvc animated:YES]; +} + + +- (void) dealloc { + [_dvc release]; + [_bvc release]; + [_type release]; + [_domain release]; + [_searchingForServicesString release]; + [super dealloc]; +} + +@end diff --git a/BonjourWeb/BonjourSupport/BrowserViewController.h b/BonjourWeb/BonjourSupport/BrowserViewController.h new file mode 100644 index 0000000..f40fcf5 --- /dev/null +++ b/BonjourWeb/BonjourSupport/BrowserViewController.h @@ -0,0 +1,94 @@ +/* + + File: BrowserViewController.h +Abstract: View controller for the service instance list. + This object manages a NSNetServiceBrowser configured to look for Bonjour +services. + It has an array of NSNetService objects that are displayed in a table view. + When the service browser reports that it has discovered a service, the +corresponding NSNetService is added to the array. + When a service goes away, the corresponding NSNetService is removed from the +array. + Selecting an item in the table view asynchronously resolves the corresponding +net service. + When that resolution completes, the delegate is called with the corresponding +NSNetService. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import + +@class BrowserViewController; + +@protocol BrowserViewControllerDelegate +@required +// This method will be invoked when the user selects one of the service instances from the list. +// The ref parameter will be the selected (already resolved) instance or nil if the user taps the 'Cancel' button (if shown). +- (void) browserViewController:(BrowserViewController*)bvc didResolveInstance:(NSNetService*)ref; +@end + +@interface BrowserViewController : UITableViewController { + +@private + id _delegate; + NSString* _searchingForServicesString; + BOOL _showDisclosureIndicators; + NSMutableArray* _services; + NSNetServiceBrowser* _netServiceBrowser; + NSNetService* _currentResolve; + NSTimer* _timer; + BOOL _needsActivityIndicator; + BOOL _initialWaitOver; +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, copy) NSString* searchingForServicesString; + +- (id)initWithTitle:(NSString *)title showDisclosureIndicators:(BOOL)showDisclosureIndicators showCancelButton:(BOOL)showCancelButton; +- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain; + +@end diff --git a/BonjourWeb/BonjourSupport/BrowserViewController.m b/BonjourWeb/BonjourSupport/BrowserViewController.m new file mode 100644 index 0000000..2c93372 --- /dev/null +++ b/BonjourWeb/BonjourSupport/BrowserViewController.m @@ -0,0 +1,386 @@ +/* + + File: BrowserViewController.m +Abstract: View controller for the service instance list. +This object manages a NSNetServiceBrowser configured to look for Bonjour +services. +It has an array of NSNetService objects that are displayed in a table view. +When the service browser reports that it has discovered a service, the +corresponding NSNetService is added to the array. +When a service goes away, the corresponding NSNetService is removed from the +array. +Selecting an item in the table view asynchronously resolves the corresponding +net service. +When that resolution completes, the delegate is called with the corresponding +NSNetService. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "BrowserViewController.h" + +#define kProgressIndicatorSize 20.0 + +// A category on NSNetService that's used to sort NSNetService objects by their name. +@interface NSNetService (BrowserViewControllerAdditions) +- (NSComparisonResult) localizedCaseInsensitiveCompareByName:(NSNetService*)aService; +@end + +@implementation NSNetService (BrowserViewControllerAdditions) +- (NSComparisonResult) localizedCaseInsensitiveCompareByName:(NSNetService*)aService { + return [[self name] localizedCaseInsensitiveCompare:[aService name]]; +} +@end + + +@interface BrowserViewController() +@property (nonatomic, assign, readwrite) BOOL showDisclosureIndicators; +@property (nonatomic, retain, readwrite) NSMutableArray* services; +@property (nonatomic, retain, readwrite) NSNetServiceBrowser* netServiceBrowser; +@property (nonatomic, retain, readwrite) NSNetService* currentResolve; +@property (nonatomic, retain, readwrite) NSTimer* timer; +@property (nonatomic, assign, readwrite) BOOL needsActivityIndicator; +@property (nonatomic, assign, readwrite) BOOL initialWaitOver; + +- (void)stopCurrentResolve; +- (void)initialWaitOver:(NSTimer*)timer; +@end + +@implementation BrowserViewController + +@synthesize delegate = _delegate; +@synthesize showDisclosureIndicators = _showDisclosureIndicators; +@synthesize currentResolve = _currentResolve; +@synthesize netServiceBrowser = _netServiceBrowser; +@synthesize services = _services; +@synthesize needsActivityIndicator = _needsActivityIndicator; +@dynamic timer; +@synthesize initialWaitOver = _initialWaitOver; + +- (id)initWithTitle:(NSString*)title showDisclosureIndicators:(BOOL)show showCancelButton:(BOOL)showCancelButton { + + if ((self = [super initWithStyle:UITableViewStylePlain])) { + self.title = title; + _services = [[NSMutableArray alloc] init]; + self.showDisclosureIndicators = show; + + if (showCancelButton) { + // add Cancel button as the nav bar's custom right view + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction)]; + self.navigationItem.rightBarButtonItem = addButton; + [addButton release]; + } + + // Make sure we have a chance to discover devices before showing the user that nothing was found (yet) + [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(initialWaitOver:) userInfo:nil repeats:NO]; + } + + return self; +} + +- (NSString *)searchingForServicesString { + return _searchingForServicesString; +} + +// Holds the string that's displayed in the table view during service discovery. +- (void)setSearchingForServicesString:(NSString *)searchingForServicesString { + if (_searchingForServicesString != searchingForServicesString) { + [_searchingForServicesString release]; + _searchingForServicesString = [searchingForServicesString copy]; + + // If there are no services, reload the table to ensure that searchingForServicesString appears. + if ([self.services count] == 0) { + [self.tableView reloadData]; + } + } +} + +// Creates an NSNetServiceBrowser that searches for services of a particular type in a particular domain. +// If a service is currently being resolved, stop resolving it and stop the service browser from +// discovering other services. +- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain { + + [self stopCurrentResolve]; + [self.netServiceBrowser stop]; + [self.services removeAllObjects]; + + NSNetServiceBrowser *aNetServiceBrowser = [[NSNetServiceBrowser alloc] init]; + if(!aNetServiceBrowser) { + // The NSNetServiceBrowser couldn't be allocated and initialized. + return NO; + } + + aNetServiceBrowser.delegate = self; + self.netServiceBrowser = aNetServiceBrowser; + [aNetServiceBrowser release]; + [self.netServiceBrowser searchForServicesOfType:type inDomain:domain]; + + [self.tableView reloadData]; + return YES; +} + + +- (NSTimer *)timer { + return _timer; +} + +// When this is called, invalidate the existing timer before releasing it. +- (void)setTimer:(NSTimer *)newTimer { + [_timer invalidate]; + [newTimer retain]; + [_timer release]; + _timer = newTimer; +} + + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // If there are no services and searchingForServicesString is set, show one row to tell the user. + NSUInteger count = [self.services count]; + if (count == 0 && self.searchingForServicesString && self.initialWaitOver) + return 1; + + return count; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *tableCellIdentifier = @"UITableViewCell"; + UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableCellIdentifier] autorelease]; + } + + NSUInteger count = [self.services count]; + if (count == 0 && self.searchingForServicesString) { + // If there are no services and searchingForServicesString is set, show one row explaining that to the user. + cell.textLabel.text = self.searchingForServicesString; + cell.textLabel.textColor = [UIColor colorWithWhite:0.5 alpha:0.5]; + cell.accessoryType = UITableViewCellAccessoryNone; + // Make sure to get rid of the activity indicator that may be showing if we were resolving cell zero but + // then got didRemoveService callbacks for all services (e.g. the network connection went down). + if (cell.accessoryView) + cell.accessoryView = nil; + return cell; + } + + // Set up the text for the cell + NSNetService* service = [self.services objectAtIndex:indexPath.row]; + cell.textLabel.text = [service name]; + cell.textLabel.textColor = [UIColor blackColor]; + cell.accessoryType = self.showDisclosureIndicators ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + // Note that the underlying array could have changed, and we want to show the activity indicator on the correct cell + if (self.needsActivityIndicator && self.currentResolve == service) { + if (!cell.accessoryView) { + CGRect frame = CGRectMake(0.0, 0.0, kProgressIndicatorSize, kProgressIndicatorSize); + UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithFrame:frame]; + [spinner startAnimating]; + spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; + [spinner sizeToFit]; + spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | + UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleTopMargin | + UIViewAutoresizingFlexibleBottomMargin); + cell.accessoryView = spinner; + [spinner release]; + } + } else if (cell.accessoryView) { + cell.accessoryView = nil; + } + + return cell; +} + + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // Ignore the selection if there are no services as the searchingForServicesString cell + // may be visible and tapping it would do nothing + if ([self.services count] == 0) + return nil; + + return indexPath; +} + + +- (void)stopCurrentResolve { + self.needsActivityIndicator = NO; + self.timer = nil; + + [self.currentResolve stop]; + self.currentResolve = nil; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // If another resolve was running, stop it & remove the activity indicator from that cell + if (self.currentResolve) { + // Get the indexPath for the active resolve cell + NSIndexPath* indexPath = [NSIndexPath indexPathForRow:[self.services indexOfObject:self.currentResolve] inSection:0]; + + // Stop the current resolve, which will also set self.needsActivityIndicator + [self stopCurrentResolve]; + + // If we found the indexPath for the row, reload that cell to remove the activity indicator + if (indexPath.row != NSNotFound) + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; + } + + // Then set the current resolve to the service corresponding to the tapped cell + self.currentResolve = [self.services objectAtIndex:indexPath.row]; + [self.currentResolve setDelegate:self]; + + // Attempt to resolve the service. A value of 0.0 sets an unlimited time to resolve it. The user can + // choose to cancel the resolve by selecting another service in the table view. + [self.currentResolve resolveWithTimeout:0.0]; + + // Make sure we give the user some feedback that the resolve is happening. + // We will be called back asynchronously, so we don't want the user to think we're just stuck. + // We delay showing this activity indicator in case the service is resolved quickly. + self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showWaiting:) userInfo:self.currentResolve repeats:NO]; +} + + +// If necessary, sets up state to show an activity indicator to let the user know that a resolve is occuring. +- (void)showWaiting:(NSTimer*)timer { + if (timer == self.timer) { + NSNetService* service = (NSNetService*)[self.timer userInfo]; + if (self.currentResolve == service) { + self.needsActivityIndicator = YES; + + NSIndexPath* indexPath = [NSIndexPath indexPathForRow:[self.services indexOfObject:self.currentResolve] inSection:0]; + if (indexPath.row != NSNotFound) { + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; + // Deselect the row since the activity indicator shows the user something is happening. + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + } + } + } +} + + +- (void)initialWaitOver:(NSTimer*)timer { + self.initialWaitOver= YES; + if (![self.services count]) + [self.tableView reloadData]; +} + + +- (void)sortAndUpdateUI { + // Sort the services by name. + [self.services sortUsingSelector:@selector(localizedCaseInsensitiveCompareByName:)]; + [self.tableView reloadData]; +} + + +- (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser didRemoveService:(NSNetService*)service moreComing:(BOOL)moreComing { + // If a service went away, stop resolving it if it's currently being resolved, + // remove it from the list and update the table view if no more events are queued. + if (self.currentResolve && [service isEqual:self.currentResolve]) { + [self stopCurrentResolve]; + } + [self.services removeObject:service]; + + // If moreComing is NO, it means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI. + // When moreComing is set, we don't update the UI so that it doesn't 'flash'. + if (!moreComing) { + [self sortAndUpdateUI]; + } +} + + +- (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser didFindService:(NSNetService*)service moreComing:(BOOL)moreComing { + // If a service came online, add it to the list and update the table view if no more events are queued. + [self.services addObject:service]; + + // If moreComing is NO, it means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI. + // When moreComing is set, we don't update the UI so that it doesn't 'flash'. + if (!moreComing) { + [self sortAndUpdateUI]; + } +} + + +// This should never be called, since we resolve with a timeout of 0.0, which means indefinite +- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict { + [self stopCurrentResolve]; + [self.tableView reloadData]; +} + + +- (void)netServiceDidResolveAddress:(NSNetService *)service { + assert(service == self.currentResolve); + + [service retain]; + [self stopCurrentResolve]; + + [self.delegate browserViewController:self didResolveInstance:service]; + [service release]; +} + + +- (void)cancelAction { + [self.delegate browserViewController:self didResolveInstance:nil]; +} + + +- (void)dealloc { + // Cleanup any running resolve and free memory + [self stopCurrentResolve]; + self.services = nil; + [self.netServiceBrowser stop]; + self.netServiceBrowser = nil; + [_searchingForServicesString release]; + + [super dealloc]; +} + + +@end diff --git a/BonjourWeb/BonjourSupport/DomainViewController.h b/BonjourWeb/BonjourSupport/DomainViewController.h new file mode 100644 index 0000000..ee0f8d5 --- /dev/null +++ b/BonjourWeb/BonjourSupport/DomainViewController.h @@ -0,0 +1,92 @@ +/* + + File: DomainViewController.h +Abstract: View controller for the domain list. + This object manages a NSNetServiceBrowser configured to look for Bonjour +domains. + It has two arrays of NSString objects that are displayed in two sections of a +table view. + When the service browser reports that it has discovered a domain, that domain +is added to the first array. + When a domain goes away it is removed from the first array. + It allows the user to add/remove their own domains from the second array, which +is displayed in the second section of the table. + When an item in the table view is selected, the delegate is called with the +corresponding domain. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import +#import "SimpleEditViewController.h" + +@class DomainViewController; + +@protocol DomainViewControllerDelegate +@required +// This method will be invoked when the user selects one of the domains from the list. +// The domain parameter will be the selected domain or nil if the user taps the 'Cancel' button (if shown) +- (void) domainViewController:(DomainViewController*)dvc didSelectDomain:(NSString*)domain; +@end + +@interface DomainViewController : UITableViewController { + id _delegate; + BOOL _showDisclosureIndicators; + NSMutableArray* _domains; + NSMutableArray* _customs; + NSString* _customTitle; + NSString* _addDomainTitle; + NSNetServiceBrowser* _netServiceBrowser; + BOOL _showCancelButton; +} + +@property(nonatomic, assign) id delegate; + +- (id)initWithTitle:(NSString *)title showDisclosureIndicators:(BOOL)showDisclosureIndicators customsTitle:(NSString*)customsTitle customs:(NSMutableArray*)customs addDomainTitle:(NSString*)addDomainTitle showCancelButton:(BOOL)showCancelButton; +- (BOOL)searchForBrowsableDomains; +- (BOOL)searchForRegistrationDomains; + +@end diff --git a/BonjourWeb/BonjourSupport/DomainViewController.m b/BonjourWeb/BonjourSupport/DomainViewController.m new file mode 100644 index 0000000..24135bb --- /dev/null +++ b/BonjourWeb/BonjourSupport/DomainViewController.m @@ -0,0 +1,356 @@ +/* + + File: DomainViewController.m +Abstract: View controller for the domain list. +This object manages a NSNetServiceBrowser configured to look for Bonjour +domains. +It has two arrays of NSString objects that are displayed in two sections of a +table view. +When the service browser reports that it has discovered a domain, that domain +is added to the first array. +When a domain goes away it is removed from the first array. +It allows the user to add/remove their own domains from the second array, which +is displayed in the second section of the table. +When an item in the table view is selected, the delegate is called with the +corresponding domain. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "DomainViewController.h" + +#define kProgressIndicatorSize 20.0 + +@interface DomainViewController () +@property(nonatomic, assign) BOOL showDisclosureIndicators; +@property(nonatomic, retain) NSMutableArray* domains; +@property(nonatomic, retain) NSMutableArray* customs; +@property(nonatomic, retain) NSString* customTitle; +@property(nonatomic, retain) NSString* addDomainTitle; +@property(nonatomic, retain) NSNetServiceBrowser* netServiceBrowser; +@property(nonatomic, assign) BOOL showCancelButton; + +- (void)addButtons:(BOOL)editing; +- (void)addAction:(id)sender; +- (void)editAction:(id)sender; +@end + +@implementation DomainViewController + +@synthesize delegate = _delegate; +@synthesize showDisclosureIndicators = _showDisclosureIndicators; +@synthesize domains = _domains; +@synthesize customs = _customs; +@synthesize customTitle = _customTitle; +@synthesize addDomainTitle = _addDomainTitle; +@dynamic netServiceBrowser; +@synthesize showCancelButton = _showCancelButton; + +// Initialization. BonjourBrowser invokes this during its initialization. +- (id)initWithTitle:(NSString*)title showDisclosureIndicators:(BOOL)show customsTitle:(NSString*)customsTitle customs:(NSMutableArray*)customs addDomainTitle:(NSString*)addDomainTitle showCancelButton:(BOOL)showCancelButton { + if ((self = [super initWithStyle:UITableViewStylePlain])) { + self.title = title; + self.domains = [[[NSMutableArray alloc] init] autorelease]; + self.showDisclosureIndicators = show; + self.customTitle = customsTitle; + self.customs = customs ? customs : [NSMutableArray array]; + self.addDomainTitle = addDomainTitle; + self.showCancelButton = showCancelButton; + [self addButtons:self.tableView.editing]; + } + + return self; +} + +// Stores newBrowser in the _netServiceBrowser instance variable. If _netServiceBrowser has already been set, +// this first sends it a -stop message before releasing it. +- (void)setNetServiceBrowser:(NSNetServiceBrowser*)newBrowser { + [_netServiceBrowser stop]; + [newBrowser retain]; + [_netServiceBrowser release]; + _netServiceBrowser = newBrowser; +} + + +- (NSNetServiceBrowser*)netServiceBrowser { + return _netServiceBrowser; +} + + +- (void)addAddButton:(BOOL)right { + // add + button as the nav bar's custom right view + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction:)]; + if (right) self.navigationItem.rightBarButtonItem = addButton; + else self.navigationItem.leftBarButtonItem = addButton; + [addButton release]; +} + +- (void)addButtons:(BOOL)editing { + if (editing) { + // Add the "done" button to the navigation bar + UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneAction:)]; + + self.navigationItem.leftBarButtonItem = doneButton; + [doneButton release]; + + [self addAddButton:YES]; + } else { + if ([self.customs count]) { + // Add the "edit" button to the navigation bar + UIBarButtonItem *editButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editAction:)]; + + self.navigationItem.leftBarButtonItem = editButton; + [editButton release]; + } else { + [self addAddButton:NO]; + } + + if (self.showCancelButton) { + // add Cancel button as the nav bar's custom right view + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction)]; + self.navigationItem.rightBarButtonItem = addButton; + [addButton release]; + } else { + self.navigationItem.rightBarButtonItem = nil; + } + } +} + +- (BOOL)commonSetup { + self.netServiceBrowser = [[[NSNetServiceBrowser alloc] init] autorelease]; + if(!self.netServiceBrowser) { + return NO; + } + + [self.netServiceBrowser setDelegate:self]; + return YES; +} + +// A cover method to -[NSNetServiceBrowser searchForBrowsableDomains]. +- (BOOL)searchForBrowsableDomains { + if (![self commonSetup]) return NO; + [self.netServiceBrowser searchForBrowsableDomains]; + return YES; +} + +// A cover method to -[NSNetServiceBrowser searchForRegistrationDomains]. +- (BOOL)searchForRegistrationDomains { + if (![self commonSetup]) return NO; + [self.netServiceBrowser searchForRegistrationDomains]; + return YES; +} + + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1 + ([self.customs count] ? 1 : 0); +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [(section ? self.customs : self.domains) count]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + return section ? self.customTitle : @"Bonjour"; // Note that "Bonjour" is the proper name of the technology, therefore should not be localized +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"] autorelease]; + } + + // Set up the text for the cell + cell.textLabel.text = [(indexPath.section ? self.customs : self.domains) objectAtIndex:indexPath.row]; + cell.textLabel.textColor = [UIColor blackColor]; + cell.accessoryType = self.showDisclosureIndicators ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + return cell; +} + + +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + return indexPath.section && tableView.editing; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [self.delegate domainViewController:self didSelectDomain:[(indexPath.section ? self.customs : self.domains) objectAtIndex:indexPath.row]]; +} + + +- (void)updateUI { + // Sort the domains by name, then modify the selection, as it may have moved + [self.domains sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + [self.tableView reloadData]; +} + +/* + The 'domain' parameter passed to netServiceBrowser:didRemoveDomain:moreComing: and netServiceBrowser:didFindDomain:moreComing: may contain escaped characters. This function unescapes them before they are added to or removed from the list that is displayed to the user. +*/ +- (NSString*) transmogrify:(NSString*)aString { + + NSString* tmp = [NSString stringWithString:aString]; + const char *ostr = [tmp UTF8String]; + const char *cstr = ostr; + char *ptr = (char*) ostr; + + while (*cstr) { + char c = *cstr++; + if (c == '\\') + { + c = *cstr++; + if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1])) + { + NSInteger v0 = cstr[-1] - '0'; // then interpret as three-digit decimal + NSInteger v1 = cstr[ 0] - '0'; + NSInteger v2 = cstr[ 1] - '0'; + NSInteger val = v0 * 100 + v1 * 10 + v2; + if (val <= 255) { c = (char)val; cstr += 2; } // If valid three-digit decimal value, use it + } + } + *ptr++ = c; + } + ptr--; + *ptr = 0; + return [NSString stringWithUTF8String:ostr]; +} + + +- (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser didRemoveDomain:(NSString*)domain moreComing:(BOOL)moreComing { + [self.domains removeObject:[self transmogrify:domain]]; + + // moreComing really means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI. + // When moreComing is set, we don't update the UI so that it doesn't 'flash'. + if (!moreComing) + [self updateUI]; +} + + +- (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser didFindDomain:(NSString*)domain moreComing:(BOOL)moreComing { + NSString* tmp = [self transmogrify:domain]; + if (![self.domains containsObject:tmp]) [self.domains addObject:tmp]; + + // moreComing really means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI. + // When moreComing is set, we don't update the UI so that it doesn't 'flash'. + if (!moreComing) + [self updateUI]; +} + + +- (void)doneAction:(id)sender { + [self.tableView setEditing:NO animated:YES]; + [self addButtons:self.tableView.editing]; +} + + +- (void)editAction:(id)sender { + [self.tableView setEditing:YES animated:YES]; + [self addButtons:self.tableView.editing]; +} + + +- (IBAction)cancelAction { + [self.delegate domainViewController:self didSelectDomain:nil]; +} + + +- (void)addAction:(id)sender { + SimpleEditViewController* sevc = [[SimpleEditViewController alloc] initWithTitle:self.addDomainTitle currentText:nil]; + [sevc setDelegate:self]; + UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:sevc]; + [sevc release]; + [self.navigationController presentModalViewController:nc animated:YES]; + [nc release]; +} + + +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + assert(editingStyle == UITableViewCellEditingStyleDelete); + assert(indexPath.section == 1); + [self.customs removeObjectAtIndex:indexPath.row]; + if (![self.customs count]) { + [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationRight]; + } else { + [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; + } + [self addButtons:self.tableView.editing]; +} + + +- (void) simpleEditViewController:(SimpleEditViewController*)sevc didGetText:(NSString*)text { + [self.navigationController dismissModalViewControllerAnimated:YES]; + + if (![text length]) + return; + + if (![self.customs containsObject:text]) { + [self.customs addObject:text]; + [self.customs sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + } + + [self addButtons:self.tableView.editing]; + [self.tableView reloadData]; + NSUInteger ints[2] = {1,[self.customs indexOfObject:text]}; + NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:ints length:2]; + [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES]; +} + + +- (void)dealloc { + [_domains release]; + [_customs release]; + [_customTitle release]; + [_addDomainTitle release]; + [_netServiceBrowser release]; + + [super dealloc]; +} + +@end diff --git a/BonjourWeb/BonjourSupport/SimpleEditViewController.h b/BonjourWeb/BonjourSupport/SimpleEditViewController.h new file mode 100644 index 0000000..83bb176 --- /dev/null +++ b/BonjourWeb/BonjourSupport/SimpleEditViewController.h @@ -0,0 +1,70 @@ +/* + File: SimpleEditViewController.h +Abstract: View controller which allows the user to enter a small amount of text. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class SimpleEditViewController; + +@protocol SimpleEditViewControllerDelegate +@required +// This method will be invoked when the user taps the 'Done' or 'Cancel' buttons. +// The text parameter will be nil if the user taps the 'Cancel' button. +- (void) simpleEditViewController:(SimpleEditViewController*)sevc didGetText:(NSString*)text; +@end + +@interface SimpleEditViewController : UIViewController { + id _delegate; + UITextField* _textField; + BOOL cancelling; +} + +@property(nonatomic, assign) id delegate; + +- (id)initWithTitle:(NSString*)title currentText:(NSString*)current; + +@end diff --git a/BonjourWeb/BonjourSupport/SimpleEditViewController.m b/BonjourWeb/BonjourSupport/SimpleEditViewController.m new file mode 100644 index 0000000..fb9109c --- /dev/null +++ b/BonjourWeb/BonjourSupport/SimpleEditViewController.m @@ -0,0 +1,132 @@ +/* + + File: SimpleEditViewController.m +Abstract: View controller which allows the user to enter a small amount of text. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "SimpleEditViewController.h" + +@interface SimpleEditViewController () +@property(nonatomic, retain) UITextField* textField; +@end + +@implementation SimpleEditViewController + +@synthesize delegate = _delegate; +@synthesize textField = _textField; + +- (id)initWithTitle:(NSString*)title currentText:(NSString*)current { + + if ((self = [super init])) { + self.title = title; + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; + + // Add the "cancel" button to the navigation bar + UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction)]; + + self.navigationItem.leftBarButtonItem = cancelButton; + [cancelButton release]; + + CGSize size = self.view.frame.size; + CGRect rect = CGRectMake(5, 5, size.width-10, 30); + + _textField = [[UITextField alloc] initWithFrame:rect]; + + _textField.text = current; + _textField.autocorrectionType = UITextAutocorrectionTypeNo; + _textField.autocapitalizationType = UITextAutocapitalizationTypeNone; + _textField.borderStyle = UITextBorderStyleRoundedRect; + _textField.textColor = [UIColor blackColor]; + _textField.font = [UIFont systemFontOfSize:17.0]; + _textField.backgroundColor = [UIColor clearColor]; + _textField.keyboardType = UIKeyboardTypeURL; + _textField.returnKeyType = UIReturnKeyDone; + _textField.clearButtonMode = UITextFieldViewModeWhileEditing; + + _textField.delegate = self; + + [self.view addSubview:_textField]; + + [_textField becomeFirstResponder]; + + cancelling = NO; + } + + return self; +} + + +- (IBAction)cancelAction { + cancelling = YES; + [self.textField resignFirstResponder]; +} + + +- (void)textFieldDidEndEditing:(UITextField *)textField { + if (textField == self.textField) { + [self.delegate simpleEditViewController:self didGetText:cancelling ? nil : self.textField.text]; + } +} + + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + if (textField == self.textField) { + [self.textField resignFirstResponder]; + } + return YES; +} + + +- (void)dealloc { + [_textField release]; + [super dealloc]; +} + + +@end + diff --git a/BonjourWeb/BonjourWeb.xcodeproj/project.pbxproj b/BonjourWeb/BonjourWeb.xcodeproj/project.pbxproj new file mode 100755 index 0000000..18aba74 --- /dev/null +++ b/BonjourWeb/BonjourWeb.xcodeproj/project.pbxproj @@ -0,0 +1,322 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D4F2F9A0D10AC310045FB13 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D4F2F990D10AC310045FB13 /* Default.png */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 28141FFC0D6E783400D05362 /* BonjourWebAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 28141FFB0D6E783400D05362 /* BonjourWebAppDelegate.m */; }; + 2883CB400DE2CC1800AFA03B /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2883CB3F0DE2CC1800AFA03B /* Icon.png */; }; + 2B449E2911C8326F00B24959 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B449E2811C8326F00B24959 /* CoreGraphics.framework */; }; + 2B449E2B11C8327500B24959 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B449E2A11C8327500B24959 /* Foundation.framework */; }; + 2B449E2D11C8327B00B24959 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B449E2C11C8327B00B24959 /* UIKit.framework */; }; + 4ADC7FB80DDD21B500F4B61B /* BonjourBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ADC7FB10DDD21B500F4B61B /* BonjourBrowser.m */; }; + 4ADC7FB90DDD21B500F4B61B /* BrowserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ADC7FB30DDD21B500F4B61B /* BrowserViewController.m */; }; + 4ADC7FBA0DDD21B500F4B61B /* DomainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ADC7FB50DDD21B500F4B61B /* DomainViewController.m */; }; + 4ADC7FBB0DDD21B500F4B61B /* SimpleEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ADC7FB70DDD21B500F4B61B /* SimpleEditViewController.m */; }; + 533541920F94E6F300F4AF08 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5335418E0F94E6F300F4AF08 /* Localizable.strings */; }; + 533541930F94E6F300F4AF08 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 533541900F94E6F300F4AF08 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D4F2F990D10AC310045FB13 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* BonjourWeb.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BonjourWeb.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 28141FF50D6E774E00D05362 /* BonjourWeb_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BonjourWeb_Prefix.pch; sourceTree = ""; }; + 28141FFA0D6E783400D05362 /* BonjourWebAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BonjourWebAppDelegate.h; sourceTree = ""; }; + 28141FFB0D6E783400D05362 /* BonjourWebAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BonjourWebAppDelegate.m; sourceTree = ""; }; + 2883CB3F0DE2CC1800AFA03B /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B449E2811C8326F00B24959 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2B449E2A11C8327500B24959 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2B449E2C11C8327B00B24959 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 4ADC7FB00DDD21B500F4B61B /* BonjourBrowser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BonjourBrowser.h; path = BonjourSupport/BonjourBrowser.h; sourceTree = ""; }; + 4ADC7FB10DDD21B500F4B61B /* BonjourBrowser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BonjourBrowser.m; path = BonjourSupport/BonjourBrowser.m; sourceTree = ""; }; + 4ADC7FB20DDD21B500F4B61B /* BrowserViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserViewController.h; path = BonjourSupport/BrowserViewController.h; sourceTree = ""; }; + 4ADC7FB30DDD21B500F4B61B /* BrowserViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserViewController.m; path = BonjourSupport/BrowserViewController.m; sourceTree = ""; }; + 4ADC7FB40DDD21B500F4B61B /* DomainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DomainViewController.h; path = BonjourSupport/DomainViewController.h; sourceTree = ""; }; + 4ADC7FB50DDD21B500F4B61B /* DomainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DomainViewController.m; path = BonjourSupport/DomainViewController.m; sourceTree = ""; }; + 4ADC7FB60DDD21B500F4B61B /* SimpleEditViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SimpleEditViewController.h; path = BonjourSupport/SimpleEditViewController.h; sourceTree = ""; }; + 4ADC7FB70DDD21B500F4B61B /* SimpleEditViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SimpleEditViewController.m; path = BonjourSupport/SimpleEditViewController.m; sourceTree = ""; }; + 5335418F0F94E6F300F4AF08 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 533541910F94E6F300F4AF08 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 844867370DB92514009556CD /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; wrapsLines = 1; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B449E2911C8326F00B24959 /* CoreGraphics.framework in Frameworks */, + 2B449E2B11C8327500B24959 /* Foundation.framework in Frameworks */, + 2B449E2D11C8327B00B24959 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28141FFA0D6E783400D05362 /* BonjourWebAppDelegate.h */, + 28141FFB0D6E783400D05362 /* BonjourWebAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* BonjourWeb.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 844867370DB92514009556CD /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 4ADC7FA00DDD217500F4B61B /* Support */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28141FF50D6E774E00D05362 /* BonjourWeb_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 5335418E0F94E6F300F4AF08 /* Localizable.strings */, + 533541900F94E6F300F4AF08 /* MainWindow.xib */, + 1D4F2F990D10AC310045FB13 /* Default.png */, + 2883CB3F0DE2CC1800AFA03B /* Icon.png */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B449E2811C8326F00B24959 /* CoreGraphics.framework */, + 2B449E2A11C8327500B24959 /* Foundation.framework */, + 2B449E2C11C8327B00B24959 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 4ADC7FA00DDD217500F4B61B /* Support */ = { + isa = PBXGroup; + children = ( + 4ADC7FB00DDD21B500F4B61B /* BonjourBrowser.h */, + 4ADC7FB10DDD21B500F4B61B /* BonjourBrowser.m */, + 4ADC7FB20DDD21B500F4B61B /* BrowserViewController.h */, + 4ADC7FB30DDD21B500F4B61B /* BrowserViewController.m */, + 4ADC7FB40DDD21B500F4B61B /* DomainViewController.h */, + 4ADC7FB50DDD21B500F4B61B /* DomainViewController.m */, + 4ADC7FB60DDD21B500F4B61B /* SimpleEditViewController.h */, + 4ADC7FB70DDD21B500F4B61B /* SimpleEditViewController.m */, + ); + name = Support; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* BonjourWeb */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "BonjourWeb" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BonjourWeb; + productName = BonjourWeb; + productReference = 1D6058910D05DD3D006BFB54 /* BonjourWeb.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "BonjourWeb" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* BonjourWeb */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D4F2F9A0D10AC310045FB13 /* Default.png in Resources */, + 2883CB400DE2CC1800AFA03B /* Icon.png in Resources */, + 533541920F94E6F300F4AF08 /* Localizable.strings in Resources */, + 533541930F94E6F300F4AF08 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 28141FFC0D6E783400D05362 /* BonjourWebAppDelegate.m in Sources */, + 4ADC7FB80DDD21B500F4B61B /* BonjourBrowser.m in Sources */, + 4ADC7FB90DDD21B500F4B61B /* BrowserViewController.m in Sources */, + 4ADC7FBA0DDD21B500F4B61B /* DomainViewController.m in Sources */, + 4ADC7FBB0DDD21B500F4B61B /* SimpleEditViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5335418E0F94E6F300F4AF08 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 5335418F0F94E6F300F4AF08 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 533541900F94E6F300F4AF08 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 533541910F94E6F300F4AF08 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = BonjourWeb_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = BonjourWeb; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = BonjourWeb_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = BonjourWeb; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "BonjourWeb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "BonjourWeb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/BonjourWeb/BonjourWeb_Prefix.pch b/BonjourWeb/BonjourWeb_Prefix.pch new file mode 100755 index 0000000..4c63f9a --- /dev/null +++ b/BonjourWeb/BonjourWeb_Prefix.pch @@ -0,0 +1,59 @@ +/* + + File: BonjourWeb_Prefix.pch +Abstract: This file is included for support purposes and isn't necessary for +understanding this sample. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +// +// Prefix header for all source files of the 'BonjourWeb' target in the 'BonjourWeb' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/BonjourWeb/Classes/BonjourWebAppDelegate.h b/BonjourWeb/Classes/BonjourWebAppDelegate.h new file mode 100755 index 0000000..dd423ff --- /dev/null +++ b/BonjourWeb/Classes/BonjourWebAppDelegate.h @@ -0,0 +1,66 @@ +/* + + File: BonjourWebAppDelegate.h +Abstract: The application delegate. + It creates the BonjourBrowser (a navigation controller) and is the delgate for +that BonjourBrowser. + When it gets the delegate callback, it constructs a URL and launches that URL +in Safari. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import "BonjourBrowser.h" + +@interface BonjourWebAppDelegate : NSObject { + UIWindow *window; + BonjourBrowser *browser; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) BonjourBrowser *browser; + +@end diff --git a/BonjourWeb/Classes/BonjourWebAppDelegate.m b/BonjourWeb/Classes/BonjourWebAppDelegate.m new file mode 100755 index 0000000..43e60a8 --- /dev/null +++ b/BonjourWeb/Classes/BonjourWebAppDelegate.m @@ -0,0 +1,155 @@ +/* + + File: BonjourWebAppDelegate.m +Abstract: The application delegate. +It creates the BonjourBrowser (a navigation controller) and is the delgate for +that BonjourBrowser. +When it gets the delegate callback, it constructs a URL and launches that URL +in Safari. + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "BonjourWebAppDelegate.h" +#import "BonjourBrowser.h" + + +#define kWebServiceType @"_http._tcp" +#define kInitialDomain @"local" + + +@implementation BonjourWebAppDelegate + +@synthesize window; +@synthesize browser; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + // Create the Bonjour Browser for Web services + BonjourBrowser *aBrowser = [[BonjourBrowser alloc] initForType:kWebServiceType + inDomain:kInitialDomain + customDomains:nil // we won't save any additional domains added by the user + showDisclosureIndicators:NO + showCancelButton:NO]; + self.browser = aBrowser; + [aBrowser release]; + + self.browser.delegate = self; + + // We want to let the user know that the services list is dynamic and always updating, even when there are no + // services currently found. + self.browser.searchingForServicesString = NSLocalizedString(@"Searching for web services", @"Searching for web services string"); + + // Add the controller's view as a subview of the window + [self.window addSubview:[self.browser view]]; +} + + +- (void)dealloc { + [browser release]; + [window release]; + [super dealloc]; +} + + +- (NSString *)copyStringFromTXTDict:(NSDictionary *)dict which:(NSString*)which { + // Helper for getting information from the TXT data + NSData* data = [dict objectForKey:which]; + NSString *resultString = nil; + if (data) { + resultString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + } + return resultString; +} + + +- (void) bonjourBrowser:(BonjourBrowser*)browser didResolveInstance:(NSNetService*)service { + // Construct the URL including the port number + // Also use the path, username and password fields that can be in the TXT record + NSDictionary* dict = [[NSNetService dictionaryFromTXTRecordData:[service TXTRecordData]] retain]; + NSString *host = [service hostName]; + + NSString* user = [self copyStringFromTXTDict:dict which:@"u"]; + NSString* pass = [self copyStringFromTXTDict:dict which:@"p"]; + + NSString* portStr = @""; + + // Note that [NSNetService port:] returns an NSInteger in host byte order + NSInteger port = [service port]; + if (port != 0 && port != 80) + portStr = [[NSString alloc] initWithFormat:@":%d",port]; + + NSString* path = [self copyStringFromTXTDict:dict which:@"path"]; + if (!path || [path length]==0) { + [path release]; + path = [[NSString alloc] initWithString:@"/"]; + } else if (![[path substringToIndex:1] isEqual:@"/"]) { + NSString *tempPath = [[NSString alloc] initWithFormat:@"/%@",path]; + [path release]; + path = tempPath; + } + + NSString* string = [[NSString alloc] initWithFormat:@"http://%@%@%@%@%@%@%@", + user?user:@"", + pass?@":":@"", + pass?pass:@"", + (user||pass)?@"@":@"", + host, + portStr, + path]; + + NSURL *url = [[NSURL alloc] initWithString:string]; + [[UIApplication sharedApplication] openURL:url]; + + [url release]; + [string release]; + [portStr release]; + [pass release]; + [user release]; + [dict release]; + [path release]; +} + +@end diff --git a/BonjourWeb/Default.png b/BonjourWeb/Default.png new file mode 100644 index 0000000..32ba931 Binary files /dev/null and b/BonjourWeb/Default.png differ diff --git a/BonjourWeb/Icon.png b/BonjourWeb/Icon.png new file mode 100644 index 0000000..300eefb Binary files /dev/null and b/BonjourWeb/Icon.png differ diff --git a/BonjourWeb/Info.plist b/BonjourWeb/Info.plist new file mode 100755 index 0000000..eb1b859 --- /dev/null +++ b/BonjourWeb/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Icon.png + LSRequiresIPhoneOS + true + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.9 + NSMainNibFile + MainWindow + UIPrerenderedIcon + + UIRequiresPersistentWiFi + + + diff --git a/BonjourWeb/ReadMe.txt b/BonjourWeb/ReadMe.txt new file mode 100644 index 0000000..a347b8d --- /dev/null +++ b/BonjourWeb/ReadMe.txt @@ -0,0 +1,105 @@ +BonjourWeb + +=========================================================================== +DESCRIPTION: + +Shows how to find network services that are advertised by Bonjour. + +This application illustrates the fundamentals of browsing for network services using Bonjour. The BonjourBrowser hierarchically displays Bonjour domains and services as table views in a navigation controller. The contents of the table views are discovered and updated dynamically using NSNetServiceBrowser objects. Tapping an item in the services table causes the corresponding NSNetService object to be resolved asynchronously. When that resolution completes, a delegate method is called which constructs a URL and opens it in Safari. + +=========================================================================== +BUILD REQUIREMENTS + +iOS SDK 4.0 + +=========================================================================== +RUNTIME REQUIREMENTS + +iOS 4.0 + +=========================================================================== +PACKAGING LIST + +Classes/BonjourWebAppDelegate.h +Classes/BonjourWebAppDelegate.m +The application delegate. +It creates, displays and is the delegate for a BonjourBrowser. +When it gets the delegate callback, it constructs and launches a URL in Safari. + +main.m +Standard application entry point. + +BonjourSupport/BonjourBrowser.h +BonjourSupport/BonjourBrowser.m +A subclass of UINavigationController that handles the UI needed for a user to browse for Bonjour services. +It constructs and displays list view controllers for domains and service instances. + +BonjourSupport/BrowserViewController.h +BonjourSupport/BrowserViewController.m +View controller for the service instance list. +This object manages a NSNetServiceBrowser configured to look for Bonjour services. +It has an array of NSNetService objects that are displayed in a table view. +When the service browser reports that it has discovered a service, the corresponding NSNetService is added to the array. +When a service goes away, the corresponding NSNetService is removed from the array. +Selecting an item in the table view asynchronously resolves the corresponding net service. +When that resolution completes, the delegate is called with the corresponding net service. + +BonjourSupport/DomainViewController.h +BonjourSupport/DomainViewController.m +View controller for the domain list. +This object manages a NSNetServiceBrowser configured to look for Bonjour domains. +It has two arrays of NSString objects that are displayed in two sections of a table view. +When the service browser reports that it has discovered a domain, that domain is added to the first array. +When a domain goes away it is removed from the first array. +It allows the user to add/remove their own domains from the second array, which is displayed in the second section of the table. +When an item in the table view is selected, the delegate is called with the corresponding domain. + +BonjourSupport/SimpleEditViewController.h +BonjourSupport/SimpleEditViewController.m +View controller which allows the user to enter a small amount of text. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS + +Version 2.9 +- Updated to work with iOS SDK 4.0. + +Version 2.8 +- Fixed bug updating cells when all services are removed during a resolve. + +Version 2.7 +- Fixed table selection bug when no services are listed. + +Version 2.6 +- Upgraded for 3.0 SDK due to deprecated APIs; in "cellForRowAtIndexPath" it now uses UITableViewCell's initWithStyle. + +Version 2.5 +- Updated for and tested with iPhone OS 2.0. First public release. + +Version 2.4 +- Updated for Beta 7. +- Significant code changes that adopt Bonjour best practices. + +Version 2.3 +- Updated for Beta 6. +- Added LSRequiresIPhoneOS key to Info.plist. + +Version 2.2 +- Updated for Beta 5. +- Converted from CFNetService/CFNetServiceBrowser to NSNetService and NSNetServiceBrowser. + +Version 2.1 +- Updated for Beta 4. Added code signing. + +Version 2.0 +- Removed check for kCFNetServiceFlagIsDomain flag as BrowserViewController only browses for services. +- Changed code so that the application now: +-- Updates the UI only once there are no more add/remove events coming. +-- Starts the resolve after the selection has changed rather than before it changes. +-- Takes into account the port number and the various fields from the TXT record when constructing the URL. +-- Asynchronously resolves services; the user should control cancelation, rather than an arbitrary timeout. +-- Shows the network status activity indicator when resolving +-- Uses a nib file for the main window. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/BonjourWeb/en.lproj/Localizable.strings b/BonjourWeb/en.lproj/Localizable.strings new file mode 100644 index 0000000..7a044f6 Binary files /dev/null and b/BonjourWeb/en.lproj/Localizable.strings differ diff --git a/BonjourWeb/en.lproj/MainWindow.xib b/BonjourWeb/en.lproj/MainWindow.xib new file mode 100755 index 0000000..1d65e87 --- /dev/null +++ b/BonjourWeb/en.lproj/MainWindow.xib @@ -0,0 +1,170 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 268 + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 6 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 2 + + + + + 3 + + + BonjourWebAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + {{460, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + BonjourWebAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 6 + + + + YES + + BonjourWebAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/BonjourWebAppDelegate.h + + + + + 0 + BonjourWeb.xcodeproj + 3 + + diff --git a/BonjourWeb/main.m b/BonjourWeb/main.m new file mode 100755 index 0000000..8ee9828 --- /dev/null +++ b/BonjourWeb/main.m @@ -0,0 +1,59 @@ +/* + + File: main.m +Abstract: The main entry point for the BonjourWeb application + + Version: 2.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/DateCell.zip b/DateCell.zip new file mode 100644 index 0000000..f48f3af Binary files /dev/null and b/DateCell.zip differ diff --git a/DateCell/AppDelegate.h b/DateCell/AppDelegate.h new file mode 100755 index 0000000..4b5a5f9 --- /dev/null +++ b/DateCell/AppDelegate.h @@ -0,0 +1,61 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for installing our navigation controller. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class MyTableViewController; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navController; + +@end diff --git a/DateCell/AppDelegate.m b/DateCell/AppDelegate.m new file mode 100755 index 0000000..e69a3ea --- /dev/null +++ b/DateCell/AppDelegate.m @@ -0,0 +1,71 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for installing our navigation controller. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MyTableViewController.h" + +@implementation AppDelegate; + +@synthesize window, navController; + +- (void)dealloc +{ + [navController release]; + [window release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + [window addSubview:navController.view]; + + [window makeKeyAndVisible]; +} + +@end diff --git a/DateCell/DateCell.xcodeproj/project.pbxproj b/DateCell/DateCell.xcodeproj/project.pbxproj new file mode 100755 index 0000000..7c89ec9 --- /dev/null +++ b/DateCell/DateCell.xcodeproj/project.pbxproj @@ -0,0 +1,311 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF30D9C4D1A00F143AD /* AppDelegate.m */; }; + 53198DAB0F7ADD8E00E6403A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53198DAA0F7ADD8E00E6403A /* CoreGraphics.framework */; }; + 531F3BDE0F7D65AD00705AB5 /* TableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 531F3BDC0F7D65AD00705AB5 /* TableViewController.xib */; }; + 53A7B2750E311095003A40F3 /* MyTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A7B2730E311095003A40F3 /* MyTableViewController.m */; }; + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EACC050DDA319F00908D73 /* MainWindow.xib */; }; + 7E37055B11CAC1C800F5DB11 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37055611CAC1C800F5DB11 /* Icon-Small.png */; }; + 7E37055C11CAC1C800F5DB11 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37055711CAC1C800F5DB11 /* Icon-Small@2x.png */; }; + 7E37055D11CAC1C800F5DB11 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37055811CAC1C800F5DB11 /* Icon.png */; }; + 7E37055E11CAC1C800F5DB11 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37055911CAC1C800F5DB11 /* Icon@2x.png */; }; + 7E37055F11CAC1C800F5DB11 /* iTunesArtwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37055A11CAC1C800F5DB11 /* iTunesArtwork.png */; }; + 7E3705FC11CAC66500F5DB11 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E3705FB11CAC66500F5DB11 /* Default.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* DateCell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DateCell.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53095FEF0D9C4D0500F143AD /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 53198DAA0F7ADD8E00E6403A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 531F3BDD0F7D65AD00705AB5 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TableViewController.xib; sourceTree = ""; }; + 53A42B810E8A976E00A08910 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 53A7B2730E311095003A40F3 /* MyTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTableViewController.m; sourceTree = ""; }; + 53A7B2740E311095003A40F3 /* MyTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTableViewController.h; sourceTree = ""; }; + 53EACC060DDA319F00908D73 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 7E37055611CAC1C800F5DB11 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + 7E37055711CAC1C800F5DB11 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + 7E37055811CAC1C800F5DB11 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + 7E37055911CAC1C800F5DB11 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + 7E37055A11CAC1C800F5DB11 /* iTunesArtwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iTunesArtwork.png; path = Images/iTunesArtwork.png; sourceTree = ""; }; + 7E3705FB11CAC66500F5DB11 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Images/Default.png; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 53198DAB0F7ADD8E00E6403A /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* DateCell.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53A42B810E8A976E00A08910 /* ReadMe.txt */, + 53AF8AEC0D9C50B700726DBA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 7E3703DF11CA98C900F5DB11 /* Images */, + 8D1107310486CEB800E47090 /* Info.plist */, + 53EACC050DDA319F00908D73 /* MainWindow.xib */, + 531F3BDC0F7D65AD00705AB5 /* TableViewController.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 53198DAA0F7ADD8E00E6403A /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53AF8AEC0D9C50B700726DBA /* Sources */ = { + isa = PBXGroup; + children = ( + 53095FEF0D9C4D0500F143AD /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */, + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */, + 53A7B2740E311095003A40F3 /* MyTableViewController.h */, + 53A7B2730E311095003A40F3 /* MyTableViewController.m */, + ); + name = Sources; + sourceTree = ""; + }; + 7E3703DF11CA98C900F5DB11 /* Images */ = { + isa = PBXGroup; + children = ( + 7E3705FB11CAC66500F5DB11 /* Default.png */, + 7E37055611CAC1C800F5DB11 /* Icon-Small.png */, + 7E37055711CAC1C800F5DB11 /* Icon-Small@2x.png */, + 7E37055811CAC1C800F5DB11 /* Icon.png */, + 7E37055911CAC1C800F5DB11 /* Icon@2x.png */, + 7E37055A11CAC1C800F5DB11 /* iTunesArtwork.png */, + ); + name = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* DateCell */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DateCell" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DateCell; + productName = IBTest; + productReference = 1D6058910D05DD3D006BFB54 /* DateCell.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DateCell" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* DateCell */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */, + 531F3BDE0F7D65AD00705AB5 /* TableViewController.xib in Resources */, + 7E37055B11CAC1C800F5DB11 /* Icon-Small.png in Resources */, + 7E37055C11CAC1C800F5DB11 /* Icon-Small@2x.png in Resources */, + 7E37055D11CAC1C800F5DB11 /* Icon.png in Resources */, + 7E37055E11CAC1C800F5DB11 /* Icon@2x.png in Resources */, + 7E37055F11CAC1C800F5DB11 /* iTunesArtwork.png in Resources */, + 7E3705FC11CAC66500F5DB11 /* Default.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */, + 53A7B2750E311095003A40F3 /* MyTableViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 531F3BDC0F7D65AD00705AB5 /* TableViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 531F3BDD0F7D65AD00705AB5 /* en */, + ); + name = TableViewController.xib; + sourceTree = ""; + }; + 53EACC050DDA319F00908D73 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53EACC060DDA319F00908D73 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = DateCell; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = DateCell; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DateCell" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DateCell" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/DateCell/Images/Default.png b/DateCell/Images/Default.png new file mode 100644 index 0000000..f186cd2 Binary files /dev/null and b/DateCell/Images/Default.png differ diff --git a/DateCell/Images/Icon-Small.png b/DateCell/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/DateCell/Images/Icon-Small.png differ diff --git a/DateCell/Images/Icon-Small@2x.png b/DateCell/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/DateCell/Images/Icon-Small@2x.png differ diff --git a/DateCell/Images/Icon.png b/DateCell/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/DateCell/Images/Icon.png differ diff --git a/DateCell/Images/Icon@2x.png b/DateCell/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/DateCell/Images/Icon@2x.png differ diff --git a/DateCell/Images/iTunesArtwork.png b/DateCell/Images/iTunesArtwork.png new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/DateCell/Images/iTunesArtwork.png differ diff --git a/DateCell/Info.plist b/DateCell/Info.plist new file mode 100755 index 0000000..2c31d2a --- /dev/null +++ b/DateCell/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Icon.png + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + NSMainNibFile + MainWindow + LSRequiresIPhoneOS + + + diff --git a/DateCell/MyTableViewController.h b/DateCell/MyTableViewController.h new file mode 100644 index 0000000..8c4a652 --- /dev/null +++ b/DateCell/MyTableViewController.h @@ -0,0 +1,70 @@ +/* + File: MyTableViewController.h + Abstract: The main table view controller of this app. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface MyTableViewController : UITableViewController +{ +@private + UIDatePicker *pickerView; + UIBarButtonItem *doneButton; // this button appears only when the date picker is open + + NSArray *dataArray; + + NSDateFormatter *dateFormatter; +} + +@property (nonatomic, retain) IBOutlet UIDatePicker *pickerView; +@property (nonatomic, retain) IBOutlet UIBarButtonItem *doneButton; + +@property (nonatomic, retain) NSArray *dataArray; +@property (nonatomic, retain) NSDateFormatter *dateFormatter; + +- (IBAction)doneAction:(id)sender; // when the done button is clicked +- (IBAction)dateAction:(id)sender; // when the user has changed the date picke values (m/d/y) + +@end diff --git a/DateCell/MyTableViewController.m b/DateCell/MyTableViewController.m new file mode 100644 index 0000000..8706896 --- /dev/null +++ b/DateCell/MyTableViewController.m @@ -0,0 +1,192 @@ +/* + File: MyTableViewController.m + Abstract: The main table view controller of this app. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyTableViewController.h" + +@implementation MyTableViewController + +@synthesize pickerView, doneButton, dataArray, dateFormatter; + +- (void)viewDidLoad +{ + self.dataArray = [NSArray arrayWithObjects:@"Start Date", @"End Date", nil]; + + self.dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; + [self.dateFormatter setDateStyle:NSDateFormatterShortStyle]; + [self.dateFormatter setTimeStyle:NSDateFormatterNoStyle]; +} + +- (void)viewDidUnload +{ + self.dataArray = nil; + self.dateFormatter = nil; +} + +- (void)dealloc +{ + [doneButton release]; + [dataArray release]; + [pickerView release]; + [dateFormatter release]; + + [super dealloc]; +} + + +#pragma mark - UITableView delegate methods + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.dataArray count]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *targetCell = [tableView cellForRowAtIndexPath:indexPath]; + self.pickerView.date = [self.dateFormatter dateFromString:targetCell.detailTextLabel.text]; + + // check if our date picker is already on screen + if (self.pickerView.superview == nil) + { + [self.view.window addSubview: self.pickerView]; + + // size up the picker view to our screen and compute the start/end frame origin for our slide up animation + // + // compute the start frame + CGRect screenRect = [[UIScreen mainScreen] applicationFrame]; + CGSize pickerSize = [self.pickerView sizeThatFits:CGSizeZero]; + CGRect startRect = CGRectMake(0.0, + screenRect.origin.y + screenRect.size.height, + pickerSize.width, pickerSize.height); + self.pickerView.frame = startRect; + + // compute the end frame + CGRect pickerRect = CGRectMake(0.0, + screenRect.origin.y + screenRect.size.height - pickerSize.height, + pickerSize.width, + pickerSize.height); + // start the slide up animation + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:0.3]; + + // we need to perform some post operations after the animation is complete + [UIView setAnimationDelegate:self]; + + self.pickerView.frame = pickerRect; + + // shrink the table vertical size to make room for the date picker + CGRect newFrame = self.tableView.frame; + newFrame.size.height -= self.pickerView.frame.size.height; + self.tableView.frame = newFrame; + [UIView commitAnimations]; + + // add the "Done" button to the nav bar + self.navigationItem.rightBarButtonItem = self.doneButton; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kCustomCellID = @"CustomCellID"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCustomCellID]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCustomCellID] autorelease]; + } + + cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row]; + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:[NSDate date]]; + + return cell; +} + +- (void)slideDownDidStop +{ + // the date picker has finished sliding downwards, so remove it + [self.pickerView removeFromSuperview]; +} + +- (IBAction)dateAction:(id)sender +{ + NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:self.pickerView.date]; +} + +- (IBAction)doneAction:(id)sender +{ + CGRect screenRect = [[UIScreen mainScreen] applicationFrame]; + CGRect endFrame = self.pickerView.frame; + endFrame.origin.y = screenRect.origin.y + screenRect.size.height; + + // start the slide down animation + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:0.3]; + + // we need to perform some post operations after the animation is complete + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(slideDownDidStop)]; + + self.pickerView.frame = endFrame; + [UIView commitAnimations]; + + // grow the table back again in vertical size to make room for the date picker + CGRect newFrame = self.tableView.frame; + newFrame.size.height += self.pickerView.frame.size.height; + self.tableView.frame = newFrame; + + // remove the "Done" button in the nav bar + self.navigationItem.rightBarButtonItem = nil; + + // deselect the current table row + NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +@end + diff --git a/DateCell/Prefix.pch b/DateCell/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/DateCell/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/DateCell/ReadMe.txt b/DateCell/ReadMe.txt new file mode 100644 index 0000000..cbdf81c --- /dev/null +++ b/DateCell/ReadMe.txt @@ -0,0 +1,44 @@ +DateCell + +Demonstrates formatted display of date objects in table cells and use of UIDatePicker to edit those values. + +Using a grouped style UITableViewController, the sample has two UITableViewCells to draw the primary title and NSDate values. +This is accomplished using the built-in cell type "UITableViewCellStyleValue1" which supports left and right text. +As a delegate to this table, the sample uses the method "didSelectRowAtIndexPath" to open the UIDatePicker control. +UIViewAnimation is used for sliding the picker up on-screen and down off-screen. +The action method of the UIDatePicker will directly set the NSDate property of the custom table cell. +The Done button is a UIBarButton item set as the "rightBarButtonItem" of the navigation controller and it set only when the picker is open. +In addition, this sample shows how to use NSDateFormatter class to achieve the custom cell's date-formatted appearance. + + +Build Requirements: +iOS SDK 4.0 + +Runtime Requirements: +iOS 4.0 + + +Using the Sample +Launch the DateCell project using Xcode. + +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. +When launched launched, touch the Start Date cell to change its value. A UIDatePicker view will slide onto the screen from the bottom. +As you pick the month, day, year components on the picker, the cell's date changes on-the-fly. + +You can click the Done button to finish the edit which will dismiss the picker as it slides down off screen. +The targeted cell will become deselected. In addition while the picker is open, you can also freely tap between both Start and End dates to change their values. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application's delegate to setup its window and content. +MyTableViewController.h/.m - The main UITableViewController controlling the table and date picker. + + +Changes from Previous Versions +1.1 - Upgraded project to build with the iOS 4 SDK. + +1.0 - First release. + + +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/DateCell/en.lproj/MainWindow.xib b/DateCell/en.lproj/MainWindow.xib new file mode 100644 index 0000000..9f60617 --- /dev/null +++ b/DateCell/en.lproj/MainWindow.xib @@ -0,0 +1,362 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + 292 + {320, 216} + NO + YES + YES + 0 + 0 + 1 + + en_US + + + America/Los_Angeles + + VFppZgAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAC5AAAABAAAABCepkign7sVkKCGKqChmveQ +y4kaoNIj9HDSYSYQ1v50INiArZDa/tGg28CQENzes6DdqayQ3r6VoN+JjpDgnneg4WlwkOJ+WaDjSVKQ +5F47oOUpNJDmR1gg5xJREOgnOiDo8jMQ6gccIOrSFRDr5v4g7LH3EO3G4CDukdkQ76/8oPBxuxDxj96g +8n/BkPNvwKD0X6OQ9U+ioPY/hZD3L4Sg+CiiEPkPZqD6CIQQ+viDIPvoZhD82GUg/chIEP64RyD/qCoQ +AJgpIAGIDBACeAsgA3EokARhJ6AFUQqQBkEJoAcw7JAHjUOgCRDOkAmtvyAK8LCQC+CvoAzZzRANwJGg +DrmvEA+priAQmZEQEYmQIBJ5cxATaXIgFFlVEBVJVCAWOTcQFyk2IBgiU5AZCRggGgI1kBryNKAb4heQ +HNIWoB3B+ZAesfigH6HbkCB2KyAhgb2QIlYNICNq2hAkNe8gJUq8ECYV0SAnKp4QJ/7toCkKgBAp3s+g +KupiECu+saAs036QLZ6ToC6zYJAvfnWgMJNCkDFnkiAycySQM0d0IDRTBpA1J1YgNjLokDcHOCA4HAUQ +OOcaIDn75xA6xvwgO9vJEDywGKA9u6sQPo/6oD+bjRBAb9ygQYSpkEJPvqBDZIuQRC+goEVEbZBF89Mg +Ry2KEEfTtSBJDWwQSbOXIErtThBLnLOgTNZqkE18laBOtkyQT1x3oFCWLpBRPFmgUnYQkFMcO6BUVfKQ +VPwdoFY11JBW5TogWB7xEFjFHCBZ/tMQWqT+IFvetRBchOAgXb6XEF5kwiBfnnkQYE3eoGGHlZBiLcCg +Y2d3kGQNoqBlR1mQZe2EoGcnO5BnzWagaQcdkGmtSKBq5v+Qa5ZlIGzQHBBtdkcgbq/+EG9WKSBwj+AQ +cTYLIHJvwhBzFe0gdE+kEHT/CaB2OMCQdt7roHgYopB4vs2gefiEkHqer6B72GaQfH6RoH24SJB+XnOg +f5gqkAABAAECAwEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA +AQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA +AQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA +AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA + + + 5 + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + DateCell + + + TableViewController + + + + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + pickerView + + + + 61 + + + + navController + + + + 67 + + + + dateAction: + + + 13 + + 74 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 60 + + + + + 62 + + + YES + + + + + + + 64 + + + + + 55 + + + YES + + + + MyTableViewController + + + 66 + + + YES + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 55.CustomClassName + 55.IBEditorWindowLastContentRect + 55.IBPluginDependency + 60.IBEditorWindowLastContentRect + 60.IBPluginDependency + 62.IBEditorWindowLastContentRect + 62.IBPluginDependency + 64.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyTableViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{0, 779}, {320, 216}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 75 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + MyTableViewController + UITableViewController + + YES + + YES + dateAction: + doneAction: + + + YES + id + id + + + + YES + + YES + doneButton + pickerView + + + YES + UIBarButtonItem + UIDatePicker + + + + IBProjectSource + MyTableViewController.h + + + + + 0 + ../DateCell.xcodeproj + 3 + + diff --git a/DateCell/en.lproj/TableViewController.xib b/DateCell/en.lproj/TableViewController.xib new file mode 100644 index 0000000..1545b6f --- /dev/null +++ b/DateCell/en.lproj/TableViewController.xib @@ -0,0 +1,425 @@ + + + + 1024 + 10D573 + 788 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 117 + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {320, 416} + + 10 + + 549453824 + {84, 1} + + + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + YES + NO + IBCocoaTouchFramework + 1 + 1 + 0 + YES + 44 + 27 + 27 + + + Done + IBCocoaTouchFramework + 2 + + + + + + + view + + + + 5 + + + + doneButton + + + + 7 + + + + doneAction: + + + + 8 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + 6 + + + + + + + MyTableViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 8 + + + + + MyTableViewController + UITableViewController + + id + id + + + + dateAction: + id + + + doneAction: + id + + + + UIBarButtonItem + UIDatePicker + + + + doneButton + UIBarButtonItem + + + pickerView + UIDatePicker + + + + IBProjectSource + MyTableViewController.h + + + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIDatePicker + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIDatePicker.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + ../DateCell.xcodeproj + 3 + 117 + + diff --git a/DateCell/main.m b/DateCell/main.m new file mode 100755 index 0000000..a68080b --- /dev/null +++ b/DateCell/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Implementation of the standard main function for iPhone OS applications. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/DateSectionTitles.zip b/DateSectionTitles.zip new file mode 100644 index 0000000..458c7a8 Binary files /dev/null and b/DateSectionTitles.zip differ diff --git a/DateSectionTitles/Classes/DateSectionTitlesAppDelegate.h b/DateSectionTitles/Classes/DateSectionTitlesAppDelegate.h new file mode 100644 index 0000000..4c220ca --- /dev/null +++ b/DateSectionTitles/Classes/DateSectionTitlesAppDelegate.h @@ -0,0 +1,67 @@ + +/* + File: DateSectionTitlesAppDelegate.h + Abstract: Table view controller to display Events by section. + The application delegate is almost unchanged from that provided by the standard Xcode template, except that application data is created in the persistentStoreCoordinator method. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface DateSectionTitlesAppDelegate : NSObject { + + NSManagedObjectModel *managedObjectModel; + NSManagedObjectContext *managedObjectContext; + NSPersistentStoreCoordinator *persistentStoreCoordinator; + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +- (NSString *)applicationDocumentsDirectory; + +@end + diff --git a/DateSectionTitles/Classes/DateSectionTitlesAppDelegate.m b/DateSectionTitles/Classes/DateSectionTitlesAppDelegate.m new file mode 100644 index 0000000..4c55c90 --- /dev/null +++ b/DateSectionTitles/Classes/DateSectionTitlesAppDelegate.m @@ -0,0 +1,214 @@ + +/* + File: DateSectionTitlesAppDelegate.m + Abstract: Table view controller to display Events by section. + The application delegate is almost unchanged from that provided by the standard Xcode template, except that application data is created in the persistentStoreCoordinator method. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "DateSectionTitlesAppDelegate.h" +#import "RootViewController.h" + +#import "Event.h" + +@interface DateSectionTitlesAppDelegate (CoreDateStack) +@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; +@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; +@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; +@end + + +@implementation DateSectionTitlesAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + RootViewController *rootViewController = (RootViewController *)[navigationController topViewController]; + rootViewController.managedObjectContext = self.managedObjectContext; + + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + + NSError *error = nil; + if (managedObjectContext != nil) { + if ([managedObjectContext hasChanges] && ![managedObjectContext 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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. + */ + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } + } +} + + +#pragma mark - +#pragma mark Core Data stack + +- (NSManagedObjectContext *) managedObjectContext { + + if (managedObjectContext != nil) { + return managedObjectContext; + } + + NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; + if (coordinator != nil) { + managedObjectContext = [[NSManagedObjectContext alloc] init]; + [managedObjectContext setPersistentStoreCoordinator: coordinator]; + } + return managedObjectContext; +} + + +- (NSManagedObjectModel *)managedObjectModel { + + if (managedObjectModel != nil) { + return managedObjectModel; + } + managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; + return managedObjectModel; +} + + +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { + + if (persistentStoreCoordinator != nil) { + return persistentStoreCoordinator; + } + + NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"DateSectionTitles.sqlite"]]; + + + BOOL firstRun = NO; + if (![[NSFileManager defaultManager] fileExistsAtPath:[storeUrl path] isDirectory:NULL]) { + firstRun = YES; + } + + NSError *error = nil; + persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; + if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. + */ + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } + + /* + If this is the first run, populate a new store with events whose timestamps are spaced every 7 days throughout 2009. + */ + if (firstRun) { + NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; + [context setPersistentStoreCoordinator:persistentStoreCoordinator]; + + NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; + [dateComponents setYear:2009]; + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; + + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSInteger day; + + for (day = 1; day < 365; day += 7) { + + [dateComponents setDay:day]; + NSDate *date = [calendar dateFromComponents:dateComponents]; + + Event *newEvent = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context]; + newEvent.timeStamp = date; + newEvent.title = [NSString stringWithFormat:@"%@ (day %d)", [dateFormatter stringFromDate:date], [dateComponents day]]; + } + + [context save:NULL]; + + [context release]; + [dateComponents release]; + } + + return persistentStoreCoordinator; +} + + +#pragma mark - +#pragma mark Application's Documents directory + +- (NSString *)applicationDocumentsDirectory { + return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + + [managedObjectContext release]; + [managedObjectModel release]; + [persistentStoreCoordinator release]; + + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/DateSectionTitles/Classes/Event.h b/DateSectionTitles/Classes/Event.h new file mode 100644 index 0000000..df53186 --- /dev/null +++ b/DateSectionTitles/Classes/Event.h @@ -0,0 +1,74 @@ + +/* + File: Event.h + Abstract: Custom class for the Event entity. + + The timeStamp and title are persistent attributes; the sectionIdentifier is transient and derived from timeStamp. + * timeStamp is the date on which the event occurred. + * title is displayed in the table view rows. + When the default data is created in the application delegate, the title is initialized to a string representation of the date. + * sectionIdentifier is used to divide the events into sections in the table view. + sectionIdentifier is a string value representing the number ((year * 1000) + month). Using this value, events can be correctly ordered and grouped regardless of the actual name of the month. It is calculated and cached on demand in the custom accessor method. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface Event : NSManagedObject { +} + +@property (nonatomic, retain) NSString *title; + +@property (nonatomic, retain) NSDate *timeStamp; +@property (nonatomic, retain) NSDate *primitiveTimeStamp; + +@property (nonatomic, retain) NSString *sectionIdentifier; +@property (nonatomic, retain) NSString *primitiveSectionIdentifier; + +@end + + + diff --git a/DateSectionTitles/Classes/Event.m b/DateSectionTitles/Classes/Event.m new file mode 100644 index 0000000..898b1c7 --- /dev/null +++ b/DateSectionTitles/Classes/Event.m @@ -0,0 +1,112 @@ + +/* + File: Event.m + Abstract: Custom class for the Event entity. + + The timeStamp and title are persistent attributes; the sectionIdentifier is transient and derived from timeStamp. + * timeStamp is the date on which the event occurred. + * title is displayed in the table view rows. + When the default data is created in the application delegate, the title is initialized to a string representation of the date. + * sectionIdentifier is used to divide the events into sections in the table view. + sectionIdentifier is a string value representing the number ((year * 1000) + month). Using this value, events can be correctly ordered and grouped regardless of the actual name of the month. It is calculated and cached on demand in the custom accessor method. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Event.h" + +@implementation Event + +@dynamic title, timeStamp, primitiveTimeStamp, sectionIdentifier, primitiveSectionIdentifier; + + +#pragma mark - +#pragma mark Transient properties + +- (NSString *)sectionIdentifier { + + // Create and cache the section identifier on demand. + + [self willAccessValueForKey:@"sectionIdentifier"]; + NSString *tmp = [self primitiveSectionIdentifier]; + [self didAccessValueForKey:@"sectionIdentifier"]; + + if (!tmp) { + /* + Sections are organized by month and year. Create the section identifier as a string representing the number (year * 1000) + month; this way they will be correctly ordered chronologically regardless of the actual name of the month. + */ + NSCalendar *calendar = [NSCalendar currentCalendar]; + + NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[self timeStamp]]; + tmp = [NSString stringWithFormat:@"%d", ([components year] * 1000) + [components month]]; + [self setPrimitiveSectionIdentifier:tmp]; + } + return tmp; +} + + +#pragma mark - +#pragma mark Time stamp setter + +- (void)setTimeStamp:(NSDate *)newDate { + + // If the time stamp changes, the section identifier become invalid. + [self willChangeValueForKey:@"timeStamp"]; + [self setPrimitiveTimeStamp:newDate]; + [self didChangeValueForKey:@"timeStamp"]; + + [self setPrimitiveSectionIdentifier:nil]; +} + + +#pragma mark - +#pragma mark Key path dependencies + ++ (NSSet *)keyPathsForValuesAffectingSectionIdentifier { + // If the value of timeStamp changes, the section identifier may change as well. + return [NSSet setWithObject:@"timeStamp"]; +} + + +@end diff --git a/DateSectionTitles/Classes/RootViewController.h b/DateSectionTitles/Classes/RootViewController.h new file mode 100644 index 0000000..aad21fc --- /dev/null +++ b/DateSectionTitles/Classes/RootViewController.h @@ -0,0 +1,58 @@ + +/* + File: RootViewController.h + Abstract: Table view controller to display Events by section. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface RootViewController : UITableViewController { + NSFetchedResultsController *fetchedResultsController; + NSManagedObjectContext *managedObjectContext; +} + +@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; +@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; + +@end diff --git a/DateSectionTitles/Classes/RootViewController.m b/DateSectionTitles/Classes/RootViewController.m new file mode 100644 index 0000000..c80117c --- /dev/null +++ b/DateSectionTitles/Classes/RootViewController.m @@ -0,0 +1,203 @@ + +/* + File: RootViewController.m + Abstract: Table view controller to display Events by section. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "Event.h" + + +@implementation RootViewController + +@synthesize fetchedResultsController, managedObjectContext; + + +#pragma mark - +#pragma mark View lifecycle + + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = @"Events"; + NSError *error = nil; + if (![[self 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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. + */ + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } +} + + +#pragma mark - +#pragma mark Table view methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + + NSInteger count = [[fetchedResultsController sections] count]; + return count; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; + + NSInteger count = [sectionInfo numberOfObjects]; + return count; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + /* + Use a default table view cell to display the event's title. + */ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; + } + + Event *event = [fetchedResultsController objectAtIndexPath:indexPath]; + cell.textLabel.text = event.title; + + return cell; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + + id theSection = [[fetchedResultsController sections] objectAtIndex:section]; + + /* + Section information derives from an event's sectionIdentifier, which is a string representing the number (year * 1000) + month. + To display the section title, convert the year and month components to a string representation. + */ + static NSArray *monthSymbols = nil; + + if (!monthSymbols) { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setCalendar:[NSCalendar currentCalendar]]; + monthSymbols = [[formatter monthSymbols] retain]; + [formatter release]; + } + + NSInteger numericSection = [[theSection name] integerValue]; + + NSInteger year = numericSection / 1000; + NSInteger month = numericSection - (year * 1000); + + NSString *titleString = [NSString stringWithFormat:@"%@ %d", [monthSymbols objectAtIndex:month-1], year]; + + return titleString; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +#pragma mark - +#pragma mark Fetched results controller + +- (NSFetchedResultsController *)fetchedResultsController { + + if (fetchedResultsController != nil) { + return fetchedResultsController; + } + + /* + Set up the fetched results controller. + */ + // Create the fetch request for the entity. + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + // Edit the entity name as appropriate. + NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext]; + [fetchRequest setEntity:entity]; + + // Set the batch size to a suitable number. + [fetchRequest setFetchBatchSize:20]; + + // Sort using the timeStamp property.. + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; + + [fetchRequest setSortDescriptors:sortDescriptors]; + + // Use the sectionIdentifier property to group into sections. + NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"sectionIdentifier" cacheName:@"Root"]; + aFetchedResultsController.delegate = self; + self.fetchedResultsController = aFetchedResultsController; + + [aFetchedResultsController release]; + [fetchRequest release]; + [sortDescriptor release]; + [sortDescriptors release]; + + return fetchedResultsController; +} + + +#pragma mark - +#pragma mark Memory management + + +- (void)dealloc { + [fetchedResultsController release]; + [managedObjectContext release]; + [super dealloc]; +} + + +@end + diff --git a/DateSectionTitles/DateSectionTitles-Info.plist b/DateSectionTitles/DateSectionTitles-Info.plist new file mode 100644 index 0000000..73a625e --- /dev/null +++ b/DateSectionTitles/DateSectionTitles-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/DateSectionTitles/DateSectionTitles.xcdatamodel/elements b/DateSectionTitles/DateSectionTitles.xcdatamodel/elements new file mode 100644 index 0000000..0271f3f Binary files /dev/null and b/DateSectionTitles/DateSectionTitles.xcdatamodel/elements differ diff --git a/DateSectionTitles/DateSectionTitles.xcdatamodel/layout b/DateSectionTitles/DateSectionTitles.xcdatamodel/layout new file mode 100644 index 0000000..af5941e Binary files /dev/null and b/DateSectionTitles/DateSectionTitles.xcdatamodel/layout differ diff --git a/DateSectionTitles/DateSectionTitles.xcodeproj/project.pbxproj b/DateSectionTitles/DateSectionTitles.xcodeproj/project.pbxproj new file mode 100755 index 0000000..b7dcfea --- /dev/null +++ b/DateSectionTitles/DateSectionTitles.xcodeproj/project.pbxproj @@ -0,0 +1,323 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 186FBDB011CACAEE000061EC /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 186FBDAB11CACAEE000061EC /* Icon-Small.png */; }; + 186FBDB111CACAEE000061EC /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 186FBDAC11CACAEE000061EC /* Icon-Small@2x.png */; }; + 186FBDB211CACAEE000061EC /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 186FBDAD11CACAEE000061EC /* Icon.png */; }; + 186FBDB311CACAEE000061EC /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 186FBDAE11CACAEE000061EC /* Icon@2x.png */; }; + 186FBE5411CADABD000061EC /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 186FBE5011CADABD000061EC /* MainWindow.xib */; }; + 186FBE5511CADABD000061EC /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 186FBE5211CADABD000061EC /* RootViewController.xib */; }; + 18A6153111D416E40078F8B4 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18A6152E11D416E40078F8B4 /* Icon-72.png */; }; + 18A6153211D416E40078F8B4 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18A6152F11D416E40078F8B4 /* Icon-Small-50.png */; }; + 18A6153311D416E40078F8B4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18A6153011D416E40078F8B4 /* iTunesArtwork */; }; + 1D3623260D0F684500981E51 /* DateSectionTitlesAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* DateSectionTitlesAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2827E62F110192F900AF0069 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2827E62E110192F900AF0069 /* ReadMe.txt */; }; + 28860B770F44E54D00985440 /* DateSectionTitles.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 28860B760F44E54D00985440 /* DateSectionTitles.xcdatamodel */; }; + 28860BE50F44EE6400985440 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28860BE40F44EE6400985440 /* CoreData.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + 28D3EB4D1102C2C300C4B25E /* Event.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D3EB4C1102C2C300C4B25E /* Event.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 186FBDAB11CACAEE000061EC /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 186FBDAC11CACAEE000061EC /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 186FBDAD11CACAEE000061EC /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 186FBDAE11CACAEE000061EC /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 186FBE5111CADABD000061EC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 186FBE5311CADABD000061EC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; + 18A6152E11D416E40078F8B4 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18A6152F11D416E40078F8B4 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18A6153011D416E40078F8B4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* DateSectionTitlesAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateSectionTitlesAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* DateSectionTitlesAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateSectionTitlesAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* DateSectionTitles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DateSectionTitles.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2827E62E110192F900AF0069 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 28860B760F44E54D00985440 /* DateSectionTitles.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = DateSectionTitles.xcdatamodel; sourceTree = ""; }; + 28860BE40F44EE6400985440 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* DateSectionTitles_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateSectionTitles_Prefix.pch; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28D3EB4B1102C2C300C4B25E /* Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; + 28D3EB4C1102C2C300C4B25E /* Event.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Event.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* DateSectionTitles-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "DateSectionTitles-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + 28860BE50F44EE6400985440 /* CoreData.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28D3EB4B1102C2C300C4B25E /* Event.h */, + 28D3EB4C1102C2C300C4B25E /* Event.m */, + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + 1D3623240D0F684500981E51 /* DateSectionTitlesAppDelegate.h */, + 1D3623250D0F684500981E51 /* DateSectionTitlesAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* DateSectionTitles.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2827E62E110192F900AF0069 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* DateSectionTitles_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18A6152E11D416E40078F8B4 /* Icon-72.png */, + 18A6152F11D416E40078F8B4 /* Icon-Small-50.png */, + 18A6153011D416E40078F8B4 /* iTunesArtwork */, + 186FBE5011CADABD000061EC /* MainWindow.xib */, + 186FBE5211CADABD000061EC /* RootViewController.xib */, + 186FBDAB11CACAEE000061EC /* Icon-Small.png */, + 186FBDAC11CACAEE000061EC /* Icon-Small@2x.png */, + 186FBDAD11CACAEE000061EC /* Icon.png */, + 186FBDAE11CACAEE000061EC /* Icon@2x.png */, + 28860B760F44E54D00985440 /* DateSectionTitles.xcdatamodel */, + 8D1107310486CEB800E47090 /* DateSectionTitles-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + 28860BE40F44EE6400985440 /* CoreData.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* DateSectionTitles */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DateSectionTitles" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DateSectionTitles; + productName = DateSectionTitles; + productReference = 1D6058910D05DD3D006BFB54 /* DateSectionTitles.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DateSectionTitles" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* DateSectionTitles */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2827E62F110192F900AF0069 /* ReadMe.txt in Resources */, + 186FBDB011CACAEE000061EC /* Icon-Small.png in Resources */, + 186FBDB111CACAEE000061EC /* Icon-Small@2x.png in Resources */, + 186FBDB211CACAEE000061EC /* Icon.png in Resources */, + 186FBDB311CACAEE000061EC /* Icon@2x.png in Resources */, + 186FBE5411CADABD000061EC /* MainWindow.xib in Resources */, + 186FBE5511CADABD000061EC /* RootViewController.xib in Resources */, + 18A6153111D416E40078F8B4 /* Icon-72.png in Resources */, + 18A6153211D416E40078F8B4 /* Icon-Small-50.png in Resources */, + 18A6153311D416E40078F8B4 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* DateSectionTitlesAppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + 28860B770F44E54D00985440 /* DateSectionTitles.xcdatamodel in Sources */, + 28D3EB4D1102C2C300C4B25E /* Event.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 186FBE5011CADABD000061EC /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 186FBE5111CADABD000061EC /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 186FBE5211CADABD000061EC /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 186FBE5311CADABD000061EC /* en */, + ); + name = RootViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = DateSectionTitles_Prefix.pch; + INFOPLIST_FILE = "DateSectionTitles-Info.plist"; + PRODUCT_NAME = DateSectionTitles; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = DateSectionTitles_Prefix.pch; + INFOPLIST_FILE = "DateSectionTitles-Info.plist"; + PRODUCT_NAME = DateSectionTitles; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DateSectionTitles" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DateSectionTitles" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/DateSectionTitles/DateSectionTitles_Prefix.pch b/DateSectionTitles/DateSectionTitles_Prefix.pch new file mode 100644 index 0000000..2b55dfd --- /dev/null +++ b/DateSectionTitles/DateSectionTitles_Prefix.pch @@ -0,0 +1,58 @@ +/* + File: DateSectionTitles_Prefix.pch + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +// +// Prefix header for all source files of the 'DateSectionTitles' target in the 'DateSectionTitles' project +// + +#import + +#ifdef __OBJC__ + #import + #import + #import +#endif diff --git a/DateSectionTitles/ReadMe.txt b/DateSectionTitles/ReadMe.txt new file mode 100644 index 0000000..ca81f00 --- /dev/null +++ b/DateSectionTitles/ReadMe.txt @@ -0,0 +1,55 @@ + +### DateSectionTitles ### + +=========================================================================== +DESCRIPTION: + +This application shows how to create section information for NSFetchedResultsController using dates. + +A single table view controller displays events sorted by date and grouped into sections by year and month. The Event entity has three attributes: +* timeStamp (persistent NSDate object). + The time stamp represents the time the event occurred. +* title (persistent NSString object). + The title of each event as it will be displayed on a row in the table view (this is not to be confused with section title). When the default data is created in the application delegate, the title is initialized to a string representation of the date. +* sectionIdentifier (transient NSString object). + The sectionIdentifier is used to divide the events into sections in the table view. It is a string value representing the number ((year * 1000) + month). Using this value, events can be correctly ordered chronologically regardless of the actual name of the month. It is calculated and cached on demand in the custom accessor method. + +The sorting is all done at fetch time by the fetched results controller. The section name transformations are UI level and have no effect on the order of data. + + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST: + +DateSectionTitlesAppDelegate.{h,m} +Application delegate that configures the Core Data stack. + +RootViewController.{h,m} +A table view controller that presents events by section. + +Event.{h,m} +A managed object class to represent an event in time. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.2 +- Changed deployment target back to iPhone OS 3.2 and added CFBundleIconFiles in Info.plist. + +Version 1.1 +- Upgraded project to build with the iOS 4 SDK. + +Version 1.0 +- First version. + +=========================================================================== +Copyright (C) 2009-2010 Apple Inc. All rights reserved. diff --git a/DateSectionTitles/en.lproj/MainWindow.xib b/DateSectionTitles/en.lproj/MainWindow.xib new file mode 100644 index 0000000..7d43793 --- /dev/null +++ b/DateSectionTitles/en.lproj/MainWindow.xib @@ -0,0 +1,272 @@ + + + + 784 + 10A398 + 732 + 1029 + 431.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 60 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + + + RootViewController + + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DateSectionTitlesAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 15 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + DateSectionTitlesAppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + Classes/DateSectionTitlesAppDelegate.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + DateSectionTitles.xcodeproj + 3 + 3.1 + + diff --git a/DateSectionTitles/en.lproj/RootViewController.xib b/DateSectionTitles/en.lproj/RootViewController.xib new file mode 100644 index 0000000..220e94f --- /dev/null +++ b/DateSectionTitles/en.lproj/RootViewController.xib @@ -0,0 +1,380 @@ + + + + 784 + 10A405 + 732 + 1031 + 432.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + {320, 247} + + + 3 + MQA + + NO + YES + NO + NO + 1 + 0 + YES + 44 + 22 + 22 + + + + + YES + + + view + + + + 3 + + + + dataSource + + + + 4 + + + + delegate + + + + 5 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + + + YES + RootViewController + UIResponder + {{0, 598}, {320, 247}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 5 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + DateSectionTitles.xcodeproj + 3 + 3.1 + + diff --git a/DateSectionTitles/images/Icon-72.png b/DateSectionTitles/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/DateSectionTitles/images/Icon-72.png differ diff --git a/DateSectionTitles/images/Icon-Small-50.png b/DateSectionTitles/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/DateSectionTitles/images/Icon-Small-50.png differ diff --git a/DateSectionTitles/images/Icon-Small.png b/DateSectionTitles/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/DateSectionTitles/images/Icon-Small.png differ diff --git a/DateSectionTitles/images/Icon-Small@2x.png b/DateSectionTitles/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/DateSectionTitles/images/Icon-Small@2x.png differ diff --git a/DateSectionTitles/images/Icon.png b/DateSectionTitles/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/DateSectionTitles/images/Icon.png differ diff --git a/DateSectionTitles/images/Icon@2x.png b/DateSectionTitles/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/DateSectionTitles/images/Icon@2x.png differ diff --git a/DateSectionTitles/images/iTunesArtwork b/DateSectionTitles/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/DateSectionTitles/images/iTunesArtwork differ diff --git a/DateSectionTitles/main.m b/DateSectionTitles/main.m new file mode 100644 index 0000000..23256dc --- /dev/null +++ b/DateSectionTitles/main.m @@ -0,0 +1,58 @@ + +/* + File: main.m + Abstract: Standard main.m file. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/EADemo.zip b/EADemo.zip new file mode 100644 index 0000000..deedb73 Binary files /dev/null and b/EADemo.zip differ diff --git a/EADemo/EADSessionController.h b/EADemo/EADSessionController.h new file mode 100644 index 0000000..88e4a36 --- /dev/null +++ b/EADemo/EADSessionController.h @@ -0,0 +1,80 @@ +/* + + File: EADSessionController.h + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import +#import + +extern NSString *EADSessionDataReceivedNotification; + +// NOTE: EADSessionController is not threadsafe, calling methods from different threads will lead to unpredictable results +@interface EADSessionController : NSObject { + EAAccessory *_accessory; + EASession *_session; + NSString *_protocolString; + + NSMutableData *_writeData; + NSMutableData *_readData; +} + ++ (EADSessionController *)sharedController; + +- (void)setupControllerForAccessory:(EAAccessory *)accessory withProtocolString:(NSString *)protocolString; + +- (BOOL)openSession; +- (void)closeSession; + +- (void)writeData:(NSData *)data; + +- (NSUInteger)readBytesAvailable; +- (NSData *)readData:(NSUInteger)bytesToRead; + +@property (nonatomic, readonly) EAAccessory *accessory; +@property (nonatomic, readonly) NSString *protocolString; + +@end diff --git a/EADemo/EADSessionController.m b/EADemo/EADSessionController.m new file mode 100644 index 0000000..63ac72d --- /dev/null +++ b/EADemo/EADSessionController.m @@ -0,0 +1,227 @@ +/* + + File: EADSessionController.m + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import "EADSessionController.h" + +NSString *EADSessionDataReceivedNotification = @"EADSessionDataReceivedNotification"; + +@implementation EADSessionController + +@synthesize accessory = _accessory; +@synthesize protocolString = _protocolString; + +#pragma mark Internal + +// low level write method - write data to the accessory while there is space available and data to write +- (void)_writeData { + while (([[_session outputStream] hasSpaceAvailable]) && ([_writeData length] > 0)) + { + NSInteger bytesWritten = [[_session outputStream] write:[_writeData bytes] maxLength:[_writeData length]]; + if (bytesWritten == -1) + { + NSLog(@"write error"); + break; + } + else if (bytesWritten > 0) + { + [_writeData replaceBytesInRange:NSMakeRange(0, bytesWritten) withBytes:NULL length:0]; + } + } +} + +// low level read method - read data while there is data and space available in the input buffer +- (void)_readData { +#define EAD_INPUT_BUFFER_SIZE 128 + uint8_t buf[EAD_INPUT_BUFFER_SIZE]; + while ([[_session inputStream] hasBytesAvailable]) + { + NSInteger bytesRead = [[_session inputStream] read:buf maxLength:EAD_INPUT_BUFFER_SIZE]; + if (_readData == nil) { + _readData = [[NSMutableData alloc] init]; + } + [_readData appendBytes:(void *)buf length:bytesRead]; + //NSLog(@"read %d bytes from input stream", bytesRead); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:EADSessionDataReceivedNotification object:self userInfo:nil]; +} + +#pragma mark Public Methods + ++ (EADSessionController *)sharedController +{ + static EADSessionController *sessionController = nil; + if (sessionController == nil) { + sessionController = [[EADSessionController alloc] init]; + } + + return sessionController; +} + +- (void)dealloc +{ + [self closeSession]; + [self setupControllerForAccessory:nil withProtocolString:nil]; + + [super dealloc]; +} + +// initialize the accessory with the protocolString +- (void)setupControllerForAccessory:(EAAccessory *)accessory withProtocolString:(NSString *)protocolString +{ + [_accessory release]; + _accessory = [accessory retain]; + [_protocolString release]; + _protocolString = [protocolString copy]; +} + +// open a session with the accessory and set up the input and output stream on the default run loop +- (BOOL)openSession +{ + [_accessory setDelegate:self]; + _session = [[EASession alloc] initWithAccessory:_accessory forProtocol:_protocolString]; + + if (_session) + { + [[_session inputStream] setDelegate:self]; + [[_session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [[_session inputStream] open]; + + [[_session outputStream] setDelegate:self]; + [[_session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [[_session outputStream] open]; + } + else + { + NSLog(@"creating session failed"); + } + + return (_session != nil); +} + +// close the session with the accessory. +- (void)closeSession +{ + [[_session inputStream] close]; + [[_session inputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [[_session inputStream] setDelegate:nil]; + [[_session outputStream] close]; + [[_session outputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [[_session outputStream] setDelegate:nil]; + + [_session release]; + _session = nil; + + [_writeData release]; + _writeData = nil; + [_readData release]; + _readData = nil; +} + +// high level write data method +- (void)writeData:(NSData *)data +{ + if (_writeData == nil) { + _writeData = [[NSMutableData alloc] init]; + } + + [_writeData appendData:data]; + [self _writeData]; +} + +// high level read method +- (NSData *)readData:(NSUInteger)bytesToRead +{ + NSData *data = nil; + if ([_readData length] >= bytesToRead) { + NSRange range = NSMakeRange(0, bytesToRead); + data = [_readData subdataWithRange:range]; + [_readData replaceBytesInRange:range withBytes:NULL length:0]; + } + return data; +} + +// get number of bytes read into local buffer +- (NSUInteger)readBytesAvailable +{ + return [_readData length]; +} + +#pragma mark EAAccessoryDelegate +- (void)accessoryDidDisconnect:(EAAccessory *)accessory +{ + // do something ... +} + +#pragma mark NSStreamDelegateEventExtensions + +// asynchronous NSStream handleEvent method +- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode +{ + switch (eventCode) { + case NSStreamEventNone: + break; + case NSStreamEventOpenCompleted: + break; + case NSStreamEventHasBytesAvailable: + [self _readData]; + break; + case NSStreamEventHasSpaceAvailable: + [self _writeData]; + break; + case NSStreamEventErrorOccurred: + break; + case NSStreamEventEndEncountered: + break; + default: + break; + } +} + +@end diff --git a/EADemo/EADSessionTransferViewController.h b/EADemo/EADSessionTransferViewController.h new file mode 100644 index 0000000..8abe60f --- /dev/null +++ b/EADemo/EADSessionTransferViewController.h @@ -0,0 +1,72 @@ +/* + + File: EADSessionTransferViewController.h + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import + +@interface EADSessionTransferViewController : UIViewController { + EAAccessory *_accessory; + UILabel *_receivedBytesLabel; + UITextField *_stringToSendTextField; + UITextField *_hexToSendTextField; + + uint32_t _totalBytesRead; +} + +- (IBAction)sendString:(id)sender; +- (IBAction)sendHex:(id)sender; +- (IBAction)send10K:(id)sender; + +// UITextFieldDelegate +- (BOOL)textFieldShouldReturn:(UITextField *)textField; + +@property(nonatomic, retain) IBOutlet UILabel *receivedBytesLabel; +@property(nonatomic, retain) IBOutlet UITextField *stringToSendTextField; +@property(nonatomic, retain) IBOutlet UITextField *hexToSendTextField; + +@end diff --git a/EADemo/EADSessionTransferViewController.m b/EADemo/EADSessionTransferViewController.m new file mode 100644 index 0000000..61d1f34 --- /dev/null +++ b/EADemo/EADSessionTransferViewController.m @@ -0,0 +1,200 @@ +/* + + File: EADSessionTransferViewController.m + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import "EADSessionTransferViewController.h" +#import "EADSessionController.h" + +@implementation EADSessionTransferViewController + +@synthesize + receivedBytesLabel = _receivedBytesLabel, + stringToSendTextField = _stringToSendTextField, + hexToSendTextField = _hexToSendTextField; + +// send test string to the accessory +- (IBAction)sendString:(id)sender; +{ + if ([_stringToSendTextField isFirstResponder]) { + [_stringToSendTextField resignFirstResponder]; + } + + const char *buf = [[_stringToSendTextField text] UTF8String]; + if (buf) + { + uint32_t len = strlen(buf) + 1; + [[EADSessionController sharedController] writeData:[NSData dataWithBytes:buf length:len]]; + } +} + +// Interpret a UITextField's string at a sequence of hex bytes and send those bytes to the accessory +- (IBAction)sendHex:(id)sender; +{ + if ([_hexToSendTextField isFirstResponder]) { + [_hexToSendTextField resignFirstResponder]; + } + + const char *buf = [[_hexToSendTextField text] UTF8String]; + NSMutableData *data = [NSMutableData data]; + if (buf) + { + uint32_t len = strlen(buf); + + char singleNumberString[3] = {'\0', '\0', '\0'}; + uint32_t singleNumber = 0; + for(uint32_t i = 0 ; i < len; i+=2) + { + if ( ((i+1) < len) && isxdigit(buf[i]) && (isxdigit(buf[i+1])) ) + { + singleNumberString[0] = buf[i]; + singleNumberString[1] = buf[i + 1]; + sscanf(singleNumberString, "%x", &singleNumber); + uint8_t tmp = (uint8_t)(singleNumber & 0x000000FF); + [data appendBytes:(void *)(&tmp) length:1]; + } + else + { + break; + } + } + + [[EADSessionController sharedController] writeData:data]; + } +} + +// send 10K of data to the accessory. +- (IBAction)send10K:(id)sender +{ +#define STRESS_TEST_BYTE_COUNT 10000 + uint8_t buf[STRESS_TEST_BYTE_COUNT]; + for(int i = 0; i < STRESS_TEST_BYTE_COUNT; i++) { + buf[i] = (i & 0xFF); // fill buf with incrementing bytes; + } + + [[EADSessionController sharedController] writeData:[NSData dataWithBytes:buf length:STRESS_TEST_BYTE_COUNT]]; +} + +#pragma mark UIViewController + +- (void)viewWillAppear:(BOOL)animated +{ + // watch for the accessory being disconnected + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidDisconnect:) name:EAAccessoryDidDisconnectNotification object:nil]; + // watch for received data from the accessory + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_sessionDataReceived:) name:EADSessionDataReceivedNotification object:nil]; + + EADSessionController *sessionController = [EADSessionController sharedController]; + + _accessory = [[sessionController accessory] retain]; + [self setTitle:[sessionController protocolString]]; + [sessionController openSession]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + // remove the observers + [[NSNotificationCenter defaultCenter] removeObserver:self name:EAAccessoryDidConnectNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:EADSessionDataReceivedNotification object:nil]; + + EADSessionController *sessionController = [EADSessionController sharedController]; + + [sessionController closeSession]; + [_accessory release]; + _accessory = nil; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + self.receivedBytesLabel = nil; + self.stringToSendTextField = nil; + self.hexToSendTextField = nil; +} + +#pragma mark UITextFieldDelegate + +- (BOOL)textFieldShouldReturn:(UITextField *)textField +{ + [textField resignFirstResponder]; + return YES; +} + +#pragma mark Internal + +- (void)_accessoryDidDisconnect:(NSNotification *)notification +{ + if ([[self navigationController] topViewController] == self) + { + EAAccessory *disconnectedAccessory = [[notification userInfo] objectForKey:EAAccessoryKey]; + if ([disconnectedAccessory connectionID] == [_accessory connectionID]) + { + [[self navigationController] popViewControllerAnimated:YES]; + + } + } +} + +// Data was received from the accessory, real apps should do something with this data but currently: +// 1. bytes counter is incremented +// 2. bytes are read from the session controller and thrown away +- (void)_sessionDataReceived:(NSNotification *)notification +{ + EADSessionController *sessionController = (EADSessionController *)[notification object]; + uint32_t bytesAvailable = 0; + + while ((bytesAvailable = [sessionController readBytesAvailable]) > 0) { + NSData *data = [sessionController readData:bytesAvailable]; + if (data) { + _totalBytesRead += bytesAvailable; + } + } + + [_receivedBytesLabel setText:[NSString stringWithFormat:@"Bytes Received from Session: %d", _totalBytesRead]]; +} + +@end diff --git a/EADemo/EADemo-Info.plist b/EADemo/EADemo-Info.plist new file mode 100644 index 0000000..dadc8a4 --- /dev/null +++ b/EADemo/EADemo-Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + UISupportedExternalAccessoryProtocols + + com.apple.p1 + com.apple.p2 + + + diff --git a/EADemo/EADemo.xcodeproj/project.pbxproj b/EADemo/EADemo.xcodeproj/project.pbxproj new file mode 100755 index 0000000..ac456bd --- /dev/null +++ b/EADemo/EADemo.xcodeproj/project.pbxproj @@ -0,0 +1,345 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 30631982106F42E500DAD121 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 30631981106F42E500DAD121 /* ReadMe.txt */; }; + 3087049811912FC700E6E8E0 /* EADSessionTransfer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3087049211912FC700E6E8E0 /* EADSessionTransfer.xib */; }; + 3087049911912FC700E6E8E0 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3087049411912FC700E6E8E0 /* MainWindow.xib */; }; + 3087049A11912FC700E6E8E0 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3087049611912FC700E6E8E0 /* RootViewController.xib */; }; + 309BCA6D11DB0A0E000B4574 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 309BCA6611DB0A0E000B4574 /* Icon-72.png */; }; + 309BCA6E11DB0A0E000B4574 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 309BCA6711DB0A0E000B4574 /* Icon-Small-50.png */; }; + 309BCA6F11DB0A0E000B4574 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 309BCA6811DB0A0E000B4574 /* Icon-Small.png */; }; + 309BCA7011DB0A0E000B4574 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 309BCA6911DB0A0E000B4574 /* Icon-Small@2x.png */; }; + 309BCA7111DB0A0E000B4574 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 309BCA6A11DB0A0E000B4574 /* Icon.png */; }; + 309BCA7211DB0A0E000B4574 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 309BCA6B11DB0A0E000B4574 /* Icon@2x.png */; }; + 30B3DE3311ED1F7700C12546 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 30B3DE3211ED1F7700C12546 /* iTunesArtwork */; }; + C952826C0FB397D500E6CF4C /* ExternalAccessory.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C952826B0FB397D500E6CF4C /* ExternalAccessory.framework */; }; + C986345C0FB66A2200D461F2 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C986345A0FB66A2200D461F2 /* RootViewController.m */; }; + C986345F0FB66A3500D461F2 /* EADemoAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C986345E0FB66A3500D461F2 /* EADemoAppDelegate.m */; }; + C9E1AAB6104EBA61002BECB8 /* EADSessionController.m in Sources */ = {isa = PBXBuildFile; fileRef = C9E1AAB5104EBA61002BECB8 /* EADSessionController.m */; }; + C9E1AB2E104EF18F002BECB8 /* EADSessionTransferViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C9E1AB2D104EF18F002BECB8 /* EADSessionTransferViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* EADemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EADemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* EADemo_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EADemo_Prefix.pch; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 30631981106F42E500DAD121 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 3087049311912FC700E6E8E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/EADSessionTransfer.xib; sourceTree = ""; }; + 3087049511912FC700E6E8E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 3087049711912FC700E6E8E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; + 309BCA6611DB0A0E000B4574 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 309BCA6711DB0A0E000B4574 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 309BCA6811DB0A0E000B4574 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 309BCA6911DB0A0E000B4574 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 309BCA6A11DB0A0E000B4574 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 309BCA6B11DB0A0E000B4574 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 30B3DE3211ED1F7700C12546 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* EADemo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "EADemo-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + C952826B0FB397D500E6CF4C /* ExternalAccessory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExternalAccessory.framework; path = System/Library/Frameworks/ExternalAccessory.framework; sourceTree = SDKROOT; }; + C98634590FB66A2200D461F2 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + C986345A0FB66A2200D461F2 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + C986345D0FB66A3500D461F2 /* EADemoAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EADemoAppDelegate.h; sourceTree = ""; }; + C986345E0FB66A3500D461F2 /* EADemoAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EADemoAppDelegate.m; sourceTree = ""; }; + C9E1AAB4104EBA61002BECB8 /* EADSessionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EADSessionController.h; sourceTree = ""; }; + C9E1AAB5104EBA61002BECB8 /* EADSessionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EADSessionController.m; sourceTree = ""; }; + C9E1AB2C104EF18F002BECB8 /* EADSessionTransferViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EADSessionTransferViewController.h; sourceTree = ""; }; + C9E1AB2D104EF18F002BECB8 /* EADSessionTransferViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EADSessionTransferViewController.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + C952826C0FB397D500E6CF4C /* ExternalAccessory.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* EADemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + C9E1AAB4104EBA61002BECB8 /* EADSessionController.h */, + C9E1AAB5104EBA61002BECB8 /* EADSessionController.m */, + C986345D0FB66A3500D461F2 /* EADemoAppDelegate.h */, + C986345E0FB66A3500D461F2 /* EADemoAppDelegate.m */, + C98631FD0FB4B35000D461F2 /* ViewControllers */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 309BCA6511DB0A0E000B4574 /* Resources */, + 28A0AAE50D9B0CCF005BE974 /* EADemo_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 3087049211912FC700E6E8E0 /* EADSessionTransfer.xib */, + 3087049411912FC700E6E8E0 /* MainWindow.xib */, + 3087049611912FC700E6E8E0 /* RootViewController.xib */, + 8D1107310486CEB800E47090 /* EADemo-Info.plist */, + 30631981106F42E500DAD121 /* ReadMe.txt */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + C952826B0FB397D500E6CF4C /* ExternalAccessory.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 309BCA6511DB0A0E000B4574 /* Resources */ = { + isa = PBXGroup; + children = ( + 309BCA6611DB0A0E000B4574 /* Icon-72.png */, + 309BCA6711DB0A0E000B4574 /* Icon-Small-50.png */, + 309BCA6811DB0A0E000B4574 /* Icon-Small.png */, + 309BCA6911DB0A0E000B4574 /* Icon-Small@2x.png */, + 309BCA6A11DB0A0E000B4574 /* Icon.png */, + 309BCA6B11DB0A0E000B4574 /* Icon@2x.png */, + 30B3DE3211ED1F7700C12546 /* iTunesArtwork */, + ); + path = Resources; + sourceTree = ""; + }; + C98631FD0FB4B35000D461F2 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + C98634590FB66A2200D461F2 /* RootViewController.h */, + C986345A0FB66A2200D461F2 /* RootViewController.m */, + C9E1AB2C104EF18F002BECB8 /* EADSessionTransferViewController.h */, + C9E1AB2D104EF18F002BECB8 /* EADSessionTransferViewController.m */, + ); + name = ViewControllers; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* EADemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "EADemo" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = EADemo; + productName = EADemo; + productReference = 1D6058910D05DD3D006BFB54 /* EADemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "EADemo" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* EADemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 30631982106F42E500DAD121 /* ReadMe.txt in Resources */, + 3087049811912FC700E6E8E0 /* EADSessionTransfer.xib in Resources */, + 3087049911912FC700E6E8E0 /* MainWindow.xib in Resources */, + 3087049A11912FC700E6E8E0 /* RootViewController.xib in Resources */, + 309BCA6D11DB0A0E000B4574 /* Icon-72.png in Resources */, + 309BCA6E11DB0A0E000B4574 /* Icon-Small-50.png in Resources */, + 309BCA6F11DB0A0E000B4574 /* Icon-Small.png in Resources */, + 309BCA7011DB0A0E000B4574 /* Icon-Small@2x.png in Resources */, + 309BCA7111DB0A0E000B4574 /* Icon.png in Resources */, + 309BCA7211DB0A0E000B4574 /* Icon@2x.png in Resources */, + 30B3DE3311ED1F7700C12546 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + C986345C0FB66A2200D461F2 /* RootViewController.m in Sources */, + C986345F0FB66A3500D461F2 /* EADemoAppDelegate.m in Sources */, + C9E1AAB6104EBA61002BECB8 /* EADSessionController.m in Sources */, + C9E1AB2E104EF18F002BECB8 /* EADSessionTransferViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 3087049211912FC700E6E8E0 /* EADSessionTransfer.xib */ = { + isa = PBXVariantGroup; + children = ( + 3087049311912FC700E6E8E0 /* en */, + ); + name = EADSessionTransfer.xib; + sourceTree = ""; + }; + 3087049411912FC700E6E8E0 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 3087049511912FC700E6E8E0 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 3087049611912FC700E6E8E0 /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 3087049711912FC700E6E8E0 /* en */, + ); + name = RootViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = EADemo_Prefix.pch; + INFOPLIST_FILE = "EADemo-Info.plist"; + PRODUCT_NAME = EADemo; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = EADemo_Prefix.pch; + INFOPLIST_FILE = "EADemo-Info.plist"; + PRODUCT_NAME = EADemo; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "ARCHS[sdk=iphoneos*]" = "$(ARCHS_STANDARD_32_BIT)"; + "ARCHS[sdk=iphonesimulator*]" = i386; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + PRODUCT_NAME = EADemo; + SDKROOT = iphoneos4.0; + TARGETED_DEVICE_FAMILY = 1; + VALID_ARCHS = "armv7 armv6"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "ARCHS[sdk=iphoneos*]" = "$(ARCHS_STANDARD_32_BIT)"; + "ARCHS[sdk=iphonesimulator*]" = i386; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + PRODUCT_NAME = EADemo; + SDKROOT = iphoneos4.0; + TARGETED_DEVICE_FAMILY = 1; + VALID_ARCHS = "armv7 armv6"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "EADemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "EADemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/EADemo/EADemoAppDelegate.h b/EADemo/EADemoAppDelegate.h new file mode 100644 index 0000000..6cacb51 --- /dev/null +++ b/EADemo/EADemoAppDelegate.h @@ -0,0 +1,60 @@ +/* + + File: EADemoAppDelegate.h + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +@interface EADemoAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +@end + diff --git a/EADemo/EADemoAppDelegate.m b/EADemo/EADemoAppDelegate.m new file mode 100644 index 0000000..acf4ed4 --- /dev/null +++ b/EADemo/EADemoAppDelegate.m @@ -0,0 +1,79 @@ +/* + + File: EADemoAppDelegate.m + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import "EADemoAppDelegate.h" +#import "RootViewController.h" + + +@implementation EADemoAppDelegate + +@synthesize window; +@synthesize navigationController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after app launch + + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Save data if appropriate +} + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/EADemo/EADemo_Prefix.pch b/EADemo/EADemo_Prefix.pch new file mode 100644 index 0000000..3cc6840 --- /dev/null +++ b/EADemo/EADemo_Prefix.pch @@ -0,0 +1,13 @@ +// +// Prefix header for all source files of the 'EADemo' target in the 'EADemo' project +// +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iOS SDK 3.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/EADemo/ReadMe.txt b/EADemo/ReadMe.txt new file mode 100644 index 0000000..1db5c41 --- /dev/null +++ b/EADemo/ReadMe.txt @@ -0,0 +1 @@ +Read Me about EADemo ============================== 1.1 EADemo shows how to communicate from an iOS 3.x application, with an external accessory using the External Accessory (EA) Framework API. The sample can be used with a Made For iPod (MFI) accessory, which supports the iPod Accessory Protocol (see http://developer.apple.com/iphone/program/sdk/accessories.html) designed for use with the ExternalAccessory.framework. The sample is provided to demonstrate the common functions of an EA Framework application. The goal of this sample is to demonstrate the following functions - detect the connections and disconnections of accessories that support EA protocols. - provide a demonstration for communicating with the accessory. EADemo requires iOS 4 or later to run on an iPhone or iPod Touch. EADemo requires iOS 3.2 to run on an iPad. Packing List ------------ The sample contains the following items: o ReadMe.txt -- This file. o EADemo_Prefix.pch -- Prefix header for all source files in the EADemo project. o EADemo.xcodeproj -- An Xcode project for the sample. o EADemo-Info.plist -- The application Info.plist file. o EADSessionController.[hm] -- Provides an interface for communication with an EASession. It is also the delegate for the EASession input and output stream objects. o EADSessionTransferViewController.[hm] -- A view controller to allow transferring data to and from an accessory form the UI. o EADemoAppDelegate.[hm] -- A delegate object for the User Interface. o RootViewController.[hm] -- A table view controller for watching the device come and go. Using the Sample ---------------- The sample can be used with any Made For iPod (MFI) accessory designed for use with the External Accessory Framework. The application will display all attached External Accessories in the "Accessories" table view, provide information registered by the MFI accessory, and provides methods to send and receive data to the accessory. Information about MFI accessories is available to licensees of the MFI program. You can learn more about the MFI program at the Apple Developer Connection "Made For iPod Program" web page . When the MFI accessory is attached, iOS reads the MFI accessory provided information that includes the supported protocol strings. The system searches for a matching protocol string in the UISupportedExternalAccessoryProtocols array of the Info.plist of all the installed applications. If no matching protocol string is found, iOS raises the "Application Not Installed" alert. You can modify the UISupportedExternalAccessoryProtocols property in the EADemo-Info.plist to include the protocol string registered by your accessory, to keep the system from presenting the "Application Not Installed" alert on accessory attachment. At the "Accessories" table view, the name of all attached MFI accessories are displayed. Click on the accessory name to see a list of supported protocols. Select a protocol, and the application will use the protocol to open a session for communication with the accessory. The Protocol table view provides options for three different ways to send data to the accessory. There is also a counter to display the number of bytes received from the accessory. The three buttons and the methods that are called are "Send String" - sendString - sends the string entered in the UITextField it's associated with in the view to the accessory. "Send Hex Data" - sendHex - sends the string entered in the UITextField it's associated with in the view interpreted as a hex byte sequence to the accessory. "Send 10K" - send10K - sends 10K bytes of incrementing 8-bit values (0 to 255) to the accessory. If the accessory is detached, the application will detect this action and reset itself to the main Accessories table view. When no accessory is attached, the main screen will display the message "No Accessories Connected". Building the Sample ------------------- The sample requires Xcode 3.2.3 on Mac OS X 10.6 with iOS 4 SDK. The sample program will run in the Simulator, but there is is no support communicate with real accessories through the simulator. Credits and Version History --------------------------- If you find any problems with this sample, please file a bug against it. Apple Developer Technical Support Core OS/Hardware 10 July 2010 \ No newline at end of file diff --git a/EADemo/Resources/Icon-72.png b/EADemo/Resources/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/EADemo/Resources/Icon-72.png differ diff --git a/EADemo/Resources/Icon-Small-50.png b/EADemo/Resources/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/EADemo/Resources/Icon-Small-50.png differ diff --git a/EADemo/Resources/Icon-Small.png b/EADemo/Resources/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/EADemo/Resources/Icon-Small.png differ diff --git a/EADemo/Resources/Icon-Small@2x.png b/EADemo/Resources/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/EADemo/Resources/Icon-Small@2x.png differ diff --git a/EADemo/Resources/Icon.png b/EADemo/Resources/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/EADemo/Resources/Icon.png differ diff --git a/EADemo/Resources/Icon@2x.png b/EADemo/Resources/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/EADemo/Resources/Icon@2x.png differ diff --git a/EADemo/Resources/iTunesArtwork b/EADemo/Resources/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/EADemo/Resources/iTunesArtwork differ diff --git a/EADemo/RootViewController.h b/EADemo/RootViewController.h new file mode 100644 index 0000000..030492b --- /dev/null +++ b/EADemo/RootViewController.h @@ -0,0 +1,68 @@ +/* + + File: RootViewController.h + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import + +@class EADSessionController; + +@interface RootViewController : UITableViewController { + NSMutableArray *_accessoryList; + + EAAccessory *_selectedAccessory; + EADSessionController *_eaSessionController; + + UIActionSheet *_protocolSelectionActionSheet; + + UIView *_noExternalAccessoriesPosterView; + UILabel *_noExternalAccessoriesLabelView; +} + +// from UIActionSheetDelegate +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex; +@end diff --git a/EADemo/RootViewController.m b/EADemo/RootViewController.m new file mode 100644 index 0000000..3d0d113 --- /dev/null +++ b/EADemo/RootViewController.m @@ -0,0 +1,229 @@ +/* + + File: RootViewController.m + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import "RootViewController.h" +#import "EADSessionTransferViewController.h" +#import "EADSessionController.h" + +#import + +@implementation RootViewController + +- (void)dealloc +{ + [super dealloc]; +} + +- (void)viewDidLoad { + // Create the view that gets shown when no accessories are connected + _noExternalAccessoriesPosterView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + [_noExternalAccessoriesPosterView setBackgroundColor:[UIColor whiteColor]]; + _noExternalAccessoriesLabelView = [[UILabel alloc] initWithFrame:CGRectMake(60, 170, 240, 50)]; + [_noExternalAccessoriesLabelView setText:@"No Accessories Connected"]; + [_noExternalAccessoriesPosterView addSubview:_noExternalAccessoriesLabelView]; + [[self view] addSubview:_noExternalAccessoriesPosterView]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidConnect:) name:EAAccessoryDidConnectNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidDisconnect:) name:EAAccessoryDidDisconnectNotification object:nil]; + [[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications]; + + _eaSessionController = [EADSessionController sharedController]; + _accessoryList = [[NSMutableArray alloc] initWithArray:[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]]; + + [self setTitle:@"Accessories"]; + + if ([_accessoryList count] == 0) { + [_noExternalAccessoriesPosterView setHidden:NO]; + } else { + [_noExternalAccessoriesPosterView setHidden:YES]; + } + + [super viewDidLoad]; +} + +- (void)viewDidUnload { + [[NSNotificationCenter defaultCenter] removeObserver:self name:EAAccessoryDidConnectNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:EAAccessoryDidDisconnectNotification object:nil]; + [_accessoryList release]; + _accessoryList = nil; + + [_selectedAccessory release]; + _selectedAccessory = nil; + + [_protocolSelectionActionSheet release]; + _protocolSelectionActionSheet = nil; + + [_noExternalAccessoriesPosterView release]; + [_noExternalAccessoriesLabelView release]; + + [super viewDidUnload]; +} + +#pragma mark UIActionSheetDelegate methods +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (_selectedAccessory && (buttonIndex >= 0) && (buttonIndex < [[_selectedAccessory protocolStrings] count])) + { + [_eaSessionController setupControllerForAccessory:_selectedAccessory + withProtocolString:[[_selectedAccessory protocolStrings] objectAtIndex:buttonIndex]]; + + EADSessionTransferViewController *sessionTransferViewController = + [[EADSessionTransferViewController alloc] initWithNibName:@"EADSessionTransfer" bundle:nil]; + + [[self navigationController] pushViewController:sessionTransferViewController animated:YES]; + [sessionTransferViewController release]; + } + + [_selectedAccessory release]; + _selectedAccessory = nil; + [_protocolSelectionActionSheet release]; + _protocolSelectionActionSheet = nil; +} + +#pragma mark UITableViewDataSource methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + + +// Customize the number of rows in the table view. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [_accessoryList count]; +} + + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *eaAccessoryCellIdentifier = @"eaAccessoryCellIdentifier"; + NSUInteger row = [indexPath row]; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:eaAccessoryCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:eaAccessoryCellIdentifier] autorelease]; + } + + NSString *eaAccessoryName = [[_accessoryList objectAtIndex:row] name]; + if (!eaAccessoryName || [eaAccessoryName isEqualToString:@""]) { + eaAccessoryName = @"unknown"; + } + + [[cell textLabel] setText:eaAccessoryName]; + + return cell; +} + +#pragma mark UITableViewDelegate methods + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSUInteger row = [indexPath row]; + + _selectedAccessory = [[_accessoryList objectAtIndex:row] retain]; + + _protocolSelectionActionSheet = [[UIActionSheet alloc] initWithTitle:@"Select Protocol" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil]; + NSArray *protocolStrings = [_selectedAccessory protocolStrings]; + for(NSString *protocolString in protocolStrings) { + [_protocolSelectionActionSheet addButtonWithTitle:protocolString]; + } + + [_protocolSelectionActionSheet setCancelButtonIndex:[_protocolSelectionActionSheet addButtonWithTitle:@"Cancel"]]; + [_protocolSelectionActionSheet showInView:[self tableView]]; + + [[self tableView] deselectRowAtIndexPath:indexPath animated:YES]; +} + +#pragma mark Internal + +- (void)_accessoryDidConnect:(NSNotification *)notification { + EAAccessory *connectedAccessory = [[notification userInfo] objectForKey:EAAccessoryKey]; + [_accessoryList addObject:connectedAccessory]; + + if ([_accessoryList count] == 0) { + [_noExternalAccessoriesPosterView setHidden:NO]; + } else { + [_noExternalAccessoriesPosterView setHidden:YES]; + } + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:([_accessoryList count] - 1) inSection:0]; + [[self tableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft]; +} + +- (void)_accessoryDidDisconnect:(NSNotification *)notification { + EAAccessory *disconnectedAccessory = [[notification userInfo] objectForKey:EAAccessoryKey]; + + if (_selectedAccessory && [disconnectedAccessory connectionID] == [_selectedAccessory connectionID]) + { + [_protocolSelectionActionSheet dismissWithClickedButtonIndex:-1 animated:YES]; + } + + int disconnectedAccessoryIndex = 0; + for(EAAccessory *accessory in _accessoryList) { + if ([disconnectedAccessory connectionID] == [accessory connectionID]) { + break; + } + disconnectedAccessoryIndex++; + } + + if (disconnectedAccessoryIndex < [_accessoryList count]) { + [_accessoryList removeObjectAtIndex:disconnectedAccessoryIndex]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:disconnectedAccessoryIndex inSection:0]; + [[self tableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight]; + } else { + NSLog(@"could not find disconnected accessory in accessory list"); + } + + if ([_accessoryList count] == 0) { + [_noExternalAccessoriesPosterView setHidden:NO]; + } else { + [_noExternalAccessoriesPosterView setHidden:YES]; + } +} + +@end diff --git a/EADemo/en.lproj/EADSessionTransfer.xib b/EADemo/en.lproj/EADSessionTransfer.xib new file mode 100644 index 0000000..6dc0883 --- /dev/null +++ b/EADemo/en.lproj/EADSessionTransfer.xib @@ -0,0 +1,676 @@ + + + + 768 + 10A432 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 292 + {{20, 59}, {280, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + Send String + + 3 + MQA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MC41AA + + + + + 292 + {{20, 179}, {280, 37}} + + NO + NO + 0 + 0 + + 1 + Send Hex Data + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 292 + {{20, 282}, {280, 37}} + + NO + NO + 0 + 0 + + 1 + Send 10K + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 292 + {{20, 20}, {280, 31}} + + NO + NO + 0 + + 3 + Enter a string to send + + 3 + MAA + + 2 + + + + Helvetica-Bold + 12 + 16 + + YES + 17 + + 3 + + + + 292 + {{20, 140}, {280, 31}} + + NO + NO + 0 + + 3 + 0123456789ABCDEF + + 3 + MAA + + + YES + 17 + + 3 + + + + 292 + {{20, 253}, {280, 21}} + + NO + YES + NO + Stress Test + + 1 + MCAwIDAAA + + + 1 + 10 + 1 + + + + 292 + {{20, 370}, {280, 21}} + + NO + YES + NO + Bytes Received from Session: 0 + + + 1 + 10 + 1 + + + {320, 460} + + + 3 + MQA + + + + + + + + YES + + + view + + + + 7 + + + + sendString: + + + 7 + + 15 + + + + sendHex: + + + 7 + + 16 + + + + send10K: + + + 7 + + 17 + + + + delegate + + + + 18 + + + + delegate + + + + 19 + + + + stringToSendTextField + + + + 20 + + + + hexToSendTextField + + + + 21 + + + + receivedBytesLabel + + + + 22 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 3 + + + + + 4 + + + + + 8 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBPluginDependency + 3.IBPluginDependency + 4.IBPluginDependency + 8.IBPluginDependency + + + YES + EADSessionTransferViewController + UIResponder + {{393, 183}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 22 + + + + YES + + EADSessionTransferViewController + UIViewController + + YES + + YES + send10K: + sendHex: + sendString: + + + YES + id + id + id + + + + YES + + YES + hexToSendTextField + receivedBytesLabel + stringToSendTextField + + + YES + UITextField + UILabel + UITextField + + + + IBProjectSource + EADSessionTransferViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UITextInput.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextField + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + EADemo.xcodeproj + 3 + 3.1 + + diff --git a/EADemo/en.lproj/MainWindow.xib b/EADemo/en.lproj/MainWindow.xib new file mode 100644 index 0000000..522d304 --- /dev/null +++ b/EADemo/en.lproj/MainWindow.xib @@ -0,0 +1,267 @@ + + + + 768 + 10A288 + 715 + 1010 + 411.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 46 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + + + RootViewController + + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EADemoAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 15 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + EADemoAppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + Classes/EADemoAppDelegate.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + EADemo.xcodeproj + 3 + + diff --git a/EADemo/en.lproj/RootViewController.xib b/EADemo/en.lproj/RootViewController.xib new file mode 100644 index 0000000..02f0ab3 --- /dev/null +++ b/EADemo/en.lproj/RootViewController.xib @@ -0,0 +1,192 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + {320, 416} + + + 3 + MQA + + NO + YES + NO + + + NO + + NO + 1 + 0 + YES + 4.400000e+01 + 2.200000e+01 + 2.200000e+01 + + + + + YES + + + tableView + + + + 10 + + + + view + + + + 11 + + + + dataSource + + + + 12 + + + + delegate + + + + 13 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 9 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + RootViewController + UIResponder + {{236, 337}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 13 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + RootViewController + UITableViewController + + tableView + UITableView + + + IBUserSource + + + + + + 0 + EADemo.xcodeproj + 3 + + diff --git a/EADemo/main.m b/EADemo/main.m new file mode 100644 index 0000000..ed89164 --- /dev/null +++ b/EADemo/main.m @@ -0,0 +1,58 @@ +/* + + File: main.m + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/Formulaic.zip b/Formulaic.zip new file mode 100644 index 0000000..b4ccc08 Binary files /dev/null and b/Formulaic.zip differ diff --git a/Formulaic/Classes/AppDelegate.h b/Formulaic/Classes/AppDelegate.h new file mode 100644 index 0000000..c78063d --- /dev/null +++ b/Formulaic/Classes/AppDelegate.h @@ -0,0 +1,61 @@ +/* + File: AppDelegate.h + Abstract: Application delegate + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +@class ViewController; + +@interface AppDelegate : NSObject +{ +@private + UIWindow *window; + ViewController *viewController; +} + +@property(nonatomic, retain) IBOutlet UIWindow *window; +@property(nonatomic, retain) IBOutlet ViewController *viewController; + +@end + diff --git a/Formulaic/Classes/AppDelegate.m b/Formulaic/Classes/AppDelegate.m new file mode 100644 index 0000000..0d3c74b --- /dev/null +++ b/Formulaic/Classes/AppDelegate.m @@ -0,0 +1,69 @@ +/* + File: AppDelegate.m + Abstract: Application delegate + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "ViewController.h" + +@implementation AppDelegate + +@synthesize window; +@synthesize viewController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; +} + +- (void)dealloc +{ + [viewController release]; + [window release]; + [super dealloc]; +} + +@end diff --git a/Formulaic/Classes/GraphingView.h b/Formulaic/Classes/GraphingView.h new file mode 100644 index 0000000..65d0d62 --- /dev/null +++ b/Formulaic/Classes/GraphingView.h @@ -0,0 +1,61 @@ +/* + File: GraphingView.h + Abstract: Graphing View, the class responsible for drawing the graph, based on the formula + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface GraphingView : UIControl +{ +@private + CAShapeLayer *shapeLayer; + CGFloat formulaConstant; + + NSMutableArray *accessibilityChildren; +} + +@property(assign) CGFloat formulaConstant; + +@end diff --git a/Formulaic/Classes/GraphingView.m b/Formulaic/Classes/GraphingView.m new file mode 100644 index 0000000..d6964c8 --- /dev/null +++ b/Formulaic/Classes/GraphingView.m @@ -0,0 +1,213 @@ +/* + File: GraphingView.m + Abstract: Graphing View, the class responsible for drawing the graph, based on the formula + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "GraphingView.h" +#import "ViewController.h" + +@implementation GraphingView + +@synthesize formulaConstant; + +- (void)dealloc +{ + [accessibilityChildren release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark === Accessibility Container methods === + +// _accessibilityChildren returns the list of "sub-elements" that GraphingView contains +- (NSArray *)_accessibilityChildren +{ + if ( accessibilityChildren != nil ) + { + return accessibilityChildren; + } + + accessibilityChildren = [[NSMutableArray alloc] init]; + + // create an accessibility element to represent the graph + UIAccessibilityElement *graph = [[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self] autorelease]; + graph.accessibilityLabel = @"Graph"; + graph.accessibilityTraits = UIAccessibilityTraitImage; + [accessibilityChildren addObject:graph]; + + // create accessibility elements for each "button" + // assign labels and traits + // add to the children array + + UIAccessibilityElement *button1 = [[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self] autorelease]; + button1.accessibilityLabel = @"f of negative pi over 2"; + button1.accessibilityTraits = UIAccessibilityTraitButton; + [accessibilityChildren addObject:button1]; + + UIAccessibilityElement *button2 = [[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self] autorelease]; + button2.accessibilityLabel = @"f of 0"; + button2.accessibilityTraits = UIAccessibilityTraitButton; + [accessibilityChildren addObject:button2]; + + UIAccessibilityElement *button3 = [[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self] autorelease]; + button3.accessibilityLabel = @"f of pi over 2"; + button3.accessibilityTraits = UIAccessibilityTraitButton; + [accessibilityChildren addObject:button3]; + + // set the frame of each method. + // use this view's accessibilityFrame to base calculations off of + + CGRect frame = [self accessibilityFrame]; + CGFloat height = 40, width = 60; + + button1.accessibilityFrame = CGRectMake(frame.origin.x + 15, CGRectGetMaxY(frame) - height, width, height); + button2.accessibilityFrame = CGRectMake(frame.origin.x + 105, CGRectGetMaxY(frame) - height, width, height); + button3.accessibilityFrame = CGRectMake(frame.origin.x + 190, CGRectGetMaxY(frame) - height, width, height); + graph.accessibilityFrame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height - height); + + return accessibilityChildren; +} + +// if a UIView implements the container protocol, it cannot be an accessible element +- (BOOL)isAccessibilityElement +{ + return NO; +} + +// Accessibility Container protocol methods only need to reference _accessibilityChildren to be complete +- (NSInteger)accessibilityElementCount +{ + return [[self _accessibilityChildren] count]; +} + +- (id)accessibilityElementAtIndex:(NSInteger)index +{ + return [[self _accessibilityChildren] objectAtIndex:index]; +} + +- (NSInteger)indexOfAccessibilityElement:(id)element +{ + return [[self _accessibilityChildren] indexOfObject:element]; +} + +#pragma mark - +#pragma mark === Drawing and layout methods === + +- (void)awakeFromNib +{ + // set up a rounded border + CALayer *layer = [self layer]; + + // clear the view's background color so that our background + // fits within the rounded border + CGColorRef backgroundColor = [self.backgroundColor CGColor]; + self.backgroundColor = [UIColor clearColor]; + layer.backgroundColor = backgroundColor; + + layer.borderColor = [[UIColor blackColor] CGColor]; + layer.borderWidth = 3.0f; + layer.cornerRadius = 4.0f; + + shapeLayer = [CAShapeLayer layer]; + [shapeLayer setFillColor:[[UIColor clearColor] CGColor]]; + [shapeLayer setStrokeColor:[[UIColor whiteColor] CGColor]]; + [shapeLayer setLineCap:kCALineCapRound]; + [shapeLayer setLineWidth:4.0f]; + [layer addSublayer:shapeLayer]; + + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)rect +{ + // draw the "buttons" which are really strings. + [[UIColor whiteColor] set]; + [[NSString stringWithString:@"f(-∏/2)"] drawAtPoint:CGPointMake(CGRectGetMinX(rect) + 20, CGRectGetMaxY(rect) - 30) withFont:[UIFont boldSystemFontOfSize:16]]; + [[NSString stringWithFormat:@"f(0.00)"] drawAtPoint:CGPointMake(CGRectGetMinX(rect) + 110, CGRectGetMaxY(rect) - 30) withFont:[UIFont boldSystemFontOfSize:16]]; + [[NSString stringWithString:@"f(∏/2)"] drawAtPoint:CGPointMake(CGRectGetMinX(rect) + 200, CGRectGetMaxY(rect) - 30) withFont:[UIFont boldSystemFontOfSize:16]]; +} + +- (void)updateGraph +{ + // draw the graph line + CGRect bounds = self.bounds; + CGMutablePathRef path = CGPathCreateMutable(); + + CGFloat startX = CGRectGetMinX(bounds) + 10; + CGFloat width = CGRectGetWidth(bounds) - 20; + + CGFloat startY = CGRectGetMidY(bounds); + CGFloat height = CGRectGetHeight(bounds); + + CGPathMoveToPoint(path, NULL, startX, startY); + CGFloat x; + for ( x = -2*M_PI; x <= 2*M_PI; x += .15 ) + { + // find the value that we will plot + CGFloat fx = formulaConstant * x * sin(x); + + // convert the x value to a x coordinate + CGFloat rectX = (((x + 2*M_PI)/(4*M_PI)) * width) + startX; + + // convert the f(x) value to a y coordinate + CGFloat rectY = ((fx/3) * height) + startY; + + CGPathAddLineToPoint(path, NULL, rectX, rectY); + } + + [shapeLayer setPath:path]; + [shapeLayer setNeedsDisplay]; + CFRelease(path); +} + +- (void)setFormulaConstant:(CGFloat)constant +{ + // alpha as in the alpha of the equation (not opacity alpha) + formulaConstant = constant; + [self updateGraph]; +} + + +@end diff --git a/Formulaic/Classes/TabularDataCell.h b/Formulaic/Classes/TabularDataCell.h new file mode 100644 index 0000000..d2f7810 --- /dev/null +++ b/Formulaic/Classes/TabularDataCell.h @@ -0,0 +1,59 @@ +/* + File: TabularDataCell.h + Abstract: The table cell presenting the formula data in tabular form + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +@interface TabularDataCell : UITableViewCell +{ + UILabel *label1; + UILabel *label2; + NSInteger row; + CGFloat formulaConstant; +} + +@property(assign) NSInteger row; +@property(assign) CGFloat formulaConstant; + +@end diff --git a/Formulaic/Classes/TabularDataCell.m b/Formulaic/Classes/TabularDataCell.m new file mode 100644 index 0000000..93cf240 --- /dev/null +++ b/Formulaic/Classes/TabularDataCell.m @@ -0,0 +1,91 @@ +/* + File: TabularDataCell.m + Abstract: The table cell presenting the formula data in tabular form + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "TabularDataCell.h" + +@implementation TabularDataCell + +@synthesize row; +@synthesize formulaConstant; + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if ( self == nil ) + { + return nil; + } + + label1 = [[UILabel alloc] initWithFrame:CGRectMake(5, 10, 100, 30)]; + [label1 setFont:[UIFont fontWithName:@"Arial" size:14]]; + [self addSubview:label1]; + [label1 release]; + + label2 = [[UILabel alloc] initWithFrame:CGRectMake(105, 10, 100, 30)]; + [label2 setFont:[UIFont fontWithName:@"Courier" size:18]]; + [self addSubview:label2]; + [label2 release]; + + return self; +} + +- (void)setRow:(NSInteger)r +{ + row = r; + + // normalize from r/100 rows to an x value between -2∏ -> 2∏ + CGFloat x = ((row / 100.0) * 4*M_PI) - (2*M_PI); + CGFloat fx = formulaConstant * x * sin(x); + + label1.text = [NSString stringWithFormat:@"f(%.2f) = ",x]; + label2.text = [NSString stringWithFormat:@"%0.5f",fx]; + + // update the accessibility label with an appropriate string representing the data succinctly + [self setAccessibilityLabel:[NSString stringWithFormat:@"f of %.2f equals %.2f",x, fx]]; +} + +@end diff --git a/Formulaic/Classes/ViewController.h b/Formulaic/Classes/ViewController.h new file mode 100644 index 0000000..3610fd4 --- /dev/null +++ b/Formulaic/Classes/ViewController.h @@ -0,0 +1,80 @@ +/* + File: ViewController.h + Abstract: View controller, the main view controller of the app + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "GraphingView.h" + +@interface ViewController : UIViewController +{ +@private + // Main View + IBOutlet GraphingView *graphingView; + IBOutlet UITextField *valueField; + IBOutlet UISlider *slider; + IBOutlet UILabel *resultLabel; + IBOutlet UIButton *stopWatch; + + // Tabular Data slide in view + IBOutlet UIView *tabularDataView; + IBOutlet UITableView *tabularDataTableView; + + BOOL stopWatchStateOn; + BOOL stopWatchDirectionUp; + BOOL shouldUpdateGraph; +} + +- (IBAction)sliderWasChanged:(id)sender; + +- (IBAction)stopWatchButtonWasPressed:(id)sender; +- (IBAction)tableButtonWasPressed:(id)sender; + +- (IBAction)textFieldChanged:(id)sender; +- (IBAction)touchesEndedForGraphingView:(id)sender event:(UIEvent *)event; + +- (IBAction)doneButtonPressed; + +@end + diff --git a/Formulaic/Classes/ViewController.m b/Formulaic/Classes/ViewController.m new file mode 100644 index 0000000..153d145 --- /dev/null +++ b/Formulaic/Classes/ViewController.m @@ -0,0 +1,260 @@ +/* + File: ViewController.m + Abstract: View controller, the main view controller of the app + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "ViewController.h" +#import "TabularDataCell.h" +#import + +@implementation ViewController + +- (void)updateGraphingView +{ + // set the consntant (alpha) value for the graph view + CGFloat value = [valueField.text floatValue]; + + if ( value < slider.minimumValue ) + { + value = slider.minimumValue; + } + else if ( value > slider.maximumValue ) + { + value = slider.maximumValue; + } + + graphingView.formulaConstant = value; +} + +- (void)viewDidLoad +{ + // update the graph view + [self updateGraphingView]; + + // set the hint for the stop watch button + [stopWatch setAccessibilityHint:@"Toggles animation."]; + + // allow updates of graph + shouldUpdateGraph = YES; + + [super viewDidLoad]; +} + +- (void)updateLabel:(NSString *)text +{ + resultLabel.text = text; +} + +- (IBAction)touchesEndedForGraphingView:(id)sender event:(UIEvent *)event +{ + // handle touches in the graph view + CGPoint touchUp = [[[event allTouches] anyObject] locationInView:graphingView]; + if ( touchUp.x < 100 ) + { + [self updateLabel:[NSString stringWithFormat:@"f(%.2f) = %.5f",-M_PI/2, graphingView.formulaConstant * -M_PI/2 * sin(-M_PI/2)]]; + } + else if ( touchUp.x < 200 ) + { + [self updateLabel:[NSString stringWithFormat:@"f(%.2f) = %.5f",0, graphingView.formulaConstant * 0 * sin(0)]]; + } + else if ( touchUp.x < 300 ) + { + [self updateLabel:[NSString stringWithFormat:@"f(%.2f) = %.5f",M_PI/2, graphingView.formulaConstant * M_PI/2 * sin(M_PI/2)]]; + } +} + +- (void)_countdownValue +{ + // update the text field and graph based on whether the stop watch is on or off + if ( !stopWatchStateOn ) + { + return; + } + + CGFloat value = [valueField.text floatValue]; + + if ( value > slider.maximumValue ) + { + stopWatchDirectionUp = NO; + } + else if ( value < slider.minimumValue ) + { + stopWatchDirectionUp = YES; + } + + CGFloat step = .005f; + if ( stopWatchDirectionUp ) + { + value += step; + } + else + { + value -= step; + } + + slider.value = value; + + valueField.text = [NSString stringWithFormat:@"%.5f", value]; + [self updateGraphingView]; + + [self performSelector:@selector(_countdownValue) withObject:nil afterDelay:.02f]; +} + +- (IBAction)stopWatchButtonWasPressed:(id)sender +{ + if ( stopWatchStateOn ) + { + stopWatchStateOn = NO; + [stopWatch setImage:[UIImage imageNamed:@"countdown-off.png"] forState:UIControlStateNormal]; + + // update the accessibility label to indicate what pressing the button now will do + [stopWatch setAccessibilityLabel:@"Start animating graph"]; + } + else + { + stopWatchStateOn = YES; + [stopWatch setImage:[UIImage imageNamed:@"countdown-on.png"] forState:UIControlStateNormal]; + [self performSelector:@selector(_countdownValue) withObject:nil afterDelay:0.0f]; + + // update the accessibility label to indicate what pressing the button now will do + [stopWatch setAccessibilityLabel:@"Stop animating graph"]; + } + + // play sound when pressed + static SystemSoundID soundId = 0; + if ( soundId == 0 ) + { + AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"aiff"]], &soundId); + } + + AudioServicesPlaySystemSound(soundId); +} + +- (IBAction)textFieldChanged:(id)sender +{ + // only allow the text field to update in this iteration + if ( shouldUpdateGraph ) + { + shouldUpdateGraph = NO; + slider.value = [valueField.text floatValue]; + [self updateGraphingView]; + shouldUpdateGraph = YES; + } +} + +- (IBAction)sliderWasChanged:(id)sender +{ + CGFloat value = [slider value]; + + // only allow the slider to update in this iteration + if ( shouldUpdateGraph ) + { + shouldUpdateGraph = NO; + valueField.text = [NSString stringWithFormat:@"%0.5f",value]; + [self updateGraphingView]; + shouldUpdateGraph = YES; + } +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField +{ + [textField endEditing:NO]; + return YES; +} + +#pragma mark - +#pragma mark Tabular Data View + +- (IBAction)tableButtonWasPressed:(id)sender +{ + CGRect frame = tabularDataView.frame; + frame.origin.y = frame.size.height; + + if ( [tabularDataView superview] == nil ) + { + [self.view addSubview:tabularDataView]; + } + + tabularDataView.frame = frame; + [tabularDataTableView reloadData]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:.5]; + frame.origin.y = 0; + tabularDataView.frame = frame; + [UIView commitAnimations]; + + // when the table view slides in, its significant enough that a screen change notification should be posted + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); +} + +- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section +{ + return 100; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + TabularDataCell *cell = [[[TabularDataCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease]; + cell.formulaConstant = [valueField.text floatValue]; + cell.row = indexPath.row; + return cell; +} + +- (IBAction)doneButtonPressed +{ + CGRect frame = tabularDataView.frame; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:.5]; + frame.origin.y = frame.size.height; + tabularDataView.frame = frame; + [UIView commitAnimations]; + + // when the table view goes away, its significant enough that a screen change notification should be posted + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); +} + +@end diff --git a/Formulaic/Formulaic-Info.plist b/Formulaic/Formulaic-Info.plist new file mode 100644 index 0000000..1597c44 --- /dev/null +++ b/Formulaic/Formulaic-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.apple.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + + diff --git a/Formulaic/Formulaic.xcodeproj/project.pbxproj b/Formulaic/Formulaic.xcodeproj/project.pbxproj new file mode 100755 index 0000000..f080d08 --- /dev/null +++ b/Formulaic/Formulaic.xcodeproj/project.pbxproj @@ -0,0 +1,345 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 28D7ACF80DDB3853001CB0EB /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* ViewController.m */; }; + 2909CD130FC6153C0087CAF2 /* GraphingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2909CD120FC6153C0087CAF2 /* GraphingView.m */; }; + 293CD9FF0FD5920F00A12BEF /* TabularDataCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 293CD9FE0FD5920F00A12BEF /* TabularDataCell.m */; }; + 2979FBAC0FCCD36F006D7C8F /* Sound.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 2979FBAB0FCCD36F006D7C8F /* Sound.aiff */; }; + 2BA8820B11D578B600419525 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BA8820A11D578B600419525 /* AudioToolbox.framework */; }; + 2BA8820D11D578B600419525 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BA8820C11D578B600419525 /* CoreGraphics.framework */; }; + 2BA8820F11D578B600419525 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BA8820E11D578B600419525 /* Foundation.framework */; }; + 2BA8821111D578B600419525 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BA8821011D578B600419525 /* QuartzCore.framework */; }; + 2BA8821311D578B600419525 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BA8821211D578B600419525 /* UIKit.framework */; }; + 2BA8830511D57A2500419525 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA882FE11D57A2500419525 /* Icon-72.png */; }; + 2BA8830611D57A2500419525 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA882FF11D57A2500419525 /* Icon-Small-50.png */; }; + 2BA8830711D57A2500419525 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8830011D57A2500419525 /* Icon-Small.png */; }; + 2BA8830811D57A2500419525 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8830111D57A2500419525 /* Icon-Small@2x.png */; }; + 2BA8830911D57A2500419525 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8830211D57A2500419525 /* Icon.png */; }; + 2BA8830A11D57A2500419525 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8830311D57A2500419525 /* Icon@2x.png */; }; + 2BA8830B11D57A2500419525 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8830411D57A2500419525 /* iTunesArtwork */; }; + 2BA8832511D57A7400419525 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8832111D57A7400419525 /* MainWindow.xib */; }; + 2BA8832611D57A7400419525 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2BA8832311D57A7400419525 /* ViewController.xib */; }; + 2BA883CE11DA8F0A00419525 /* countdown-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA883CB11DA8F0A00419525 /* countdown-off.png */; }; + 2BA883CF11DA8F0A00419525 /* countdown-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA883CC11DA8F0A00419525 /* countdown-on.png */; }; + 2BA883D011DA8F0A00419525 /* table.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BA883CD11DA8F0A00419525 /* table.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* Formulaic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Formulaic.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 28D7ACF60DDB3853001CB0EB /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 2909CD110FC6153C0087CAF2 /* GraphingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphingView.h; sourceTree = ""; }; + 2909CD120FC6153C0087CAF2 /* GraphingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GraphingView.m; sourceTree = ""; }; + 293CD9FD0FD5920F00A12BEF /* TabularDataCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabularDataCell.h; sourceTree = ""; }; + 293CD9FE0FD5920F00A12BEF /* TabularDataCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabularDataCell.m; sourceTree = ""; }; + 2979FBAB0FCCD36F006D7C8F /* Sound.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = Sound.aiff; sourceTree = ""; }; + 297CD04F0FCF4F350003B509 /* Prefix_header.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix_header.pch; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2BA8820A11D578B600419525 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2BA8820C11D578B600419525 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2BA8820E11D578B600419525 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2BA8821011D578B600419525 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 2BA8821211D578B600419525 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2BA882FE11D57A2500419525 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + 2BA882FF11D57A2500419525 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + 2BA8830011D57A2500419525 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + 2BA8830111D57A2500419525 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + 2BA8830211D57A2500419525 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + 2BA8830311D57A2500419525 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + 2BA8830411D57A2500419525 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; + 2BA8832211D57A7400419525 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 2BA8832411D57A7400419525 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; + 2BA883CB11DA8F0A00419525 /* countdown-off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "countdown-off.png"; path = "Images/countdown-off.png"; sourceTree = ""; }; + 2BA883CC11DA8F0A00419525 /* countdown-on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "countdown-on.png"; path = "Images/countdown-on.png"; sourceTree = ""; }; + 2BA883CD11DA8F0A00419525 /* table.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = table.png; path = Images/table.png; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Formulaic-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Formulaic-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BA8820B11D578B600419525 /* AudioToolbox.framework in Frameworks */, + 2BA8820D11D578B600419525 /* CoreGraphics.framework in Frameworks */, + 2BA8820F11D578B600419525 /* Foundation.framework in Frameworks */, + 2BA8821111D578B600419525 /* QuartzCore.framework in Frameworks */, + 2BA8821311D578B600419525 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 2909CD110FC6153C0087CAF2 /* GraphingView.h */, + 2909CD120FC6153C0087CAF2 /* GraphingView.m */, + 293CD9FD0FD5920F00A12BEF /* TabularDataCell.h */, + 293CD9FE0FD5920F00A12BEF /* TabularDataCell.m */, + 28D7ACF60DDB3853001CB0EB /* ViewController.h */, + 28D7ACF70DDB3853001CB0EB /* ViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Formulaic.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 297CD04F0FCF4F350003B509 /* Prefix_header.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 2BA883CB11DA8F0A00419525 /* countdown-off.png */, + 2BA883CC11DA8F0A00419525 /* countdown-on.png */, + 2BA883CD11DA8F0A00419525 /* table.png */, + 2BA8832111D57A7400419525 /* MainWindow.xib */, + 2BA8832311D57A7400419525 /* ViewController.xib */, + 2BA882FE11D57A2500419525 /* Icon-72.png */, + 2BA882FF11D57A2500419525 /* Icon-Small-50.png */, + 2BA8830011D57A2500419525 /* Icon-Small.png */, + 2BA8830111D57A2500419525 /* Icon-Small@2x.png */, + 2BA8830211D57A2500419525 /* Icon.png */, + 2BA8830311D57A2500419525 /* Icon@2x.png */, + 2BA8830411D57A2500419525 /* iTunesArtwork */, + 2979FBAB0FCCD36F006D7C8F /* Sound.aiff */, + 8D1107310486CEB800E47090 /* Formulaic-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2BA8820A11D578B600419525 /* AudioToolbox.framework */, + 2BA8820C11D578B600419525 /* CoreGraphics.framework */, + 2BA8820E11D578B600419525 /* Foundation.framework */, + 2BA8821011D578B600419525 /* QuartzCore.framework */, + 2BA8821211D578B600419525 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Formulaic */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Formulaic" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Formulaic; + productName = WWDCDemo; + productReference = 1D6058910D05DD3D006BFB54 /* Formulaic.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Formulaic" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Formulaic */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2979FBAC0FCCD36F006D7C8F /* Sound.aiff in Resources */, + 2BA8830511D57A2500419525 /* Icon-72.png in Resources */, + 2BA8830611D57A2500419525 /* Icon-Small-50.png in Resources */, + 2BA8830711D57A2500419525 /* Icon-Small.png in Resources */, + 2BA8830811D57A2500419525 /* Icon-Small@2x.png in Resources */, + 2BA8830911D57A2500419525 /* Icon.png in Resources */, + 2BA8830A11D57A2500419525 /* Icon@2x.png in Resources */, + 2BA8830B11D57A2500419525 /* iTunesArtwork in Resources */, + 2BA8832511D57A7400419525 /* MainWindow.xib in Resources */, + 2BA8832611D57A7400419525 /* ViewController.xib in Resources */, + 2BA883CE11DA8F0A00419525 /* countdown-off.png in Resources */, + 2BA883CF11DA8F0A00419525 /* countdown-on.png in Resources */, + 2BA883D011DA8F0A00419525 /* table.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* ViewController.m in Sources */, + 2909CD130FC6153C0087CAF2 /* GraphingView.m in Sources */, + 293CD9FF0FD5920F00A12BEF /* TabularDataCell.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2BA8832111D57A7400419525 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 2BA8832211D57A7400419525 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 2BA8832311D57A7400419525 /* ViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 2BA8832411D57A7400419525 /* en */, + ); + name = ViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix_header.pch; + INFOPLIST_FILE = "Formulaic-Info.plist"; + PRODUCT_NAME = Formulaic; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix_header.pch; + INFOPLIST_FILE = "Formulaic-Info.plist"; + PRODUCT_NAME = Formulaic; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Formulaic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Formulaic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Formulaic/Images/Icon-72.png b/Formulaic/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/Formulaic/Images/Icon-72.png differ diff --git a/Formulaic/Images/Icon-Small-50.png b/Formulaic/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/Formulaic/Images/Icon-Small-50.png differ diff --git a/Formulaic/Images/Icon-Small.png b/Formulaic/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/Formulaic/Images/Icon-Small.png differ diff --git a/Formulaic/Images/Icon-Small@2x.png b/Formulaic/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/Formulaic/Images/Icon-Small@2x.png differ diff --git a/Formulaic/Images/Icon.png b/Formulaic/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/Formulaic/Images/Icon.png differ diff --git a/Formulaic/Images/Icon@2x.png b/Formulaic/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/Formulaic/Images/Icon@2x.png differ diff --git a/Formulaic/Images/countdown-off.png b/Formulaic/Images/countdown-off.png new file mode 100644 index 0000000..c6953e9 Binary files /dev/null and b/Formulaic/Images/countdown-off.png differ diff --git a/Formulaic/Images/countdown-on.png b/Formulaic/Images/countdown-on.png new file mode 100644 index 0000000..6e23eef Binary files /dev/null and b/Formulaic/Images/countdown-on.png differ diff --git a/Formulaic/Images/iTunesArtwork b/Formulaic/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/Formulaic/Images/iTunesArtwork differ diff --git a/Formulaic/Images/table.png b/Formulaic/Images/table.png new file mode 100644 index 0000000..4400af3 Binary files /dev/null and b/Formulaic/Images/table.png differ diff --git a/Formulaic/Prefix_header.pch b/Formulaic/Prefix_header.pch new file mode 100644 index 0000000..7caa540 --- /dev/null +++ b/Formulaic/Prefix_header.pch @@ -0,0 +1,52 @@ +/* + File: Prefix_header.pch + Abstract: Prefix header for all source files of the Formulaic target in the Formulaic project + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Formulaic/ReadMe.txt b/Formulaic/ReadMe.txt new file mode 100644 index 0000000..2829335 --- /dev/null +++ b/Formulaic/ReadMe.txt @@ -0,0 +1,105 @@ +### Formulaic ### + +================================================================================ +DESCRIPTION: + +Formulaic is a sample iPhone app that illustrates how to effectively use the +iPhone Accessibility API. Using the Accessibility API allows your app to work +correctly with VoiceOver. + +The app draws a graph of a formula and allows the user to change certain +constants in the formula, however its main purpose is to illustrate the +iPhone Accessibility API. + +The accessibility additions in the app demonstrate the following: + How to use accessibilityLabel, accessibilityTraits and + isAccessibilityElement to control the accessibility of the app. + How to programmatically set values through accessibility to change + various accessibility attributes. + How to use notifications to inform accessibility that an event has + occurred. + How to use the accessibility container protocol to transform a single + UIView that has multiple components into separate accessible elements. + How to use best practices to craft accessibilityLabels and + accessibilityHints correctly. + +To test the application, build and run Formulaic in iPhone Simulator. Turn on +Accessibility Inspector, located in Settings > General > Accessibility. +While Accessibility Inspector is active, single-click a user interface element +to inspect its accessibility information and double-click an element to +activate it. + +Alternatively, sync Formulaic to iPhone and turn on VoiceOver. Touch the +user interface elements to hear how the accessibility information is presented +to a VoiceOver user. + +=========================================================================== +RELATED INFORMATION: + +Accessibility Programming Guide for iPhone OS +http://developer.apple.com/iPhone/library/documentation/UserExperience/Conceptual/iPhoneAccessibility/Accessibility_on_iPhone/Accessibility_on_iPhone.html + +Testing the Accessibility of Your iPhone Application +http://developer.apple.com/iPhone/library/documentation/UserExperience/Conceptual/iPhoneAccessibility/Testing_Accessibility/Testing_Accessibility.html + +iPhone User Guide for iPhone OS 3.1 Software +http://manuals.info.apple.com/en_US/iPhone_User_Guide.pdf + +================================================================================ +BUILD REQUIREMENTS: + +iOS SDK 4.0 + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +AppDelegate.h +AppDelegate.m +UIApplication's delegate class i.e. the central controller of the application. + +GraphingView.h +GraphingView.m +The class responsible for drawing the graph, based on the formula. + +TabularDataCell.h +TabularDataCell.m +A UITableViewCell subclass that presents data from the formula in a tabular form. + +ViewController.h +ViewController.m +The main view controller of the app. + +main.m +The main entry point for the Formulaic application. + +Prefix_header.pch +A prefix header. + +countdown-on.png +A picture used for a button in the on state. + +countdown-off.png +A picture used for a button in the off state. + +table.png +A picture used for a button. + +Sound.aiff +A sound that is played when a specific button is pressed. + +ViewController.xib +An xib file for the main view. + +MainWindow.xib +A xib file for the main window. + +Formulaic-Info.plist +The Info plist file. + +================================================================================ +Copyright (C) 2009-2010 Apple Inc. All rights reserved. diff --git a/Formulaic/Sound.aiff b/Formulaic/Sound.aiff new file mode 100644 index 0000000..1a94956 Binary files /dev/null and b/Formulaic/Sound.aiff differ diff --git a/Formulaic/en.lproj/MainWindow.xib b/Formulaic/en.lproj/MainWindow.xib new file mode 100644 index 0000000..ffd0081 --- /dev/null +++ b/Formulaic/en.lproj/MainWindow.xib @@ -0,0 +1,254 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + ViewController + + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + viewController + + + + 11 + + + + window + + + + 14 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + App Delegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + ViewController + {{928, 828}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 14 + + + + YES + + AppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + ViewController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + GraphingView + UIControl + + IBProjectSource + Classes/GraphingView.h + + + + ViewController + UIViewController + + YES + + YES + sliderWasChanged: + stopWatchButtonWasPressed: + tableButtonWasPressed: + textFieldChanged: + touchesEndedForGraphingView:event: + + + YES + id + id + id + id + id + + + + YES + + YES + graphingView + resultLabel + slider + stopWatch + valueField + + + YES + GraphingView + UILabel + UISlider + UIButton + UITextField + + + + IBProjectSource + Classes/ViewController.h + + + + + 0 + Formulaic.xcodeproj + 3 + 3.0 + + diff --git a/Formulaic/en.lproj/ViewController.xib b/Formulaic/en.lproj/ViewController.xib new file mode 100644 index 0000000..123d11d --- /dev/null +++ b/Formulaic/en.lproj/ViewController.xib @@ -0,0 +1,1196 @@ + + + + 768 + 10F569 + 788 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 117 + + + YES + + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 274 + + YES + + + 292 + {{55, 81}, {210, 23}} + + NO + YES + 0.44366198778152466 + + alpha + + IBCocoaTouchFramework + 0 + 0 + 0.15000000596046448 + -0.30000001192092896 + 0.30000001192092896 + + + + 292 + {{20, 52}, {29, 21}} + + NO + YES + NO + + + + IBCocoaTouchFramework + α = + + 1 + MCAwIDAAA + + + 1 + 10 + + + + 292 + {{35, 81}, {21, 21}} + + NO + YES + NO + + + + IBCocoaTouchFramework + -.3 + + Helvetica + 14 + 16 + + + + 1 + 10 + + + + 292 + {{267, 81}, {29, 21}} + + NO + YES + NO + + + + IBCocoaTouchFramework + .3 + + + + 1 + 10 + + + + 292 + {{57, 49}, {206, 31}} + + NO + NO + + alpha equals + + + IBCocoaTouchFramework + 0 + 0.15 + 3 + + 3 + MAA + + 2 + + + YES + YES + 17 + + 1 + 2 + 9 + IBCocoaTouchFramework + + + + + 292 + {{72, 404}, {179, 36}} + + NO + NO + + + + IBCocoaTouchFramework + 0 + 0 + + Monaco + 15 + 16 + + Visit our webpage! + + 3 + MQA + + + 1 + MCAwIDEAA + + + 3 + MC41AA + + + + + 292 + {{267, 406}, {38, 34}} + + NO + NO + + Animate graph + + + IBCocoaTouchFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + NSImage + countdown-off.png + + + + + 292 + {{20, 403}, {44, 46}} + + NO + NO + + Show table + + IBCocoaTouchFramework + 0 + 0 + + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + NSImage + table.png + + + + + 292 + {{86, 8}, {148, 33}} + + NO + YES + NO + IBCocoaTouchFramework + f(x) = αx sin x + + Monaco + 24 + 16 + + + + 1 + 10 + + + + 292 + {{20, 284}, {254, 26}} + + NO + YES + NO + IBCocoaTouchFramework + f(x) = … + + + 1 + 10 + + + + 292 + {{20, 111}, {280, 165}} + + + 1 + MCAwLjAwNTU3MTUzMDY2NiAwLjUzMDYxMjIzMDMAA + + NO + + graph + + + + IBCocoaTouchFramework + + + {320, 460} + + + 1 + MC43NTgyNjQ5NTg5IDAuNzYxNjMzNTc1IDAuNzcxNzM5MTI1MyAwLjczMDAwMDAxOTEAA + + NO + IBCocoaTouchFramework + + + {320, 460} + + + 3 + MC43NQA + + + NO + + IBCocoaTouchFramework + + + + 256 + + YES + + + 290 + {320, 44} + + NO + NO + IBCocoaTouchFramework + + YES + + + Tabular Data + + Back + IBCocoaTouchFramework + 1 + + + Done + IBCocoaTouchFramework + 1 + + + IBCocoaTouchFramework + + + + + + 274 + {{0, 44}, {320, 416}} + + + NO + YES + NO + IBCocoaTouchFramework + YES + NO + 1 + 0 + 44 + + + {320, 460} + + + 3 + MQA + + + NO + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 7 + + + + graphingView + + + + 20 + + + + slider + + + + 24 + + + + textFieldChanged: + + + 18 + + 26 + + + + delegate + + + + 27 + + + + valueField + + + + 29 + + + + resultLabel + + + + 32 + + + + sliderWasChanged: + + + 13 + + 33 + + + + stopWatch + + + + 35 + + + + touchesEndedForGraphingView:event: + + + 7 + + 41 + + + + stopWatchButtonWasPressed: + + + 7 + + 42 + + + + tableButtonWasPressed: + + + 7 + + 43 + + + + tabularDataTableView + + + + 53 + + + + dataSource + + + + 58 + + + + doneButtonPressed + + + + 65 + + + + tabularDataView + + + + 67 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + YES + + + + + + 8 + + + YES + + + + + + + + + + + + + + + + 9 + + + + + 12 + + + + + 16 + + + + + 17 + + + + + 22 + + + + + 23 + + + + + 30 + + + + + 31 + + + + + 10 + + + + + 44 + + + + + 45 + + + + + 66 + + + YES + + + + + TabularView + + + 60 + + + YES + + + + + + 61 + + + YES + + + + + + + 62 + + + + + 64 + + + + + 50 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBPluginDependency + 12.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 22.IBPluginDependency + 23.IBPluginDependency + 30.IBPluginDependency + 31.IBPluginDependency + 44.IBPluginDependency + 45.IBPluginDependency + 50.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 60.IBPluginDependency + 61.IBPluginDependency + 64.IBPluginDependency + 66.IBEditorWindowLastContentRect + 66.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + ViewController + UIResponder + GraphingView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{360, 526}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{1005, 526}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 80 + + + + YES + + GraphingView + UIControl + + IBProjectSource + Classes/GraphingView.h + + + + ViewController + UIViewController + + YES + + YES + doneButtonPressed + sliderWasChanged: + stopWatchButtonWasPressed: + tableButtonWasPressed: + textFieldChanged: + touchesEndedForGraphingView:event: + + + YES + id + id + id + id + id + id + + + + YES + + YES + doneButtonPressed + sliderWasChanged: + stopWatchButtonWasPressed: + tableButtonWasPressed: + textFieldChanged: + touchesEndedForGraphingView:event: + + + YES + + doneButtonPressed + id + + + sliderWasChanged: + id + + + stopWatchButtonWasPressed: + id + + + tableButtonWasPressed: + id + + + textFieldChanged: + id + + + touchesEndedForGraphingView:event: + id + + + + + YES + + YES + graphingView + resultLabel + slider + stopWatch + tabularDataTableView + tabularDataView + tabularNavigationBar + valueField + + + YES + GraphingView + UILabel + UISlider + UIButton + UITableView + UIView + UINavigationBar + UITextField + + + + YES + + YES + graphingView + resultLabel + slider + stopWatch + tabularDataTableView + tabularDataView + tabularNavigationBar + valueField + + + YES + + graphingView + GraphingView + + + resultLabel + UILabel + + + slider + UISlider + + + stopWatch + UIButton + + + tabularDataTableView + UITableView + + + tabularDataView + UIView + + + tabularNavigationBar + UINavigationBar + + + valueField + UITextField + + + + + IBProjectSource + Classes/ViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISlider + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISlider.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITextField + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../Formulaic.xcodeproj + 3 + + YES + + YES + countdown-off.png + table.png + + + YES + {32, 32} + {43, 35} + + + 117 + + diff --git a/Formulaic/main.m b/Formulaic/main.m new file mode 100644 index 0000000..0c0c4a5 --- /dev/null +++ b/Formulaic/main.m @@ -0,0 +1,55 @@ +/* + File: main.m + Abstract: Entry point for application. Creates the application object and causes the event loop to start. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GKTank.zip b/GKTank.zip new file mode 100644 index 0000000..3f8055c Binary files /dev/null and b/GKTank.zip differ diff --git a/GKTank/Classes/TankAppDelegate.h b/GKTank/Classes/TankAppDelegate.h new file mode 100644 index 0000000..b78c713 --- /dev/null +++ b/GKTank/Classes/TankAppDelegate.h @@ -0,0 +1,76 @@ +/* + + ===== IMPORTANT ===== + + This is sample code demonstrating API, technology or techniques in development. + Although this sample code has been reviewed for technical accuracy, it is not + final. Apple is supplying this information to help you plan for the adoption of + the technologies and programming interfaces described herein. This information + is subject to change, and software implemented based on this sample code should + be tested with final operating system software and final documentation. Newer + versions of this sample code may be provided with future seeds of the API or + technology. For information about updates to this and other developer + documentation, view the New & Updated sidebars in subsequent documentation + seeds. + + ===================== + + File: TankAppDelegate.h + Abstract: A simple game showing off the features of GameKit. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + + */ + +#import + +@class TankViewController; + +@interface TankAppDelegate : NSObject { + UIWindow *window; + TankViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet TankViewController *viewController; + +@end + diff --git a/GKTank/Classes/TankAppDelegate.m b/GKTank/Classes/TankAppDelegate.m new file mode 100644 index 0000000..6f2e6fc --- /dev/null +++ b/GKTank/Classes/TankAppDelegate.m @@ -0,0 +1,89 @@ +/* + + ===== IMPORTANT ===== + + This is sample code demonstrating API, technology or techniques in development. + Although this sample code has been reviewed for technical accuracy, it is not + final. Apple is supplying this information to help you plan for the adoption of + the technologies and programming interfaces described herein. This information + is subject to change, and software implemented based on this sample code should + be tested with final operating system software and final documentation. Newer + versions of this sample code may be provided with future seeds of the API or + technology. For information about updates to this and other developer + documentation, view the New & Updated sidebars in subsequent documentation + seeds. + + ===================== + + File: TankAppDelegate.m + Abstract: A simple game showing off the features of GameKit. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + + */ + +#import "TankAppDelegate.h" +#import "TankViewController.h" + +@implementation TankAppDelegate + +@synthesize window; +@synthesize viewController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + application.idleTimerDisabled = YES; // we don't want the screen to sleep during our game + + // Override point for customization after app launch + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/GKTank/Classes/TankViewController.h b/GKTank/Classes/TankViewController.h new file mode 100644 index 0000000..ef56c65 --- /dev/null +++ b/GKTank/Classes/TankViewController.h @@ -0,0 +1,156 @@ +/* + + ===== IMPORTANT ===== + + This is sample code demonstrating API, technology or techniques in development. + Although this sample code has been reviewed for technical accuracy, it is not + final. Apple is supplying this information to help you plan for the adoption of + the technologies and programming interfaces described herein. This information + is subject to change, and software implemented based on this sample code should + be tested with final operating system software and final documentation. Newer + versions of this sample code may be provided with future seeds of the API or + technology. For information about updates to this and other developer + documentation, view the New & Updated sidebars in subsequent documentation + seeds. + + ===================== + + File: TankViewController.h + Abstract: A simple game showing off the features of GameKit. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +#define NUMWALLS 32 + +typedef enum { + BLOCK_VERTICAL, + BLOCK_HORIZONTAL +} levelBlockType; + +typedef enum { + NETWORK_ACK, // no packet + NETWORK_COINTOSS, // decide who is going to be the server + NETWORK_MOVE_EVENT, // send position + NETWORK_FIRE_EVENT, // send fire + NETWORK_HEARTBEAT // send of entire state at regular intervals +} packetCodes; + +typedef struct { + CGPoint tankPreviousPosition; + CGPoint tankPosition; + CGPoint tankMissilePosition; + CGPoint tankDestination; + + float tankRotation; + float tankDirection; + float tankMissileDirection; + int tankMissile; +} tankInfo; + +@interface TankViewController : UIViewController { + IBOutlet UIImageView *tank1; + IBOutlet UIImageView *tank2; + IBOutlet UIImageView *missile1; + IBOutlet UIImageView *missile2; + + IBOutlet UILabel *gameLabel; + IBOutlet UILabel *score1; + IBOutlet UILabel *score2; + + UIImageView *walls[NUMWALLS]; + + UIImage *levelBlockV; + UIImage *levelBlockH; + + CGPoint tank1Start; + CGPoint tank2Start; + tankInfo tankStats[2]; + + int levelBlocks; + int playerScore1, playerScore2; + + NSInteger gameState; + NSInteger peerStatus; + + // networking + GKSession *gameSession; + int gameUniqueID; + int gamePacketNumber; + NSString *gamePeerId; + NSDate *lastHeartbeatDate; + + UIAlertView *connectionAlert; +} + +@property(nonatomic, retain) IBOutlet UIImageView *tank1; +@property(nonatomic, retain) IBOutlet UIImageView *tank2; +@property(nonatomic, retain) IBOutlet UIImageView *missile1; +@property(nonatomic, retain) IBOutlet UIImageView *missile2; +@property(nonatomic, retain) IBOutlet UILabel *gameLabel; +@property(nonatomic, retain) IBOutlet UILabel *score1; +@property(nonatomic, retain) IBOutlet UILabel *score2; +@property(nonatomic, retain) UIImage *levelBlockV; +@property(nonatomic, retain) UIImage *levelBlockH; + +@property(nonatomic) NSInteger gameState; +@property(nonatomic) NSInteger peerStatus; + +@property(nonatomic, retain) GKSession *gameSession; +@property(nonatomic, copy) NSString *gamePeerId; +@property(nonatomic, retain) NSDate *lastHeartbeatDate; +@property(nonatomic, retain) UIAlertView *connectionAlert; + +- (void)invalidateSession:(GKSession *)session; + +- (void)playerReset; +- (void)updateTanks; +- (void)gameLoop; +- (void)addToLevel:(levelBlockType)bType atX:(float)x atY:(float)y width:(float)w height:(float)h; +- (void)sendNetworkPacket:(GKSession *)session packetID:(int)packetID withData:(void *)data ofLength:(int)length reliable:(BOOL)howtosend; +- (BOOL)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error; + +@end + diff --git a/GKTank/Classes/TankViewController.m b/GKTank/Classes/TankViewController.m new file mode 100644 index 0000000..e7122fb --- /dev/null +++ b/GKTank/Classes/TankViewController.m @@ -0,0 +1,816 @@ +/* + + ===== IMPORTANT ===== + + This is sample code demonstrating API, technology or techniques in development. + Although this sample code has been reviewed for technical accuracy, it is not + final. Apple is supplying this information to help you plan for the adoption of + the technologies and programming interfaces described herein. This information + is subject to change, and software implemented based on this sample code should + be tested with final operating system software and final documentation. Newer + versions of this sample code may be provided with future seeds of the API or + technology. For information about updates to this and other developer + documentation, view the New & Updated sidebars in subsequent documentation + seeds. + + ===================== + + File: TankViewController.m + Abstract: A simple game showing off the features of GameKit. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + + */ + +#import "TankViewController.h" + +// +// various states the game can get into +// +typedef enum { + kStateStartGame, + kStatePicker, + kStateMultiplayer, + kStateMultiplayerCointoss, + kStateMultiplayerReconnect +} gameStates; + +// +// for the sake of simplicity tank1 is the server and tank2 is the client +// +typedef enum { + kServer, + kClient +} gameNetwork; + +// the cool "completely change the game" variables +const float kTankSpeed = 1.0f; +const float kMissileSpeed = 3.0f; +const float kTankTurnSpeed = 0.1f; +const float kHeartbeatTimeMaxDelay = 2.0f; +#define missileLife 60 + +// strings for game label +#define kStartLabel @"Tap to Start" +#define kBlueLabel @"You're Blue" +#define kRedLabel @"You're Red" + +// GameKit Session ID for app +#define kTankSessionID @"gktank" + +#define kMaxTankPacketSize 1024 + +#pragma mark - +@implementation TankViewController + +#pragma mark View Controller Related Methods + +@synthesize tank1, tank2, missile1, missile2, gameState, peerStatus, gameLabel, levelBlockV, levelBlockH, score1, score2, gameSession, gamePeerId, lastHeartbeatDate, connectionAlert; + +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; + + peerStatus = kServer; + gamePacketNumber = 0; + gameSession = nil; + gamePeerId = nil; + lastHeartbeatDate = nil; + + NSString *uid = [[UIDevice currentDevice] uniqueIdentifier]; + + levelBlocks = 0; + gameUniqueID = [uid hash]; + + NSError *parseError = nil; + NSBundle *bundle = [NSBundle mainBundle]; + levelBlockH = [UIImage imageNamed:@"blockh.png"]; + levelBlockV = [UIImage imageNamed:@"blockv.png"]; + + [self parseXMLFileAtURL:[NSURL fileURLWithPath: [bundle pathForResource:@"level1" ofType:@"xml"]] parseError:&parseError]; + + self.gameState = kStateStartGame; // Setting to kStateStartGame does a reset of players, scores, etc. See -setGameState: below + + [NSTimer scheduledTimerWithTimeInterval:0.033 target:self selector:@selector(gameLoop) userInfo:nil repeats:YES]; +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + self.tank1 = nil; + self.tank2 = nil; + self.missile1 = nil; + self.missile2 = nil; + self.gameLabel = nil; + self.score1 = nil; + self.score2 = nil; + self.lastHeartbeatDate = nil; + if(self.connectionAlert.visible) { + [self.connectionAlert dismissWithClickedButtonIndex:-1 animated:NO]; + } + self.connectionAlert = nil; + + // release each of the walls + for(int i=0; i gameUniqueID) { + self.peerStatus = kClient; + } + + // notify user of tank color + self.gameLabel.text = (self.peerStatus == kServer) ? kBlueLabel : kRedLabel; // server is the blue tank, client is red + self.gameLabel.hidden = NO; + // after 1 second fire method to hide the label + [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(hideGameLabel:) userInfo:nil repeats:NO]; + } + break; + case NETWORK_MOVE_EVENT: + { + // received move event from other player, update other player's position/destination info + tankInfo *ts = (tankInfo *)&incomingPacket[8]; + int peer = (self.peerStatus == kServer) ? kClient : kServer; + tankInfo *ds = &tankStats[peer]; + ds->tankDestination = ts->tankDestination; + ds->tankDirection = ts->tankDirection; + } + break; + case NETWORK_FIRE_EVENT: + { + // received a missile fire event from other player, update other player's firing status + tankInfo *ts = (tankInfo *)&incomingPacket[8]; + int peer = (self.peerStatus == kServer) ? kClient : kServer; + tankInfo *ds = &tankStats[peer]; + ds->tankMissile = ts->tankMissile; + ds->tankMissilePosition = ts->tankMissilePosition; + ds->tankMissileDirection = ts->tankMissileDirection; + } + break; + case NETWORK_HEARTBEAT: + { + // Received heartbeat data with other player's position, destination, and firing status. + + // update the other player's info from the heartbeat + tankInfo *ts = (tankInfo *)&incomingPacket[8]; // tank data as seen on other client + int peer = (self.peerStatus == kServer) ? kClient : kServer; + tankInfo *ds = &tankStats[peer]; // same tank, as we see it on this client + memcpy( ds, ts, sizeof(tankInfo) ); + + // update heartbeat timestamp + self.lastHeartbeatDate = [NSDate date]; + + // if we were trying to reconnect, set the state back to multiplayer as the peer is back + if(self.gameState == kStateMultiplayerReconnect) { + if(self.connectionAlert && self.connectionAlert.visible) { + [self.connectionAlert dismissWithClickedButtonIndex:-1 animated:YES]; + } + self.gameState = kStateMultiplayer; + } + } + break; + default: + // error + break; + } +} + +- (void)sendNetworkPacket:(GKSession *)session packetID:(int)packetID withData:(void *)data ofLength:(int)length reliable:(BOOL)howtosend { + // the packet we'll send is resued + static unsigned char networkPacket[kMaxTankPacketSize]; + const unsigned int packetHeaderSize = 2 * sizeof(int); // we have two "ints" for our header + + if(length < (kMaxTankPacketSize - packetHeaderSize)) { // our networkPacket buffer size minus the size of the header info + int *pIntData = (int *)&networkPacket[0]; + // header info + pIntData[0] = gamePacketNumber++; + pIntData[1] = packetID; + // copy data in after the header + memcpy( &networkPacket[packetHeaderSize], data, length ); + + NSData *packet = [NSData dataWithBytes: networkPacket length: (length+8)]; + if(howtosend == YES) { + [session sendData:packet toPeers:[NSArray arrayWithObject:gamePeerId] withDataMode:GKSendDataReliable error:nil]; + } else { + [session sendData:packet toPeers:[NSArray arrayWithObject:gamePeerId] withDataMode:GKSendDataUnreliable error:nil]; + } + } +} + +#pragma mark GKSessionDelegate Methods + +// we've gotten a state change in the session +- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { + if(self.gameState == kStatePicker) { + return; // only do stuff if we're in multiplayer, otherwise it is probably for Picker + } + + if(state == GKPeerStateDisconnected) { + // We've been disconnected from the other peer. + + // Update user alert or throw alert if it isn't already up + NSString *message = [NSString stringWithFormat:@"Could not reconnect with %@.", [session displayNameForPeer:peerID]]; + if((self.gameState == kStateMultiplayerReconnect) && self.connectionAlert && self.connectionAlert.visible) { + self.connectionAlert.message = message; + } + else { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Lost Connection" message:message delegate:self cancelButtonTitle:@"End Game" otherButtonTitles:nil]; + self.connectionAlert = alert; + [alert show]; + [alert release]; + } + + // go back to start mode + self.gameState = kStateStartGame; + } +} + +#pragma mark - +#pragma mark Game Logic Methods + +// +// setter for gameState property +// +- (void)setGameState:(NSInteger)newState { + if(newState == kStateStartGame) { + if(self.gameSession) { + // invalidate session and release it. + [self invalidateSession:self.gameSession]; + self.gameSession = nil; + } + + // reset players to initial positions + [self playerReset]; + + // reset scores + playerScore1 = 0; + playerScore2 = 0; + self.score1.text = @"0"; + self.score2.text = @"0"; + + // show start label + self.gameLabel.text = kStartLabel; + self.gameLabel.hidden = NO; + } + + gameState = newState; +} + +// +// Called by NSTimer fire, hides the game label +// +- (void)hideGameLabel:(NSTimer *)timer { + if(self.gameLabel) { + self.gameLabel.hidden = YES; + } +} + +// +// Put players in starting position +// +- (void)playerReset { + + tank1.center = tank1Start; + tank2.center = tank2Start; + + tankStats[0].tankPosition = tankStats[0].tankMissilePosition = tankStats[0].tankPreviousPosition = tankStats[0].tankDestination = tank1.center; + tankStats[1].tankPosition = tankStats[1].tankMissilePosition = tankStats[1].tankPreviousPosition = tankStats[1].tankDestination = tank2.center; + tankStats[0].tankRotation = tankStats[0].tankMissileDirection = tankStats[0].tankDirection = M_PI; + tankStats[1].tankRotation = tankStats[1].tankMissileDirection = tankStats[1].tankDirection = 0.0f; + tankStats[0].tankMissile = tankStats[1].tankMissile = 0; + missile1.hidden = YES; + missile2.hidden = YES; + + tank1.transform = CGAffineTransformMakeRotation(tankStats[0].tankRotation); + tank2.transform = CGAffineTransformMakeRotation(tankStats[1].tankRotation); + + self.lastHeartbeatDate = nil; +} + +// +// Game loop runs at regular interval to update game based on current game state +// +- (void)gameLoop { + static int counter = 0; + switch (self.gameState) { + case kStatePicker: + case kStateStartGame: + break; + case kStateMultiplayerCointoss: + [self sendNetworkPacket:self.gameSession packetID:NETWORK_COINTOSS withData:&gameUniqueID ofLength:sizeof(int) reliable:YES]; + self.gameState = kStateMultiplayer; // we only want to be in the cointoss state for one loop + break; + case kStateMultiplayer: + [self updateTanks]; + counter++; + if(!(counter&7)) { // once every 8 updates check if we have a recent heartbeat from the other player, and send a heartbeat packet with current state + if(self.lastHeartbeatDate == nil) { + // we haven't received a hearbeat yet, so set one (in case we never receive a single heartbeat) + self.lastHeartbeatDate = [NSDate date]; + } + else if(fabs([self.lastHeartbeatDate timeIntervalSinceNow]) >= kHeartbeatTimeMaxDelay) { // see if the last heartbeat is too old + // seems we've lost connection, notify user that we are trying to reconnect (until GKSession actually disconnects) + NSString *message = [NSString stringWithFormat:@"Trying to reconnect...\nMake sure you are within range of %@.", [self.gameSession displayNameForPeer:self.gamePeerId]]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Lost Connection" message:message delegate:self cancelButtonTitle:@"End Game" otherButtonTitles:nil]; + self.connectionAlert = alert; + [alert show]; + [alert release]; + self.gameState = kStateMultiplayerReconnect; + } + + // send a new heartbeat to other player + tankInfo *ts = &tankStats[self.peerStatus]; + [self sendNetworkPacket:gameSession packetID:NETWORK_HEARTBEAT withData:ts ofLength:sizeof(tankInfo) reliable:NO]; + } + break; + case kStateMultiplayerReconnect: + // we have lost a heartbeat for too long, so pause game and notify user while we wait for next heartbeat or session disconnect. + counter++; + if(!(counter&7)) { // keep sending heartbeats to the other player in case it returns + tankInfo *ts = &tankStats[self.peerStatus]; + [self sendNetworkPacket:gameSession packetID:NETWORK_HEARTBEAT withData:ts ofLength:sizeof(tankInfo) reliable:NO]; + } + break; + default: + break; + } +} + +// +// rotate and move the tanks towards their destinations if need be +// +- (void)updateTanks { + int i; + for(i=0;i<2;i++) { + UIImageView *theTank; + UIImageView *enemyTank; + UIImageView *theMissile; + tankInfo *ts = &tankStats[i]; + + if(i==0) { + theTank = tank1; + enemyTank = tank2; + theMissile = missile1; + } else { + theTank = tank2; + enemyTank = tank1; + theMissile = missile2; + } + + bool checkCollision = true; + + if( (fabs(ts->tankPosition.x - ts->tankDestination.x)>kTankSpeed) || (fabs(ts->tankPosition.y - ts->tankDestination.y)>kTankSpeed) ) { + // check facing + float ad = ts->tankDirection - ts->tankRotation; + + if(fabs(ad) > kTankTurnSpeed) { + // we need to turn, work out which way (find the closest 180) + while(ad > M_PI) { + ad -= (2.0 * M_PI); + } + while(ad < -M_PI) { + ad += (2.0 * M_PI); + } + if(ad < 0) { + ts->tankRotation -= kTankTurnSpeed; + if(ts->tankRotation < 0) + ts->tankRotation += (2.0*M_PI); + } else if(ad > 0) { + ts->tankRotation += kTankTurnSpeed; + if(ts->tankRotation > (2.0*M_PI)) + ts->tankRotation -= (2.0*M_PI); + } + checkCollision = false; + } else { + ts->tankRotation = ts->tankDirection; + // if facing move along line towards destination + float dx = ts->tankPosition.x - ts->tankDestination.x; + float dy = ts->tankPosition.y - ts->tankDestination.y; + float at = atan2( dy, dx ); + // 1.0 is the "speed" + ts->tankPosition.x -= kTankSpeed * cos(at); + ts->tankPosition.y -= kTankSpeed * sin(at); + } + } else { + ts->tankPosition.x = ts->tankDestination.x; + ts->tankPosition.y = ts->tankDestination.y; + } + bool collide = false; + // if we're not rotating we can check for collisions + if(checkCollision) { + // check for collisions + CGRect tankframe = CGRectInset(theTank.frame, theTank.frame.size.width/4.0, theTank.frame.size.height/4.0); // make a collision frame that's half the size and centered to the actual tank image + + for(int j=0; jtankPosition = ts->tankPreviousPosition; + ts->tankDestination = ts->tankPosition; + collide = true; + break; + } + } + } + if(!collide) { + ts->tankPreviousPosition = theTank.center; + theTank.center = ts->tankPosition; + theTank.transform = CGAffineTransformMakeRotation(ts->tankRotation); + } + // see if we've fired something + if(ts->tankMissile != 0) { + ts->tankMissile--; + if(ts->tankMissile == 0) { + theMissile.hidden = YES; + } else { + theMissile.hidden = NO; + ts->tankMissilePosition.x -= kMissileSpeed * cos(ts->tankMissileDirection); + ts->tankMissilePosition.y -= kMissileSpeed * sin(ts->tankMissileDirection); + theMissile.center = ts->tankMissilePosition; + } + + for(int j=0; jtankMissile = 0; + break; + } + } + + // check against the other tank + if(CGRectIntersectsRect(theMissile.frame, enemyTank.frame)) { + // we hit! + if(i==0) { + playerScore1 += 1; // playerScore1 is blue tanks score + [score1 setText: [NSString stringWithFormat:@"%d", playerScore1]]; + } else { + playerScore2 += 1; // playerScore2 is red tanks score + [score2 setText: [NSString stringWithFormat:@"%d", playerScore2]]; + } + [self playerReset]; + break; + } + } + } +} + +#pragma mark - +#pragma mark Event Handling Methods + +// +// someone touched the screen +// +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + switch (self.gameState) { + case kStateStartGame: + [self startPicker]; + self.gameLabel.hidden = YES; + break; + case kStateMultiplayer: + { + CGPoint thumbPoint; + UITouch *thumb = [[event allTouches] anyObject]; + thumbPoint = [thumb locationInView:thumb.view]; + tankInfo *ts = &tankStats[self.peerStatus]; + // hold to move, second finger to fire + if(thumb.tapCount==0) { + ts->tankDestination = thumbPoint; + ts->tankDirection = atan2( thumbPoint.y - ts->tankPosition.y, thumbPoint.x - ts->tankPosition.x ) + (M_PI/2.0); + // keep us 0-359 + if(ts->tankDirection < 0) + ts->tankDirection += (2.0*M_PI); + else if(ts->tankDirection > (2.0*M_PI)) + ts->tankDirection -= (2.0*M_PI); + if(self.gameState == kStateMultiplayer) { + [self sendNetworkPacket:gameSession packetID:NETWORK_MOVE_EVENT withData:ts ofLength:sizeof(tankInfo) reliable: NO]; + } + } else { + // make sure we're not shooting + if(ts->tankMissile == 0) { + ts->tankMissile = missileLife; + ts->tankMissileDirection = ts->tankRotation + (M_PI/2.0); + ts->tankMissilePosition = ts->tankPosition; + } + if(self.gameState == kStateMultiplayer) { + [self sendNetworkPacket:gameSession packetID:NETWORK_FIRE_EVENT withData:ts ofLength:sizeof(tankInfo) reliable: NO]; + } + } + } + break; + default: + break; + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + switch (self.gameState) { + case kStateStartGame: + break; + case kStateMultiplayer: + if([touches count] == 1) { + CGPoint thumbPoint; + UITouch *thumb = [[event allTouches] anyObject]; + thumbPoint = [thumb locationInView:thumb.view]; + tankInfo *ts = &tankStats[self.peerStatus]; + ts->tankDestination = thumbPoint; + ts->tankDirection = atan2( thumbPoint.y - ts->tankPosition.y, thumbPoint.x - ts->tankPosition.x ) + (M_PI/2.0); + // keep us 0-359 + if(ts->tankDirection < 0) + ts->tankDirection += (2.0*M_PI); + else if(ts->tankDirection > (2.0*M_PI)) + ts->tankDirection -= (2.0*M_PI); + if(self.gameState == kStateMultiplayer) { + [self sendNetworkPacket:gameSession packetID:NETWORK_MOVE_EVENT withData:ts ofLength:sizeof(tankInfo) reliable: NO]; + } + } + break; + default: + break; + } +} + +-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + switch (self.gameState) { + case kStateStartGame: + break; + case kStateMultiplayer: + if([touches count] == [[event touchesForView:self.view] count]) { + tankInfo *ts = &tankStats[self.peerStatus]; + ts->tankDestination = ts->tankPosition; + ts->tankDirection = ts->tankRotation; + if(self.gameState == kStateMultiplayer) { + [self sendNetworkPacket:gameSession packetID:NETWORK_MOVE_EVENT withData:ts ofLength:sizeof(tankInfo) reliable: NO]; + } + } + break; + default: + break; + } +} + +#pragma mark - +#pragma mark Level Loading Methods +// +// add something to the game level from the level XML file +// +-(void)addToLevel:(levelBlockType) bType atX:(float) x atY:(float) y width:(float)w height:(float)h { + CGRect box; + + box = CGRectMake( x,y, w,h ); + + if(levelBlocks + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + tank.png + CFBundleIdentifier + com.apple.sample.gktank + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarHidden + + + diff --git a/GKTank/GKTank.xcodeproj/project.pbxproj b/GKTank/GKTank.xcodeproj/project.pbxproj new file mode 100755 index 0000000..940ce71 --- /dev/null +++ b/GKTank/GKTank.xcodeproj/project.pbxproj @@ -0,0 +1,304 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* TankAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* TankAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 2899E5220DE3E06400AC0155 /* tankViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2899E5210DE3E06400AC0155 /* tankViewController.xib */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 28D7ACF80DDB3853001CB0EB /* TankViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* TankViewController.m */; }; + 2C47FC550FA7EBBA00441EEA /* redtank.png in Resources */ = {isa = PBXBuildFile; fileRef = 2C47FC530FA7EBBA00441EEA /* redtank.png */; }; + 2C47FC560FA7EBBA00441EEA /* tankbackground.png in Resources */ = {isa = PBXBuildFile; fileRef = 2C47FC540FA7EBBA00441EEA /* tankbackground.png */; }; + 2C47FC5D0FA7EC7A00441EEA /* bluemissile.png in Resources */ = {isa = PBXBuildFile; fileRef = 2C47FC590FA7EC7A00441EEA /* bluemissile.png */; }; + 2C47FC5E0FA7EC7A00441EEA /* bluetank.png in Resources */ = {isa = PBXBuildFile; fileRef = 2C47FC5A0FA7EC7A00441EEA /* bluetank.png */; }; + 2C47FC5F0FA7EC7A00441EEA /* redmissile.png in Resources */ = {isa = PBXBuildFile; fileRef = 2C47FC5B0FA7EC7A00441EEA /* redmissile.png */; }; + 2C47FC600FA7EC7A00441EEA /* tank.png in Resources */ = {isa = PBXBuildFile; fileRef = 2C47FC5C0FA7EC7A00441EEA /* tank.png */; }; + 2CBBFEBB0FA8B20400ED3E90 /* blockh.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CBBFEB90FA8B20400ED3E90 /* blockh.png */; }; + 2CBBFEBC0FA8B20400ED3E90 /* blockv.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CBBFEBA0FA8B20400ED3E90 /* blockv.png */; }; + 2CBBFED40FA8BA4600ED3E90 /* level1.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2CBBFED30FA8BA4600ED3E90 /* level1.xml */; }; + 2CBBFFBA0FA8F98800ED3E90 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CBBFFB90FA8F98800ED3E90 /* GameKit.framework */; }; + ABE88D5D0FD6327F00451BE7 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = ABE88D5C0FD6327F00451BE7 /* Default.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* TankAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TankAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* TankAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TankAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* GKTank.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GKTank.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2899E5210DE3E06400AC0155 /* tankViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = tankViewController.xib; sourceTree = ""; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 28D7ACF60DDB3853001CB0EB /* TankViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TankViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* TankViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TankViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2C47FC530FA7EBBA00441EEA /* redtank.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = redtank.png; sourceTree = ""; }; + 2C47FC540FA7EBBA00441EEA /* tankbackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tankbackground.png; sourceTree = ""; }; + 2C47FC590FA7EC7A00441EEA /* bluemissile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bluemissile.png; sourceTree = ""; }; + 2C47FC5A0FA7EC7A00441EEA /* bluetank.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bluetank.png; sourceTree = ""; }; + 2C47FC5B0FA7EC7A00441EEA /* redmissile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = redmissile.png; sourceTree = ""; }; + 2C47FC5C0FA7EC7A00441EEA /* tank.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tank.png; sourceTree = ""; }; + 2CBBFEB90FA8B20400ED3E90 /* blockh.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blockh.png; sourceTree = ""; }; + 2CBBFEBA0FA8B20400ED3E90 /* blockv.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blockv.png; sourceTree = ""; }; + 2CBBFED30FA8BA4600ED3E90 /* level1.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level1.xml; sourceTree = ""; }; + 2CBBFFB90FA8F98800ED3E90 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* GKTank_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKTank_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* GKTank-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GKTank-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + ABE88D5C0FD6327F00451BE7 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 2CBBFFBA0FA8F98800ED3E90 /* GameKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* TankAppDelegate.h */, + 1D3623250D0F684500981E51 /* TankAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* TankViewController.h */, + 28D7ACF70DDB3853001CB0EB /* TankViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GKTank.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2CBBFEC70FA8BA3000ED3E90 /* Levels */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* GKTank_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + ABE88D5C0FD6327F00451BE7 /* Default.png */, + 2CBBFEB90FA8B20400ED3E90 /* blockh.png */, + 2CBBFEBA0FA8B20400ED3E90 /* blockv.png */, + 2C47FC590FA7EC7A00441EEA /* bluemissile.png */, + 2C47FC5A0FA7EC7A00441EEA /* bluetank.png */, + 2C47FC5B0FA7EC7A00441EEA /* redmissile.png */, + 2C47FC5C0FA7EC7A00441EEA /* tank.png */, + 2C47FC530FA7EBBA00441EEA /* redtank.png */, + 2C47FC540FA7EBBA00441EEA /* tankbackground.png */, + 2899E5210DE3E06400AC0155 /* tankViewController.xib */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* GKTank-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2CBBFFB90FA8F98800ED3E90 /* GameKit.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2CBBFEC70FA8BA3000ED3E90 /* Levels */ = { + isa = PBXGroup; + children = ( + 2CBBFED30FA8BA4600ED3E90 /* level1.xml */, + ); + name = Levels; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GKTank */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GKTank" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GKTank; + productName = tank; + productReference = 1D6058910D05DD3D006BFB54 /* GKTank.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GKTank" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GKTank */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + 2899E5220DE3E06400AC0155 /* tankViewController.xib in Resources */, + 2C47FC550FA7EBBA00441EEA /* redtank.png in Resources */, + 2C47FC560FA7EBBA00441EEA /* tankbackground.png in Resources */, + 2C47FC5D0FA7EC7A00441EEA /* bluemissile.png in Resources */, + 2C47FC5E0FA7EC7A00441EEA /* bluetank.png in Resources */, + 2C47FC5F0FA7EC7A00441EEA /* redmissile.png in Resources */, + 2C47FC600FA7EC7A00441EEA /* tank.png in Resources */, + 2CBBFEBB0FA8B20400ED3E90 /* blockh.png in Resources */, + 2CBBFEBC0FA8B20400ED3E90 /* blockv.png in Resources */, + 2CBBFED40FA8BA4600ED3E90 /* level1.xml in Resources */, + ABE88D5D0FD6327F00451BE7 /* Default.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* TankAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* TankViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GKTank_Prefix.pch; + INFOPLIST_FILE = "GKTank-Info.plist"; + PRODUCT_NAME = GKTank; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GKTank_Prefix.pch; + INFOPLIST_FILE = "GKTank-Info.plist"; + PRODUCT_NAME = GKTank; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos3.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GKTank" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GKTank" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GKTank/GKTank_Prefix.pch b/GKTank/GKTank_Prefix.pch new file mode 100644 index 0000000..32e447b --- /dev/null +++ b/GKTank/GKTank_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'tank' target in the 'tank' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/GKTank/MainWindow.xib b/GKTank/MainWindow.xib new file mode 100644 index 0000000..82af339 --- /dev/null +++ b/GKTank/MainWindow.xib @@ -0,0 +1,231 @@ + + + + 768 + 9J60 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + tankViewController + + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + viewController + + + + 11 + + + + window + + + + 14 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + tank App Delegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + TankViewController + {{479, 179}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TankAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 14 + + + + YES + + TankAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + TankViewController + UIWindow + + + + IBProjectSource + Classes/TankAppDelegate.h + + + + TankViewController + UIViewController + + YES + + YES + gameLabel + missile1 + missile2 + score1 + score2 + tank1 + tank2 + + + YES + UILabel + UIImageView + UIImageView + UILabel + UILabel + UIImageView + UIImageView + + + + IBProjectSource + Classes/TankViewController.h + + + + + 0 + GKTank.xcodeproj + 3 + 3.0 + + diff --git a/GKTank/README.txt b/GKTank/README.txt new file mode 100644 index 0000000..01eecb0 --- /dev/null +++ b/GKTank/README.txt @@ -0,0 +1,18 @@ + +DESCRIPTION: + +GKTank is a sample application that shows how to use the GKSession and GKPeerPickerController classes in the GameKit framework to add Peer-to-Peer Connectivity to an application. + +The 'TankViewController" class defined in the TankViewController.h handles the GameKit related Peer-to-Peer Connectivity implemenation, and is also where most of the other game logic is located. + +Note: This sample application does not cover all the possible things you can or will need to do in your application to handle all possible events that could occur in a networked application environment. + +RELATED INFORMATION: + +- Game Kit Programming Guide +- Game Kit Reference Documentation + +SPECIAL CONSIDERATIONS: + +This sample application is intended to be run on the device, and requires two devices to exercise the Peer-to-Peer Connectivity functionality. + diff --git a/GKTank/blockh.png b/GKTank/blockh.png new file mode 100644 index 0000000..7048abc Binary files /dev/null and b/GKTank/blockh.png differ diff --git a/GKTank/blockv.png b/GKTank/blockv.png new file mode 100644 index 0000000..df9fc56 Binary files /dev/null and b/GKTank/blockv.png differ diff --git a/GKTank/bluemissile.png b/GKTank/bluemissile.png new file mode 100644 index 0000000..af4e65f Binary files /dev/null and b/GKTank/bluemissile.png differ diff --git a/GKTank/bluetank.png b/GKTank/bluetank.png new file mode 100644 index 0000000..56e29c6 Binary files /dev/null and b/GKTank/bluetank.png differ diff --git a/GKTank/level1.xml b/GKTank/level1.xml new file mode 100644 index 0000000..ff4daed --- /dev/null +++ b/GKTank/level1.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GKTank/main.m b/GKTank/main.m new file mode 100644 index 0000000..cbb798d --- /dev/null +++ b/GKTank/main.m @@ -0,0 +1,71 @@ +/* + + ===== IMPORTANT ===== + + This is sample code demonstrating API, technology or techniques in development. + Although this sample code has been reviewed for technical accuracy, it is not + final. Apple is supplying this information to help you plan for the adoption of + the technologies and programming interfaces described herein. This information + is subject to change, and software implemented based on this sample code should + be tested with final operating system software and final documentation. Newer + versions of this sample code may be provided with future seeds of the API or + technology. For information about updates to this and other developer + documentation, view the New & Updated sidebars in subsequent documentation + seeds. + + ===================== + + File: main.m + Abstract: A simple game showing off the features of GameKit. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GKTank/redmissile.png b/GKTank/redmissile.png new file mode 100644 index 0000000..713870c Binary files /dev/null and b/GKTank/redmissile.png differ diff --git a/GKTank/redtank.png b/GKTank/redtank.png new file mode 100644 index 0000000..5eb839a Binary files /dev/null and b/GKTank/redtank.png differ diff --git a/GKTank/tank.png b/GKTank/tank.png new file mode 100644 index 0000000..89e1f74 Binary files /dev/null and b/GKTank/tank.png differ diff --git a/GKTank/tankViewController.xib b/GKTank/tankViewController.xib new file mode 100644 index 0000000..95c67f2 --- /dev/null +++ b/GKTank/tankViewController.xib @@ -0,0 +1,433 @@ + + + + 768 + 9J60 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 274 + {320, 460} + + NO + NO + 4 + NO + + NSImage + tankbackground.png + + + + + -2147483356 + {{45, 387}, {12, 12}} + + NO + NO + 4 + NO + + NSImage + redmissile.png + + + + + 292 + {{143, 406}, {40, 40}} + + NO + NO + 4 + NO + + NSImage + redtank.png + + + + + 292 + {{139, 20}, {40, 40}} + + NO + NO + 4 + NO + + NSImage + bluetank.png + + + + + -2147483356 + {{45, 77}, {12, 12}} + + NO + NO + 4 + NO + + NSImage + bluemissile.png + + + + + -2147483356 + {{20, 196}, {280, 68}} + + NO + YES + NO + Tap to Start + + Helvetica + 4.800000e+01 + 16 + + + 1 + MC45ODM2OTU2MyAwLjk4MzY5NTYzIDAuOTgzNjk1NjMAA + + + 1 + 1.000000e+01 + 1 + + + + 292 + {{5, 5}, {58, 57}} + + NO + YES + NO + 0 + + Courier + 4.800000e+01 + 16 + + + 2 + MC4xNzY0NzA1OSAwLjcwMTk2MDggMC45OTIxNTY5MgA + + + 1 + 1.000000e+01 + 1 + + + + 292 + {{257, 5}, {58, 57}} + + NO + YES + NO + 0 + + + 2 + MC45NjA3ODQzOCAwIDAuMzA5ODAzOTMAA + + + 1 + 1.000000e+01 + 1 + + + {320, 460} + + + 3 + MC43NQA + + 2 + + + NO + YES + + + + + + YES + + + view + + + + 7 + + + + tank1 + + + + 13 + + + + missile1 + + + + 14 + + + + missile2 + + + + 15 + + + + tank2 + + + + 16 + + + + score1 + + + + 38 + + + + score2 + + + + 39 + + + + gameLabel + + + + 40 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 6 + + + YES + + + + + + + + + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 12 + + + + + 17 + + + + + 36 + + + + + 37 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 17.IBPluginDependency + 36.IBPluginDependency + 37.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + TankViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{800, 222}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 40 + + + + YES + + TankViewController + UIViewController + + YES + + YES + gameLabel + missile1 + missile2 + score1 + score2 + tank1 + tank2 + + + YES + UILabel + UIImageView + UIImageView + UILabel + UILabel + UIImageView + UIImageView + + + + IBProjectSource + Classes/TankViewController.h + + + + + 0 + GKTank.xcodeproj + 3 + 3.0 + + diff --git a/GKTank/tankbackground.png b/GKTank/tankbackground.png new file mode 100644 index 0000000..c7d2723 Binary files /dev/null and b/GKTank/tankbackground.png differ diff --git a/GKTapper.zip b/GKTapper.zip new file mode 100644 index 0000000..09b7cb7 Binary files /dev/null and b/GKTapper.zip differ diff --git a/GKTapper/Ancillary Code/TapperAppDelegate.h b/GKTapper/Ancillary Code/TapperAppDelegate.h new file mode 100644 index 0000000..9e6219d --- /dev/null +++ b/GKTapper/Ancillary Code/TapperAppDelegate.h @@ -0,0 +1,61 @@ +/* + + File: TapperAppDelegate.h + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class TapperController; + +@interface TapperAppDelegate : NSObject { + UIWindow *window; + TapperController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet TapperController *viewController; + +@end + diff --git a/GKTapper/Ancillary Code/TapperAppDelegate.m b/GKTapper/Ancillary Code/TapperAppDelegate.m new file mode 100644 index 0000000..40a936f --- /dev/null +++ b/GKTapper/Ancillary Code/TapperAppDelegate.m @@ -0,0 +1,67 @@ +/* + + File: TapperAppDelegate.m + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TapperAppDelegate.h" +#import "TapperController.h" + +@implementation TapperAppDelegate + +@synthesize window; +@synthesize viewController; + + +#pragma mark - +#pragma mark Application lifecycle +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + // Override point for customization after application launch. + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; + + return YES; +} +@end diff --git a/GKTapper/Ancillary Code/main.m b/GKTapper/Ancillary Code/main.m new file mode 100644 index 0000000..fab04e8 --- /dev/null +++ b/GKTapper/Ancillary Code/main.m @@ -0,0 +1,56 @@ +/* + + File: main.m + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, NULL, NULL); + [pool release]; + return retVal; +} diff --git a/GKTapper/Classes/AppSpecificValues.h b/GKTapper/Classes/AppSpecificValues.h new file mode 100644 index 0000000..0b84ed4 --- /dev/null +++ b/GKTapper/Classes/AppSpecificValues.h @@ -0,0 +1,66 @@ +/* + + File: AppSpecificValues.h + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +//These constants are defined in iTunesConnect, and will function as long +// as this sample is built/run with the existing bundle identifier +// (com.appledts.GKTapper). If you want to experiment with this sample and +// iTunesConnect, you'll need to define you're own bundle ID and iTunes +// Connect configurations. This sample uses reverse DNS for Leaderboards +// and Achievement IDs, but this is not a requirement. Any string that +// iTunes Connect will accept will work fine. + +//Leaderboard Category IDs +#define kEasyLeaderboardID @"com.appledts.EasyTapList" +#define kHardLeaderboardID @"com.appledts.HardTapList" +#define kAwesomeLeaderboardID @"com.appledts.AwesomeTapList" + + +//Achievement IDs +#define kAchievementGotOneTap @"com.appletest.one_tap" +#define kAchievementHidden20Taps @"com.appledts.twenty_taps" +#define kAchievementBigOneHundred @"com.appledts.one_hundred_taps" + diff --git a/GKTapper/Classes/GameCenterManager.h b/GKTapper/Classes/GameCenterManager.h new file mode 100644 index 0000000..86626f6 --- /dev/null +++ b/GKTapper/Classes/GameCenterManager.h @@ -0,0 +1,88 @@ +/* + + File: GameCenterManager.h + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@class GKLeaderboard, GKAchievement, GKPlayer; + + + +@protocol GameCenterManagerDelegate +@optional +- (void) processGameCenterAuth: (NSError*) error; +- (void) scoreReported: (NSError*) error; +- (void) reloadScoresComplete: (GKLeaderboard*) leaderBoard error: (NSError*) error; +- (void) achievementSubmitted: (GKAchievement*) ach error:(NSError*) error; +- (void) achievementResetResult: (NSError*) error; +- (void) mappedPlayerIDToPlayer: (GKPlayer*) player error: (NSError*) error; +@end + +@interface GameCenterManager : NSObject +{ + NSMutableDictionary* earnedAchievementCache; + + id delegate; +} + +//This property must be attomic to ensure that the cache is always in a viable state... +@property (retain) NSMutableDictionary* earnedAchievementCache; + +@property (nonatomic, assign) id delegate; + ++ (BOOL) isGameCenterAvailable; + +- (void) authenticateLocalUser; + +- (void) reportScore: (int64_t) score forCategory: (NSString*) category; +- (void) reloadHighScoresForCategory: (NSString*) category; + +- (void) submitAchievement: (NSString*) identifier percentComplete: (double) percentComplete; +- (void) resetAchievements; + +- (void) mapPlayerIDtoPlayer: (NSString*) playerID; +@end diff --git a/GKTapper/Classes/GameCenterManager.m b/GKTapper/Classes/GameCenterManager.m new file mode 100644 index 0000000..1870bad --- /dev/null +++ b/GKTapper/Classes/GameCenterManager.m @@ -0,0 +1,259 @@ +/* + + File: GameCenterManager.m + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "GameCenterManager.h" +#import + + + +@implementation GameCenterManager + +@synthesize earnedAchievementCache; +@synthesize delegate; + +- (id) init +{ + self = [super init]; + if(self!= NULL) + { + earnedAchievementCache= NULL; + } + return self; +} + +- (void) dealloc +{ + self.earnedAchievementCache= NULL; + [super dealloc]; +} + + +// NOTE: GameCenter does not guarantee that callback blocks will be execute on the main thread. +// As such, your application needs to be very careful in how it handles references to view +// controllers. If a view controller is referenced in a block that executes on a secondary queue, +// that view controller may be released (and dealloc'd) outside the main queue. This is true +// even if the actual block is scheduled on the main thread. In concrete terms, this code +// snippet is not safe, even though viewController is dispatching to the main queue: +// +// [object doSomethingWithCallback: ^() +// { +// dispatch_async(dispatch_get_main_queue(), ^(void) +// { +// [viewController doSomething]; +// }); +// }]; +// +// UIKit view controllers should only be accessed on the main thread, so the snippet above may +// lead to subtle and hard to trace bugs. Many solutions to this problem exist. In this sample, +// I'm bottlenecking everything through "callDelegateOnMainThread" which calls "callDelegate". +// Because "callDelegate" is the only method to access the delegate, I can ensure that delegate +// is not visible in any of my block callbacks. + +- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err +{ + assert([NSThread isMainThread]); + if([delegate respondsToSelector: selector]) + { + if(arg != NULL) + { + [delegate performSelector: selector withObject: arg withObject: err]; + } + else + { + [delegate performSelector: selector withObject: err]; + } + } + else + { + NSLog(@"Missed Method"); + } +} + + +- (void) callDelegateOnMainThread: (SEL) selector withArg: (id) arg error: (NSError*) err +{ + dispatch_async(dispatch_get_main_queue(), ^(void) + { + [self callDelegate: selector withArg: arg error: err]; + }); +} + ++ (BOOL) isGameCenterAvailable +{ + // check for presence of GKLocalPlayer API + Class gcClass = (NSClassFromString(@"GKLocalPlayer")); + + // check if the device is running iOS 4.1 or later + NSString *reqSysVer = @"4.1"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending); + + return (gcClass && osVersionSupported); +} + + +- (void) authenticateLocalUser +{ + if([GKLocalPlayer localPlayer].authenticated == NO) + { + [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) + { + [self callDelegateOnMainThread: @selector(processGameCenterAuth:) withArg: NULL error: error]; + }]; + } +} + +- (void) reloadHighScoresForCategory: (NSString*) category +{ + GKLeaderboard* leaderBoard= [[[GKLeaderboard alloc] init] autorelease]; + leaderBoard.category= category; + leaderBoard.timeScope= GKLeaderboardTimeScopeAllTime; + leaderBoard.range= NSMakeRange(1, 1); + + [leaderBoard loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) + { + [self callDelegateOnMainThread: @selector(reloadScoresComplete:error:) withArg: leaderBoard error: error]; + }]; +} + +- (void) reportScore: (int64_t) score forCategory: (NSString*) category +{ + GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease]; + scoreReporter.value = score; + [scoreReporter reportScoreWithCompletionHandler: ^(NSError *error) + { + [self callDelegateOnMainThread: @selector(scoreReported:) withArg: NULL error: error]; + }]; +} + +- (void) submitAchievement: (NSString*) identifier percentComplete: (double) percentComplete +{ + //GameCenter check for duplicate achievements when the achievement is submitted, but if you only want to report + // new achievements to the user, then you need to check if it's been earned + // before you submit. Otherwise you'll end up with a race condition between loadAchievementsWithCompletionHandler + // and reportAchievementWithCompletionHandler. To avoid this, we fetch the current achievement list once, + // then cache it and keep it updated with any new achievements. + if(self.earnedAchievementCache == NULL) + { + [GKAchievement loadAchievementsWithCompletionHandler: ^(NSArray *scores, NSError *error) + { + if(error == NULL) + { + NSMutableDictionary* tempCache= [NSMutableDictionary dictionaryWithCapacity: [scores count]]; + for (GKAchievement* score in scores) + { + [tempCache setObject: score forKey: score.identifier]; + } + self.earnedAchievementCache= tempCache; + [self submitAchievement: identifier percentComplete: percentComplete]; + } + else + { + //Something broke loading the achievement list. Error out, and we'll try again the next time achievements submit. + [self callDelegateOnMainThread: @selector(achievementSubmitted:error:) withArg: NULL error: error]; + } + + }]; + } + else + { + //Search the list for the ID we're using... + GKAchievement* achievement= [self.earnedAchievementCache objectForKey: identifier]; + if(achievement != NULL) + { + if((achievement.percentComplete >= 100.0) || (achievement.percentComplete >= percentComplete)) + { + //Achievement has already been earned so we're done. + achievement= NULL; + } + achievement.percentComplete= percentComplete; + } + else + { + achievement= [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease]; + achievement.percentComplete= percentComplete; + //Add achievement to achievement cache... + [self.earnedAchievementCache setObject: achievement forKey: achievement.identifier]; + } + if(achievement!= NULL) + { + //Submit the Achievement... + [achievement reportAchievementWithCompletionHandler: ^(NSError *error) + { + [self callDelegateOnMainThread: @selector(achievementSubmitted:error:) withArg: achievement error: error]; + }]; + } + } +} + +- (void) resetAchievements +{ + self.earnedAchievementCache= NULL; + [GKAchievement resetAchievementsWithCompletionHandler: ^(NSError *error) + { + [self callDelegateOnMainThread: @selector(achievementResetResult:) withArg: NULL error: error]; + }]; +} + +- (void) mapPlayerIDtoPlayer: (NSString*) playerID +{ + [GKPlayer loadPlayersForIdentifiers: [NSArray arrayWithObject: playerID] withCompletionHandler:^(NSArray *playerArray, NSError *error) + { + GKPlayer* player= NULL; + for (GKPlayer* tempPlayer in playerArray) + { + if([tempPlayer.playerID isEqualToString: playerID]) + { + player= tempPlayer; + break; + } + } + [self callDelegateOnMainThread: @selector(mappedPlayerIDToPlayer:error:) withArg: player error: error]; + }]; + +} +@end diff --git a/GKTapper/Classes/TapperController.h b/GKTapper/Classes/TapperController.h new file mode 100644 index 0000000..feda2f0 --- /dev/null +++ b/GKTapper/Classes/TapperController.h @@ -0,0 +1,96 @@ +/* + + File: TapperController.h + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +#import "GameCenterManager.h" + +@class GameCenterManager; +@interface TapperController : UITableViewController +{ + GameCenterManager* gameCenterManager; + + IBOutlet UIView* resetAchievementsView; + IBOutlet UIButton* achievementButton; + + NSString* personalBestScoreDescription; + NSString* personalBestScoreString; + + NSString* leaderboardHighScoreDescription; + NSString* leaderboardHighScoreString; + + NSString* currentLeaderBoard; + + int64_t currentScore; + NSString* cachedHighestScore; + + +} +@property (nonatomic, retain) GameCenterManager *gameCenterManager; + +@property (nonatomic, assign) int64_t currentScore; +@property (nonatomic, retain) NSString* cachedHighestScore; + + +@property (nonatomic, retain) UIView* resetAchievementsView; +@property (nonatomic, retain) UIView* gameButtonView; + +@property (nonatomic, retain) NSString* personalBestScoreDescription; +@property (nonatomic, retain) NSString* personalBestScoreString; +@property (nonatomic, retain) NSString* leaderboardHighScoreDescription; +@property (nonatomic, retain) NSString* leaderboardHighScoreString; +@property (nonatomic, retain) NSString* currentLeaderBoard; + +- (IBAction) resetAchievements: (id) sender; + +- (void) addOne; +- (void) submitHighScore; +- (void) showLeaderboard; +- (void) showAchievements; +@end + diff --git a/GKTapper/Classes/TapperController.m b/GKTapper/Classes/TapperController.m new file mode 100644 index 0000000..d957169 --- /dev/null +++ b/GKTapper/Classes/TapperController.m @@ -0,0 +1,687 @@ +/* + + File: TapperController.m + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppSpecificValues.h" +#import "TapperController.h" + +#import "GameCenterManager.h" + +enum +{ + kCurrentScoreSection= 0, + kScoreHandlingSection= 1, + kLeaderBoardSection= 2, + kShowViewControllersSection= 3 +}; + + +#define kNoScoreReusableCellID @"ReusableNoScoreCell" +#define kScoredReusableCellID @"ReusableScoreCell" +#define kDisclosureReusableCellID @"ReusableDisclosureCell" +#define kDisclosureWithLabelReusableCellID @"ReusableDisclosureWithLabelCell" + +@implementation TapperController + +@synthesize gameCenterManager; + +@synthesize gameButtonView; +@synthesize resetAchievementsView; + +@synthesize currentScore; +@synthesize cachedHighestScore; + +@synthesize personalBestScoreDescription; +@synthesize personalBestScoreString; +@synthesize leaderboardHighScoreDescription; +@synthesize leaderboardHighScoreString; + +@synthesize currentLeaderBoard; + +- (void) showAlertWithTitle: (NSString*) title message: (NSString*) message +{ + UIAlertView* alert= [[[UIAlertView alloc] initWithTitle: title message: message + delegate: NULL cancelButtonTitle: @"OK" otherButtonTitles: NULL] autorelease]; + [alert show]; + +} + + +#pragma mark Score Handlers +- (void) checkAchievements +{ + NSString* identifier= NULL; + double percentComplete= 0; + switch(self.currentScore) + { + case 1: + { + identifier= kAchievementGotOneTap; + percentComplete= 100.0; + break; + } + case 10: + { + identifier= kAchievementHidden20Taps; + percentComplete= 50.0; + break; + } + case 20: + { + identifier= kAchievementHidden20Taps; + percentComplete= 100.0; + break; + } + case 50: + { + identifier= kAchievementBigOneHundred; + percentComplete= 50.0; + break; + } + case 75: + { + identifier= kAchievementBigOneHundred; + percentComplete= 75.0; + break; + } + case 100: + { + identifier= kAchievementBigOneHundred; + percentComplete= 100.0; + break; + } + + } + if(identifier!= NULL) + { + [self.gameCenterManager submitAchievement: identifier percentComplete: percentComplete]; + } +} + +- (void) updateCurrentScore +{ + [self checkAchievements]; + [self.tableView reloadData]; +} + + + +- (NSString*) currentLeaderboardHumanName +{ + return NSLocalizedString(currentLeaderBoard, @"Mapping the Leaderboard IDS"); +} + +#pragma mark View Controller Methods +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad +{ + self.currentLeaderBoard= kEasyLeaderboardID; + + self.currentScore= 0; + + [super viewDidLoad]; + if([GameCenterManager isGameCenterAvailable]) + { + self.gameCenterManager= [[[GameCenterManager alloc] init] autorelease]; + [self.gameCenterManager setDelegate: self]; + [self.gameCenterManager authenticateLocalUser]; + + [self updateCurrentScore]; + } + else + { + [self showAlertWithTitle: @"Game Center Support Required!" + message: @"The current device does not support Game Center, which this sample requires."]; + } +} + +#pragma mark TableView Configuration + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 4; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + NSInteger rowCount= 0; + switch (section) + { + case kCurrentScoreSection: + rowCount= 1; + break; + case kScoreHandlingSection: + rowCount= 2; + break; + case kLeaderBoardSection: + rowCount= 3; + break; + case kShowViewControllersSection: + rowCount= 2; + break; + default: + assert(0);//Every section MUST define it's count. + break; + } + return rowCount; +} + +- (UITableViewCell*) getReusableCellForID: (NSString*) cellID +{ + UITableViewCell* retCell = [self.tableView dequeueReusableCellWithIdentifier:cellID]; + if([cellID isEqualToString: kScoredReusableCellID]) + { + if (retCell == NULL) + { + retCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kScoredReusableCellID] autorelease]; + retCell.selectionStyle= UITableViewCellSelectionStyleNone; + } + } + else if([cellID isEqualToString: kNoScoreReusableCellID]) + { + if (retCell == NULL) + { + retCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kNoScoreReusableCellID] autorelease]; + retCell.textLabel.textColor= achievementButton.currentTitleColor; + retCell.textLabel.font= achievementButton.titleLabel.font; + retCell.textLabel.textAlignment= achievementButton.titleLabel.textAlignment; + } + } + else if([cellID isEqualToString: kDisclosureReusableCellID]) + { + if (retCell == NULL) + { + retCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kDisclosureReusableCellID] autorelease]; + retCell.accessoryType= UITableViewCellAccessoryDisclosureIndicator; + } + } + else if([cellID isEqualToString: kDisclosureWithLabelReusableCellID]) + { + if (retCell == NULL) + { + retCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kDisclosureWithLabelReusableCellID] autorelease]; + retCell.accessoryType= UITableViewCellAccessoryDisclosureIndicator; + } + } + assert(retCell!= NULL); //Undefined reusable cell, should never happen. + return retCell; +} + +- (UITableViewCell*) tableCellForCurrentScoreSectionWithRow: (NSUInteger) rowNumber tableView: (UITableView *)tableView +{ + UITableViewCell *retCell= NULL; + switch (rowNumber) + { + case 0: + { + retCell= [self getReusableCellForID: kScoredReusableCellID]; + retCell.textLabel.text = @"Current Score"; + retCell.detailTextLabel.text= [NSString stringWithFormat: @"%ld", self.currentScore]; + break; + } + default: + { + assert(0);//The switch statement must define all rows! + } + } + return retCell; +} + +- (UITableViewCell*) tableCellForScoreHandlingSectionWithRow: (NSUInteger) rowNumber tableView: (UITableView *)tableView +{ + UITableViewCell *retCell= NULL; + switch (rowNumber) + { + case 0: + { + retCell= [self getReusableCellForID: kNoScoreReusableCellID]; + retCell.textLabel.text= @"Submit High Score..."; + break; + } + case 1: + { + retCell= [self getReusableCellForID: kNoScoreReusableCellID]; + retCell.textLabel.text= @"Increment Score..."; + break; + } + default: + { + assert(0);//The switch statement must define all rows! + } + } + return retCell; +} + +- (UITableViewCell*) tableCellForLeaderBoardSectionWithRow: (NSUInteger) rowNumber tableView: (UITableView *)tableView +{ + UITableViewCell *retCell= NULL; + switch (rowNumber) + { + case 0: + { + retCell= [self getReusableCellForID: kDisclosureWithLabelReusableCellID]; + retCell.textLabel.text = @"Leaderboard"; + retCell.detailTextLabel.text= [self currentLeaderboardHumanName]; + break; + } + case 1: + { + retCell= [self getReusableCellForID: kScoredReusableCellID]; + retCell.textLabel.text = personalBestScoreDescription; + retCell.detailTextLabel.text= personalBestScoreString; + break; + } + case 2: + { + retCell= [self getReusableCellForID: kScoredReusableCellID]; + retCell.textLabel.text = leaderboardHighScoreDescription; + retCell.detailTextLabel.text= leaderboardHighScoreString; + break; + } + default: + { + assert(0);//The switch statement must define all rows! + } + } + return retCell; +} + +- (UITableViewCell*) tableCellForViewControllerSectionWithRow: (NSUInteger) rowNumber tableView: (UITableView *)tableView +{ + UITableViewCell* retCell= [self getReusableCellForID: kDisclosureReusableCellID]; + switch (rowNumber) + { + case 0: + { + retCell.textLabel.text= @"Show Leaderboards"; + break; + } + case 1: + { + retCell.textLabel.text= @"Show Achievements"; + break; + } + default: + { + assert(0);//The switch statement must define all rows! + } + } + return retCell; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSUInteger sectionNumber= [indexPath indexAtPosition: 0]; + NSUInteger rowNumber= [indexPath indexAtPosition: 1]; + + UITableViewCell *retCell= NULL; + switch (sectionNumber) + { + case kCurrentScoreSection: + { + retCell= [self tableCellForCurrentScoreSectionWithRow: rowNumber tableView: tableView]; + break; + } + case kScoreHandlingSection: + { + retCell= [self tableCellForScoreHandlingSectionWithRow: rowNumber tableView: tableView]; + break; + } + case kLeaderBoardSection: + { + retCell= [self tableCellForLeaderBoardSectionWithRow: rowNumber tableView: tableView]; + break; + } + case kShowViewControllersSection: + { + retCell= [self tableCellForViewControllerSectionWithRow: rowNumber tableView: tableView]; + break; + } + default: + assert(0); //All cells should be explicitly defined. + break; + } + return retCell; +} + +#pragma mark TableView Footer Configuration + +static const CGFloat kGapViewHeight= 2.f; +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section +{ + CGFloat retVal= kGapViewHeight; + switch (section) + { + case kShowViewControllersSection: + retVal= resetAchievementsView.frame.size.height; + break; + } + return retVal; +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section +{ + static UIView* gapView= NULL; + if(NULL == gapView) + { + gapView= [[UIView alloc] initWithFrame: CGRectMake(resetAchievementsView.frame.origin.x, resetAchievementsView.frame.origin.y, resetAchievementsView.frame.size.width, kGapViewHeight)]; + } + UIView* retVal= gapView; + switch (section) + { + case kShowViewControllersSection: + retVal= resetAchievementsView; + break; + } + return retVal; +} + +#pragma mark TableView Selection Handler +- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + switch(buttonIndex) + { + case 0: + currentLeaderBoard = kAwesomeLeaderboardID; + break; + case 1: + currentLeaderBoard = kHardLeaderboardID; + break; + case 2: + currentLeaderBoard = kEasyLeaderboardID; + break; + case 3: //Cancel... + return; + default: + assert(0); //This should never happen... + break; + } + self.currentScore= 0; + [self.gameCenterManager reloadHighScoresForCategory: self.currentLeaderBoard]; + [self.tableView reloadData]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSUInteger sectionNumber= [indexPath indexAtPosition: 0]; + NSUInteger rowNumber= [indexPath indexAtPosition: 1]; + + switch (sectionNumber) + { + case kScoreHandlingSection: + { + if(rowNumber == 0) + { + [self submitHighScore]; + } + else + { + if(rowNumber == 1) + { + [self addOne]; + } + } + break; + } + case kLeaderBoardSection: + { + if(rowNumber == 0) + { + UIActionSheet* selectLeaderboard= [[[UIActionSheet alloc] initWithTitle: @"Select Leaderboard" delegate:self cancelButtonTitle: @"Cancel" destructiveButtonTitle: NULL + otherButtonTitles: [NSString stringWithFormat: @"%@ Leaderboard", NSLocalizedString(kAwesomeLeaderboardID, NULL)], + [NSString stringWithFormat: @"%@ Leaderboard", NSLocalizedString(kHardLeaderboardID, NULL)], + [NSString stringWithFormat: @"%@ Leaderboard", NSLocalizedString(kEasyLeaderboardID, NULL)], NULL] autorelease]; + [selectLeaderboard showInView: self.view]; + } + [self.tableView deselectRowAtIndexPath: indexPath animated: NO]; + break; + } + case kShowViewControllersSection: + { + if(rowNumber== 0) + { + [self showLeaderboard]; + } + else + { + [self showAchievements]; + } + break; + } + default: + [self.tableView deselectRowAtIndexPath: indexPath animated: NO]; + break; + } +} + + + + + +#pragma mark Action Methods +- (void) addOne; +{ + self.currentScore= self.currentScore + 1; + [self updateCurrentScore]; +} + +- (void) submitHighScore +{ + if(self.currentScore > 0) + { + [self.gameCenterManager reportScore: self.currentScore forCategory: self.currentLeaderBoard]; + } +} + +#pragma mark GameCenter View Controllers +- (void) showLeaderboard; +{ + GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init]; + if (leaderboardController != NULL) + { + leaderboardController.category = self.currentLeaderBoard; + leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime; + leaderboardController.leaderboardDelegate = self; + [self presentModalViewController: leaderboardController animated: YES]; + } +} + +- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController +{ + [self dismissModalViewControllerAnimated: YES]; + [viewController release]; +} + +- (void) showAchievements +{ + GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init]; + if (achievements != NULL) + { + achievements.achievementDelegate = self; + [self presentModalViewController: achievements animated: YES]; + } +} + +- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController; +{ + [self dismissModalViewControllerAnimated: YES]; + [viewController release]; +} + +- (IBAction) resetAchievements: (id) sender +{ + [gameCenterManager resetAchievements]; +} + + +#pragma mark GameCenterDelegateProtocol Methods +//Delegate method used by processGameCenterAuth to support looping waiting for game center authorization +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [self.gameCenterManager authenticateLocalUser]; +} + +- (void) processGameCenterAuth: (NSError*) error +{ + if(error == NULL) + { + [self.gameCenterManager reloadHighScoresForCategory: self.currentLeaderBoard]; + } + else + { + UIAlertView* alert= [[[UIAlertView alloc] initWithTitle: @"Game Center Account Required" + message: [NSString stringWithFormat: @"Reason: %@", [error localizedDescription]] + delegate: self cancelButtonTitle: @"Try Again..." otherButtonTitles: NULL] autorelease]; + [alert show]; + } + +} + +- (void) mappedPlayerIDToPlayer: (GKPlayer*) player error: (NSError*) error; +{ + if((error == NULL) && (player != NULL)) + { + self.leaderboardHighScoreDescription= [NSString stringWithFormat: @"%@ got:", player.alias]; + + if(self.cachedHighestScore != NULL) + { + self.leaderboardHighScoreString= self.cachedHighestScore; + } + else + { + self.leaderboardHighScoreString= @"-"; + } + + } + else + { + self.leaderboardHighScoreDescription= @"GameCenter Scores Unavailable"; + self.leaderboardHighScoreDescription= @"-"; + } + [self.tableView reloadData]; +} + +- (void) reloadScoresComplete: (GKLeaderboard*) leaderBoard error: (NSError*) error; +{ + if(error == NULL) + { + int64_t personalBest= leaderBoard.localPlayerScore.value; + self.personalBestScoreDescription= @"Your Best:"; + self.personalBestScoreString= [NSString stringWithFormat: @"%ld", personalBest]; + if([leaderBoard.scores count] >0) + { + self.leaderboardHighScoreDescription= @"-"; + self.leaderboardHighScoreString= @""; + GKScore* allTime= [leaderBoard.scores objectAtIndex: 0]; + self.cachedHighestScore= allTime.formattedValue; + [gameCenterManager mapPlayerIDtoPlayer: allTime.playerID]; + } + } + else + { + self.personalBestScoreDescription= @"GameCenter Scores Unavailable"; + self.personalBestScoreString= @"-"; + self.leaderboardHighScoreDescription= @"GameCenter Scores Unavailable"; + self.leaderboardHighScoreDescription= @"-"; + [self showAlertWithTitle: @"Score Reload Failed!" + message: [NSString stringWithFormat: @"Reason: %@", [error localizedDescription]]]; + } + [self.tableView reloadData]; +} + +- (void) scoreReported: (NSError*) error; +{ + if(error == NULL) + { + [self.gameCenterManager reloadHighScoresForCategory: self.currentLeaderBoard]; + [self showAlertWithTitle: @"High Score Reported!" + message: [NSString stringWithFormat: @"", [error localizedDescription]]]; + } + else + { + [self showAlertWithTitle: @"Score Report Failed!" + message: [NSString stringWithFormat: @"Reason: %@", [error localizedDescription]]]; + } +} + + + +- (void) achievementSubmitted: (GKAchievement*) ach error:(NSError*) error; +{ + if((error == NULL) && (ach != NULL)) + { + if(ach.percentComplete == 100.0) + { + [self showAlertWithTitle: @"Achievement Earned!" + message: [NSString stringWithFormat: @"Great job! You earned an achievement: \"%@\"", NSLocalizedString(ach.identifier, NULL)]]; + } + else + { + if(ach.percentComplete > 0) + { + [self showAlertWithTitle: @"Achievement Progress!" + message: [NSString stringWithFormat: @"Great job! You're %.0f\%% of the way to: \"%@\"",ach.percentComplete, NSLocalizedString(ach.identifier, NULL)]]; + } + } + } + else + { + [self showAlertWithTitle: @"Achievement Submission Failed!" + message: [NSString stringWithFormat: @"Reason: %@", [error localizedDescription]]]; + } +} + +- (void) achievementResetResult: (NSError*) error; +{ + self.currentScore= 0; + [self.tableView reloadData]; + if(error != NULL) + { + [self showAlertWithTitle: @"Achievement Reset Failed!" + message: [NSString stringWithFormat: @"Reason: %@", [error localizedDescription]]]; + } +} +@end diff --git a/GKTapper/GKTapper-Info.plist b/GKTapper/GKTapper-Info.plist new file mode 100644 index 0000000..2213fc8 --- /dev/null +++ b/GKTapper/GKTapper-Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small@2x.png + Icon-Small-50.png + + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.appledts.GKTapper + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/GKTapper/GKTapper.xcodeproj/project.pbxproj b/GKTapper/GKTapper.xcodeproj/project.pbxproj new file mode 100755 index 0000000..d3a80f1 --- /dev/null +++ b/GKTapper/GKTapper.xcodeproj/project.pbxproj @@ -0,0 +1,343 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 0205CAC412288963001C721C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0205CAC312288963001C721C /* MainWindow.xib */; }; + 0205CAC61228896D001C721C /* TapperView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0205CAC51228896D001C721C /* TapperView.xib */; }; + 0205CACB12288A30001C721C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0205CAC912288A30001C721C /* Localizable.strings */; }; + 022943AF12146AC700762B2E /* GameCenterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 022943AE12146AC700762B2E /* GameCenterManager.m */; }; + 0265FFAF1210A23F00926E28 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0265FFAE1210A23F00926E28 /* GameKit.framework */; }; + 02AFF2F4122C145F0052B79E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 02AFF2F3122C145F0052B79E /* main.m */; }; + 02AFF2F7122C14670052B79E /* TapperAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 02AFF2F6122C14670052B79E /* TapperAppDelegate.m */; }; + 02AFF40D122C55E30052B79E /* Read Me About GKTapper.txt in Resources */ = {isa = PBXBuildFile; fileRef = 02AFF40C122C55E30052B79E /* Read Me About GKTapper.txt */; }; + 02D8DC76121B370C00778432 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC6C121B370C00778432 /* Icon-72.png */; }; + 02D8DC77121B370C00778432 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC6D121B370C00778432 /* Icon-Small-50.png */; }; + 02D8DC78121B370C00778432 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC6E121B370C00778432 /* Icon-Small.png */; }; + 02D8DC79121B370C00778432 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC6F121B370C00778432 /* Icon-Small@2x.png */; }; + 02D8DC7A121B370C00778432 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC70121B370C00778432 /* Icon.png */; }; + 02D8DC7B121B370C00778432 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC71121B370C00778432 /* Icon@2x.png */; }; + 02D8DC7C121B370C00778432 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 02D8DC72121B370C00778432 /* iTunesArtwork */; }; + 02FF000A1215DE8700F72039 /* TapperController.m in Sources */ = {isa = PBXBuildFile; fileRef = 02FF00081215DE8700F72039 /* TapperController.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0205CACA12288A30001C721C /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = Resources/English.lproj/Localizable.strings; sourceTree = ""; }; + 022943AD12146AC700762B2E /* GameCenterManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameCenterManager.h; sourceTree = ""; }; + 022943AE12146AC700762B2E /* GameCenterManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GameCenterManager.m; sourceTree = ""; }; + 026500DB1210C03C00926E28 /* AppSpecificValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppSpecificValues.h; path = Classes/AppSpecificValues.h; sourceTree = ""; }; + 0265FFAE1210A23F00926E28 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; }; + 02AFF2F3122C145F0052B79E /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = "Ancillary Code/main.m"; sourceTree = ""; }; + 02AFF2F5122C14670052B79E /* TapperAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TapperAppDelegate.h; path = "Ancillary Code/TapperAppDelegate.h"; sourceTree = ""; }; + 02AFF2F6122C14670052B79E /* TapperAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TapperAppDelegate.m; path = "Ancillary Code/TapperAppDelegate.m"; sourceTree = ""; }; + 02AFF346122C17E60052B79E /* GKTapper_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKTapper_Prefix.pch; sourceTree = ""; }; + 02AFF40C122C55E30052B79E /* Read Me About GKTapper.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Read Me About GKTapper.txt"; sourceTree = ""; }; + 02D8DC6B121B370C00778432 /* GKTapper-Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = "GKTapper-Info.plist"; sourceTree = ""; }; + 02D8DC6C121B370C00778432 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Resources/Icon-72.png"; sourceTree = ""; }; + 02D8DC6D121B370C00778432 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Resources/Icon-Small-50.png"; sourceTree = ""; }; + 02D8DC6E121B370C00778432 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Resources/Icon-Small.png"; sourceTree = ""; }; + 02D8DC6F121B370C00778432 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Resources/Icon-Small@2x.png"; sourceTree = ""; }; + 02D8DC70121B370C00778432 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Resources/Icon.png; sourceTree = ""; }; + 02D8DC71121B370C00778432 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Resources/Icon@2x.png"; sourceTree = ""; }; + 02D8DC72121B370C00778432 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Resources/iTunesArtwork; sourceTree = ""; }; + 02D8DC73121B370C00778432 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/MainWindow.xib; sourceTree = ""; }; + 02D8DC74121B370C00778432 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/TapperView.xib; sourceTree = ""; }; + 02FF00071215DE8700F72039 /* TapperController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TapperController.h; sourceTree = ""; }; + 02FF00081215DE8700F72039 /* TapperController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TapperController.m; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* GKTapper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GKTapper.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 0265FFAF1210A23F00926E28 /* GameKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 02D8DCA3121B396500778432 /* Icons */ = { + isa = PBXGroup; + children = ( + 02D8DC6C121B370C00778432 /* Icon-72.png */, + 02D8DC6D121B370C00778432 /* Icon-Small-50.png */, + 02D8DC6E121B370C00778432 /* Icon-Small.png */, + 02D8DC6F121B370C00778432 /* Icon-Small@2x.png */, + 02D8DC70121B370C00778432 /* Icon.png */, + 02D8DC71121B370C00778432 /* Icon@2x.png */, + 02D8DC72121B370C00778432 /* iTunesArtwork */, + ); + name = Icons; + sourceTree = ""; + }; + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 02FF00071215DE8700F72039 /* TapperController.h */, + 02FF00081215DE8700F72039 /* TapperController.m */, + 022943AD12146AC700762B2E /* GameCenterManager.h */, + 022943AE12146AC700762B2E /* GameCenterManager.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GKTapper.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 02AFF40C122C55E30052B79E /* Read Me About GKTapper.txt */, + 026500DB1210C03C00926E28 /* AppSpecificValues.h */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 02AFF2F5122C14670052B79E /* TapperAppDelegate.h */, + 02AFF2F6122C14670052B79E /* TapperAppDelegate.m */, + 02AFF2F3122C145F0052B79E /* main.m */, + 02AFF346122C17E60052B79E /* GKTapper_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 02D8DC6B121B370C00778432 /* GKTapper-Info.plist */, + 0205CAC312288963001C721C /* MainWindow.xib */, + 0205CAC51228896D001C721C /* TapperView.xib */, + 02D8DCA3121B396500778432 /* Icons */, + 0205CAC912288A30001C721C /* Localizable.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0265FFAE1210A23F00926E28 /* GameKit.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GKTapper */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GKTapper" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GKTapper; + productName = "GameCenter Test"; + productReference = 1D6058910D05DD3D006BFB54 /* GKTapper.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GKTapper" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GKTapper */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 02D8DC76121B370C00778432 /* Icon-72.png in Resources */, + 02D8DC77121B370C00778432 /* Icon-Small-50.png in Resources */, + 02D8DC78121B370C00778432 /* Icon-Small.png in Resources */, + 02D8DC79121B370C00778432 /* Icon-Small@2x.png in Resources */, + 02D8DC7A121B370C00778432 /* Icon.png in Resources */, + 02D8DC7B121B370C00778432 /* Icon@2x.png in Resources */, + 02D8DC7C121B370C00778432 /* iTunesArtwork in Resources */, + 0205CAC412288963001C721C /* MainWindow.xib in Resources */, + 0205CAC61228896D001C721C /* TapperView.xib in Resources */, + 0205CACB12288A30001C721C /* Localizable.strings in Resources */, + 02AFF40D122C55E30052B79E /* Read Me About GKTapper.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 022943AF12146AC700762B2E /* GameCenterManager.m in Sources */, + 02FF000A1215DE8700F72039 /* TapperController.m in Sources */, + 02AFF2F4122C145F0052B79E /* main.m in Sources */, + 02AFF2F7122C14670052B79E /* TapperAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 0205CAC312288963001C721C /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 02D8DC73121B370C00778432 /* English */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 0205CAC51228896D001C721C /* TapperView.xib */ = { + isa = PBXVariantGroup; + children = ( + 02D8DC74121B370C00778432 /* English */, + ); + name = TapperView.xib; + sourceTree = ""; + }; + 0205CAC912288A30001C721C /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 0205CACA12288A30001C721C /* English */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GKTapper_Prefix.pch; + INFOPLIST_FILE = "GKTapper-Info.plist"; + INFOPLIST_OUTPUT_FORMAT = binary; + PRODUCT_NAME = GKTapper; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GKTapper_Prefix.pch; + INFOPLIST_FILE = "GKTapper-Info.plist"; + INFOPLIST_OUTPUT_FORMAT = binary; + PRODUCT_NAME = GKTapper; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = "GKTapper-Info.plist"; + PREBINDING = NO; + PROVISIONING_PROFILE = ""; + SDKROOT = iphoneos; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = "GKTapper-Info.plist"; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + PROVISIONING_PROFILE = ""; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GKTapper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GKTapper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GKTapper/GKTapper_Prefix.pch b/GKTapper/GKTapper_Prefix.pch new file mode 100644 index 0000000..be50df8 --- /dev/null +++ b/GKTapper/GKTapper_Prefix.pch @@ -0,0 +1,51 @@ +/* + + File: GKTapper_Prefix.pch + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/GKTapper/Read Me About GKTapper.txt b/GKTapper/Read Me About GKTapper.txt new file mode 100644 index 0000000..fe901cc --- /dev/null +++ b/GKTapper/Read Me About GKTapper.txt @@ -0,0 +1,52 @@ +Read Me About GKTapper +=========================================================================== +GKTapper is a sample application that shows how to support GameCenter +Leaderboards and Achievements. It also demonstrates using +GKLeaderboardViewController and GKAchievementViewController to display this +data. + +IMPORTANT: When adding support for Game Center to an application, it is not +enough to simply add the necessary code to your application. You will also +need to configure your app in iTunes Connect to match your desired +configuration. For example, the file "Classes/AppSpecificValues.h" contains +a number of constants that are configured to match the App ID configured in +iTunes Connect. Without this configuration, the GKTapper sample would not +function. If you run into any issues with Game Center be sure that you +confirm that your applications configuration matches you iTunes Connect +configuration. + +=========================================================================== +BUILD REQUIREMENTS: + +This project was built with Xcode 3.2.4 and iOS SDK 4.1 + +=========================================================================== +RUNTIME REQUIREMENTS: + +The project requires iOS 4.1 and a GameCenter account to run. + +=========================================================================== +PACKAGING LIST: +- Read Me About GKRTapper.txt -- This file. +- GKTapper.xcodeproj -- Xcode project for this sample. +- Resources -- The project nib, images, and so on. +- Classes/AppSpecificValues.h -- Header file that contains all of the iTunes + Connect constants for this project. See this file for more details + regarding iTunes Connect configuration. +- Classes/GameCenterManager.[h,m] -- Class containing most of the GameCenter + code. Shows how to update Leaderboards and Achievements. +- Classes/TapperController.[h,m] -- Controller class for the project. + Contains all UI code, drives GameCenterManager, and also shows how to use + GKLeaderboardViewController and GKAchievementViewController. +- Ancillary Code -- A directory full of code that's not directly relevant to + the main function of this sample. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +1.0: (Aug 2010) First shipping version. +1.1: (Nov 2010) Fixed bug in how the "submitAchievement:" method handles the + "earnedAchievementCache". + +=========================================================================== +Copyright (C) 2010 Apple Inc. All rights reserved. diff --git a/GKTapper/Resources/English.lproj/Localizable.strings b/GKTapper/Resources/English.lproj/Localizable.strings new file mode 100644 index 0000000..e0d974f --- /dev/null +++ b/GKTapper/Resources/English.lproj/Localizable.strings @@ -0,0 +1,55 @@ +/* + + File: AppSpecificValues.h + Abstract: Basic introduction to GameCenter + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +"com.appledts.EasyTapList" = "Easy"; +"com.appledts.HardTapList" = "Hard"; +"com.appledts.AwesomeTapList" = "Awesome"; + +"com.appletest.one_tap" = "Just One Tap"; +"com.appledts.twenty_taps" = "Twenty Taps In"; +"com.appledts.one_hundred_taps" = "The Big One Hundred"; \ No newline at end of file diff --git a/GKTapper/Resources/English.lproj/MainWindow.xib b/GKTapper/Resources/English.lproj/MainWindow.xib new file mode 100644 index 0000000..9588568 --- /dev/null +++ b/GKTapper/Resources/English.lproj/MainWindow.xib @@ -0,0 +1,534 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + TapperView + + + 1 + + IBCocoaTouchFramework + NO + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + IBCocoaTouchFramework + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 14 + + + + viewController + + + + 17 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + TapperAppDelegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + TapperController + {{234, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TapperAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 17 + + + + YES + + TapperAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + TapperController + UIWindow + + + + YES + + YES + viewController + window + + + YES + + viewController + TapperController + + + window + UIWindow + + + + + IBProjectSource + Classes/TapperAppDelegate.h + + + + TapperController + UIViewController + + YES + + YES + addOne: + resetAchievements: + showAchievements: + showLeaderboard: + submitHighScore: + + + YES + id + id + id + id + id + + + + YES + + YES + addOne: + resetAchievements: + showAchievements: + showLeaderboard: + submitHighScore: + + + YES + + addOne: + id + + + resetAchievements: + id + + + showAchievements: + id + + + showLeaderboard: + id + + + submitHighScore: + id + + + + + YES + + YES + mCurrentScoreField + mHighScoreField + + + YES + UITextField + UITextField + + + + YES + + YES + mCurrentScoreField + mHighScoreField + + + YES + + mCurrentScoreField + UITextField + + + mHighScoreField + UITextField + + + + + IBProjectSource + Classes/TapperController.h + + + + UIWindow + UIView + + IBUserSource + + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextField + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + GKTapper.xcodeproj + 3 + 123 + + diff --git a/GKTapper/Resources/English.lproj/TapperView.xib b/GKTapper/Resources/English.lproj/TapperView.xib new file mode 100644 index 0000000..4806308 --- /dev/null +++ b/GKTapper/Resources/English.lproj/TapperView.xib @@ -0,0 +1,555 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {857, 723} + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + YES + IBCocoaTouchFramework + YES + 1 + 2 + 0 + YES + 44 + 10 + 10 + + + + 292 + + YES + + + 292 + {{8, 8}, {304, 40}} + + NO + IBCocoaTouchFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + Reset Score and Achievements + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + + {320, 48} + + + 3 + MSAwAA + + IBCocoaTouchFramework + + + + + YES + + + dataSource + + + + 74 + + + + delegate + + + + 75 + + + + achievementButton + + + + 92 + + + + resetAchievements: + + + 7 + + 93 + + + + view + + + + 94 + + + + resetAchievementsView + + + + 95 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 71 + + + + + 76 + + + YES + + + + + + 77 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 71.IBEditorWindowLastContentRect + 71.IBPluginDependency + 71.IBViewBoundsToFrameTransform + 76.IBEditorWindowLastContentRect + 76.IBPluginDependency + 76.IBViewBoundsToFrameTransform + 77.IBPluginDependency + 77.IBViewBoundsToFrameTransform + + + YES + TapperController + UIResponder + {{86, 382}, {857, 723}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAAAAAAAAxDRAAA + + {{256, 946}, {320, 48}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAAAAAAAAwpwAAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAABBoAAAwhgAAA + + + + + YES + + + YES + + + + + YES + + + YES + + + + 95 + + + + YES + + TapperController + UITableViewController + + resetAchievements: + id + + + resetAchievements: + + resetAchievements: + id + + + + YES + + YES + achievementButton + resetAchievementsView + + + YES + UIButton + UIView + + + + YES + + YES + achievementButton + resetAchievementsView + + + YES + + achievementButton + UIButton + + + resetAchievementsView + UIView + + + + + IBProjectSource + Classes/TapperController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../GKTapper.xcodeproj + 3 + 123 + + diff --git a/GKTapper/Resources/Icon-72.png b/GKTapper/Resources/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GKTapper/Resources/Icon-72.png differ diff --git a/GKTapper/Resources/Icon-Small-50.png b/GKTapper/Resources/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GKTapper/Resources/Icon-Small-50.png differ diff --git a/GKTapper/Resources/Icon-Small.png b/GKTapper/Resources/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GKTapper/Resources/Icon-Small.png differ diff --git a/GKTapper/Resources/Icon-Small@2x.png b/GKTapper/Resources/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GKTapper/Resources/Icon-Small@2x.png differ diff --git a/GKTapper/Resources/Icon.png b/GKTapper/Resources/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GKTapper/Resources/Icon.png differ diff --git a/GKTapper/Resources/Icon@2x.png b/GKTapper/Resources/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GKTapper/Resources/Icon@2x.png differ diff --git a/GKTapper/Resources/iTunesArtwork b/GKTapper/Resources/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GKTapper/Resources/iTunesArtwork differ diff --git a/GLES2Sample.zip b/GLES2Sample.zip new file mode 100644 index 0000000..8d289b6 Binary files /dev/null and b/GLES2Sample.zip differ diff --git a/GLES2Sample/Classes/EAGLView.h b/GLES2Sample/Classes/EAGLView.h new file mode 100644 index 0000000..a54a40f --- /dev/null +++ b/GLES2Sample/Classes/EAGLView.h @@ -0,0 +1,81 @@ +/* + + File: EAGLView.h + + Abstract: The EAGLView class is a UIView subclass that renders OpenGL scene. + If the current hardware supports OpenGL ES 2.0, it draws using OpenGL ES 2.0; + otherwise it draws using OpenGL ES 1.1. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import + +#import "ESRenderer.h" + +// This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. +// The view content is basically an EAGL surface you render your OpenGL scene into. +// Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. +@interface EAGLView : UIView +{ +@private + id renderer; + + BOOL animating; + BOOL displayLinkSupported; + NSInteger animationFrameInterval; + // Use of the CADisplayLink class is the preferred method for controlling your animation timing. + // CADisplayLink will link to the main display and fire every vsync when added to a given run-loop. + // The NSTimer class is used only as fallback when running on a pre 3.1 device where CADisplayLink + // isn't available. + id displayLink; + NSTimer *animationTimer; +} + +@property (readonly, nonatomic, getter=isAnimating) BOOL animating; +@property (nonatomic) NSInteger animationFrameInterval; + +- (void) startAnimation; +- (void) stopAnimation; +- (void) drawView:(id)sender; + +@end diff --git a/GLES2Sample/Classes/EAGLView.m b/GLES2Sample/Classes/EAGLView.m new file mode 100644 index 0000000..e2937fb --- /dev/null +++ b/GLES2Sample/Classes/EAGLView.m @@ -0,0 +1,192 @@ +/* + + File: EAGLView.m + + Abstract: The EAGLView class is a UIView subclass that renders OpenGL scene. + If the current hardware supports OpenGL ES 2.0, it draws using OpenGL ES 2.0; + otherwise it draws using OpenGL ES 1.1. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "EAGLView.h" + +#import "ES1Renderer.h" +#import "ES2Renderer.h" + +@implementation EAGLView + +@synthesize animating; +@dynamic animationFrameInterval; + +// You must implement this method ++ (Class) layerClass +{ + return [CAEAGLLayer class]; +} + +//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id) initWithCoder:(NSCoder*)coder +{ + if ((self = [super initWithCoder:coder])) + { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + renderer = [[ES2Renderer alloc] init]; + + if (!renderer) + { + renderer = [[ES1Renderer alloc] init]; + + if (!renderer) + { + [self release]; + return nil; + } + } + + animating = FALSE; + displayLinkSupported = FALSE; + animationFrameInterval = 1; + displayLink = nil; + animationTimer = nil; + + // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer + // class is used as fallback when it isn't available. + NSString *reqSysVer = @"3.1"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) + displayLinkSupported = TRUE; + } + + return self; +} + +- (void) drawView:(id)sender +{ + [renderer render]; +} + +- (void) layoutSubviews +{ + [renderer resizeFromLayer:(CAEAGLLayer*)self.layer]; + [self drawView:nil]; +} + +- (NSInteger) animationFrameInterval +{ + return animationFrameInterval; +} + +- (void) setAnimationFrameInterval:(NSInteger)frameInterval +{ + // Frame interval defines how many display frames must pass between each time the + // display link fires. The display link will only fire 30 times a second when the + // frame internal is two on a display that refreshes 60 times a second. The default + // frame interval setting of one will fire 60 times a second when the display refreshes + // at 60 times a second. A frame interval setting of less than one results in undefined + // behavior. + if (frameInterval >= 1) + { + animationFrameInterval = frameInterval; + + if (animating) + { + [self stopAnimation]; + [self startAnimation]; + } + } +} + +- (void) startAnimation +{ + if (!animating) + { + if (displayLinkSupported) + { + // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed + // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will + // not be called in system versions earlier than 3.1. + + displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)]; + [displayLink setFrameInterval:animationFrameInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } + else + animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE]; + + animating = TRUE; + } +} + +- (void)stopAnimation +{ + if (animating) + { + if (displayLinkSupported) + { + [displayLink invalidate]; + displayLink = nil; + } + else + { + [animationTimer invalidate]; + animationTimer = nil; + } + + animating = FALSE; + } +} + +- (void) dealloc +{ + [renderer release]; + + [super dealloc]; +} + +@end diff --git a/GLES2Sample/Classes/ES1Renderer.h b/GLES2Sample/Classes/ES1Renderer.h new file mode 100644 index 0000000..32283fe --- /dev/null +++ b/GLES2Sample/Classes/ES1Renderer.h @@ -0,0 +1,71 @@ +/* + + File: ES1Renderer.h + + Abstract: The ES1Renderer class creates an OpenGL ES 1.1 context and draws + using OpenGL ES 1.1 functions. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "ESRenderer.h" + +#import +#import + +@interface ES1Renderer : NSObject +{ +@private + EAGLContext *context; + + // The pixel dimensions of the CAEAGLLayer + GLint backingWidth; + GLint backingHeight; + + // The OpenGL names for the framebuffer and renderbuffer used to render to this view + GLuint defaultFramebuffer, colorRenderbuffer; +} + +- (void) render; +- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer; + +@end diff --git a/GLES2Sample/Classes/ES1Renderer.m b/GLES2Sample/Classes/ES1Renderer.m new file mode 100644 index 0000000..b0524c4 --- /dev/null +++ b/GLES2Sample/Classes/ES1Renderer.m @@ -0,0 +1,162 @@ +/* + + File: ES1Renderer.m + + Abstract: The ES1Renderer class creates an OpenGL ES 1.1 context and draws + using OpenGL ES 1.1 functions. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "ES1Renderer.h" + +@implementation ES1Renderer + +// Create an ES 1.1 context +- (id ) init +{ + if (self = [super init]) + { + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if (!context || ![EAGLContext setCurrentContext:context]) + { + [self release]; + return nil; + } + + // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer + glGenFramebuffersOES(1, &defaultFramebuffer); + glGenRenderbuffersOES(1, &colorRenderbuffer); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); + } + + return self; +} + +- (void) render { + + // Replace the implementation of this method to do your own custom drawing + + const GLfloat squareVertices[] = { + -0.5f, -0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + }; + const GLubyte squareColors[] = { + 255, 255, 0, 255, + 0, 255, 255, 255, + 0, 0, 0, 0, + 255, 0, 255, 255, + }; + + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); + glViewport(0, 0, backingWidth, backingHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); + glRotatef(3.0f, 0.0f, 0.0f, 1.0f); + + glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glVertexPointer(2, GL_FLOAT, 0, squareVertices); + glEnableClientState(GL_VERTEX_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); + glEnableClientState(GL_COLOR_ARRAY); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer +{ + // Allocate color buffer backing based on the current layer size + glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer]; + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) + { + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + +- (void) dealloc +{ + // Tear down GL + if (defaultFramebuffer) + { + glDeleteFramebuffersOES(1, &defaultFramebuffer); + defaultFramebuffer = 0; + } + + if (colorRenderbuffer) + { + glDeleteRenderbuffersOES(1, &colorRenderbuffer); + colorRenderbuffer = 0; + } + + // Tear down context + if ([EAGLContext currentContext] == context) + [EAGLContext setCurrentContext:nil]; + + [context release]; + context = nil; + + [super dealloc]; +} + +@end diff --git a/GLES2Sample/Classes/ES2Renderer.h b/GLES2Sample/Classes/ES2Renderer.h new file mode 100644 index 0000000..6c2b457 --- /dev/null +++ b/GLES2Sample/Classes/ES2Renderer.h @@ -0,0 +1,78 @@ +/* + + File: ES2Renderer.h + + Abstract: The ES2Renderer class creates an OpenGL ES 2.0 context and draws + using OpenGL ES 2.0 shaders. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "ESRenderer.h" + +#import +#import + +@interface ES2Renderer : NSObject +{ +@private + EAGLContext *context; + + // The pixel dimensions of the CAEAGLLayer + GLint backingWidth; + GLint backingHeight; + + // The OpenGL names for the framebuffer and renderbuffer used to render to this view + GLuint defaultFramebuffer, colorRenderbuffer; + + /* the shader program object */ + GLuint program; + + GLfloat rotz; + +} + +- (void) render; +- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer; + +@end + diff --git a/GLES2Sample/Classes/ES2Renderer.m b/GLES2Sample/Classes/ES2Renderer.m new file mode 100644 index 0000000..12efe4e --- /dev/null +++ b/GLES2Sample/Classes/ES2Renderer.m @@ -0,0 +1,266 @@ +/* + + File: ES2Renderer.m + + Abstract: The ES2Renderer class creates an OpenGL ES 2.0 context and draws + using OpenGL ES 2.0 shaders. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "ES2Renderer.h" +#import "Shaders.h" +#include "matrix.h" + +// uniform index +enum { + UNIFORM_MODELVIEW_PROJECTION_MATRIX, + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// attribute index +enum { + ATTRIB_VERTEX, + ATTRIB_COLOR, + NUM_ATTRIBUTES +}; + +@interface ES2Renderer (PrivateMethods) +- (BOOL) loadShaders; +@end + +@implementation ES2Renderer + +// Create an ES 2.0 context +- (id ) init +{ + if (self = [super init]) + { + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!context || ![EAGLContext setCurrentContext:context] || ![self loadShaders]) + { + [self release]; + return nil; + } + + // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer + glGenFramebuffers(1, &defaultFramebuffer); + glGenRenderbuffers(1, &colorRenderbuffer); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); + } + + return self; +} + +- (void)render { + + // Replace the implementation of this method to do your own custom drawing + + const GLfloat squareVertices[] = { + -0.5f, -0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + }; + const GLubyte squareColors[] = { + 255, 255, 0, 255, + 0, 255, 255, 255, + 0, 0, 0, 0, + 255, 0, 255, 255, + }; + + [EAGLContext setCurrentContext:context]; + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); + glViewport(0, 0, backingWidth, backingHeight); + + glClearColor(0.5f, 0.4f, 0.5f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // use shader program + glUseProgram(program); + + // handle viewing matrices + GLfloat proj[16], modelview[16], modelviewProj[16]; + // setup projection matrix (orthographic) + mat4f_LoadOrtho(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f, proj); + // setup modelview matrix (rotate around z) + mat4f_LoadZRotation(rotz, modelview); + // projection matrix * modelview matrix + mat4f_MultiplyMat4f(proj, modelview, modelviewProj); + rotz += 3.0f * M_PI / 180.0f; + + // update uniform values + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_PROJECTION_MATRIX], 1, GL_FALSE, modelviewProj); + + // update attribute values + glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); + glEnableVertexAttribArray(ATTRIB_VERTEX); + glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors); //enable the normalized flag + glEnableVertexAttribArray(ATTRIB_COLOR); + + // Validate program before drawing. This is a good check, but only really necessary in a debug build. + // DEBUG macro must be defined in your debug configurations if that's not already the case. +#if defined(DEBUG) + if (![self validateProgram:program]) + { + NSLog(@"Failed to validate program: %d", program); + return; + } +#endif + + // draw + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER]; +} + +- (BOOL)loadShaders { + + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // create shader program + program = glCreateProgram(); + + // create and compile vertex shader + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"template" ofType:@"vsh"]; + if (!compileShader(&vertShader, GL_VERTEX_SHADER, 1, vertShaderPathname)) { + destroyShaders(vertShader, fragShader, program); + return NO; + } + + // create and compile fragment shader + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"template" ofType:@"fsh"]; + if (!compileShader(&fragShader, GL_FRAGMENT_SHADER, 1, fragShaderPathname)) { + destroyShaders(vertShader, fragShader, program); + return NO; + } + + // attach vertex shader to program + glAttachShader(program, vertShader); + + // attach fragment shader to program + glAttachShader(program, fragShader); + + // bind attribute locations + // this needs to be done prior to linking + glBindAttribLocation(program, ATTRIB_VERTEX, "position"); + glBindAttribLocation(program, ATTRIB_COLOR, "color"); + + // link program + if (!linkProgram(program)) { + destroyShaders(vertShader, fragShader, program); + return NO; + } + + // get uniform locations + uniforms[UNIFORM_MODELVIEW_PROJECTION_MATRIX] = glGetUniformLocation(program, "modelViewProjectionMatrix"); + + // release vertex and fragment shaders + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + + return YES; +} + +- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer +{ + // Allocate color buffer backing based on the current layer size + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + return NO; + } + + return YES; +} + +- (void) dealloc +{ + // tear down GL + if (defaultFramebuffer) + { + glDeleteFramebuffers(1, &defaultFramebuffer); + defaultFramebuffer = 0; + } + + if (colorRenderbuffer) + { + glDeleteRenderbuffers(1, &colorRenderbuffer); + colorRenderbuffer = 0; + } + + // realease the shader program object + if (program) + { + glDeleteProgram(program); + program = 0; + } + + // tear down context + if ([EAGLContext currentContext] == context) + [EAGLContext setCurrentContext:nil]; + + [context release]; + context = nil; + + [super dealloc]; +} + +@end diff --git a/GLES2Sample/Classes/ESRenderer.h b/GLES2Sample/Classes/ESRenderer.h new file mode 100644 index 0000000..c44f042 --- /dev/null +++ b/GLES2Sample/Classes/ESRenderer.h @@ -0,0 +1,62 @@ +/* + + File: ESRenderer.h + + Abstract: A protocol that defines the functions the ES1Renderer and ES2Renderer + classes must implement. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import + +#import +#import + +@protocol ESRenderer + +- (void)render; +- (BOOL)resizeFromLayer:(CAEAGLLayer*)layer; + +@end + + diff --git a/GLES2Sample/Classes/GLES2SampleAppDelegate.h b/GLES2Sample/Classes/GLES2SampleAppDelegate.h new file mode 100644 index 0000000..bf1822a --- /dev/null +++ b/GLES2Sample/Classes/GLES2SampleAppDelegate.h @@ -0,0 +1,62 @@ +/* + + File: GLES2SampleAppDelegate.h + + Abstract: The app delegate that ties everything together. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class EAGLView; + +@interface GLES2SampleAppDelegate : NSObject { + UIWindow *window; + EAGLView *glView; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet EAGLView *glView; + +@end + diff --git a/GLES2Sample/Classes/GLES2SampleAppDelegate.m b/GLES2Sample/Classes/GLES2SampleAppDelegate.m new file mode 100644 index 0000000..e373461 --- /dev/null +++ b/GLES2Sample/Classes/GLES2SampleAppDelegate.m @@ -0,0 +1,85 @@ +/* + + File: GLES2SampleAppDelegate.m + + Abstract: The app delegate that ties everything together. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "GLES2SampleAppDelegate.h" +#import "EAGLView.h" + +@implementation GLES2SampleAppDelegate + +@synthesize window; +@synthesize glView; + +- (void) applicationDidFinishLaunching:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void) applicationWillResignActive:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) applicationDidBecomeActive:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) dealloc +{ + [window release]; + [glView release]; + + [super dealloc]; +} + +@end diff --git a/GLES2Sample/Classes/Shaders.h b/GLES2Sample/Classes/Shaders.h new file mode 100644 index 0000000..a77dc67 --- /dev/null +++ b/GLES2Sample/Classes/Shaders.h @@ -0,0 +1,62 @@ +/* + + File: Shaders.h + + Abstract: Shader utilities for compiling, linking and validating shaders. + It is important to check the result status. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#ifndef SHADERS_H +#define SHADERS_H + +#include +#include + +/* Shader Utilities */ +GLint compileShader(GLuint *shader, GLenum type, GLsizei count, NSString *file); +GLint linkProgram(GLuint prog); +GLint validateProgram(GLuint prog); +void destroyShaders(GLuint vertShader, GLuint fragShader, GLuint prog); + +#endif /* SHADERS_H */ diff --git a/GLES2Sample/Classes/Shaders.m b/GLES2Sample/Classes/Shaders.m new file mode 100644 index 0000000..e5fec29 --- /dev/null +++ b/GLES2Sample/Classes/Shaders.m @@ -0,0 +1,159 @@ +/* + + File: Shaders.m + + Abstract: Shader utilities for compiling, linking and validating shaders. + It is important to check the result status. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#import "Shaders.h" + +/* Create and compile a shader from the provided source(s) */ +GLint compileShader(GLuint *shader, GLenum type, GLsizei count, NSString *file) +{ + GLint status; + const GLchar *sources; + + // get source code + sources = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!sources) + { + NSLog(@"Failed to load vertex shader"); + return 0; + } + + *shader = glCreateShader(type); // create shader + glShaderSource(*shader, 1, &sources, NULL); // set source code in the shader + glCompileShader(*shader); // compile shader + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) + { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) + { + NSLog(@"Failed to compile shader:\n"); + int i; + for (i = 0; i < count; i++) + NSLog(@"%s", sources[i]); + } + + return status; +} + + +/* Link a program with all currently attached shaders */ +GLint linkProgram(GLuint prog) +{ + GLint status; + + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) + { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == GL_FALSE) + NSLog(@"Failed to link program %d", prog); + + return status; +} + + +/* Validate a program (for i.e. inconsistent samplers) */ +GLint validateProgram(GLuint prog) +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) + { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == GL_FALSE) + NSLog(@"Failed to validate program %d", prog); + + return status; +} + +/* delete shader resources */ +void destroyShaders(GLuint vertShader, GLuint fragShader, GLuint prog) +{ + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (prog) { + glDeleteProgram(prog); + prog = 0; + } +} diff --git a/GLES2Sample/Classes/matrix.c b/GLES2Sample/Classes/matrix.c new file mode 100644 index 0000000..93ba0a2 --- /dev/null +++ b/GLES2Sample/Classes/matrix.c @@ -0,0 +1,284 @@ +/* + + File: matrix.c + + Abstract: simple 4x4 matrix computations + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#include +#include +#include "matrix.h" + +/* + NOTE: These functions are created for your convenience but the matrix algorithms + are not optimized. You are encouraged to do additional research on your own to + implement a more robust numerical algorithm. +*/ + +void mat4f_LoadIdentity(float* m) +{ + m[0] = 1.0f; + m[1] = 0.0f; + m[2] = 0.0f; + m[3] = 0.0f; + + m[4] = 0.0f; + m[5] = 1.0f; + m[6] = 0.0f; + m[7] = 0.0f; + + m[8] = 0.0f; + m[9] = 0.0f; + m[10] = 1.0f; + m[11] = 0.0f; + + m[12] = 0.0f; + m[13] = 0.0f; + m[14] = 0.0f; + m[15] = 1.0f; +} + +// s is a 3D vector +void mat4f_LoadScale(float* s, float* m) +{ + m[0] = s[0]; + m[1] = 0.0f; + m[2] = 0.0f; + m[3] = 0.0f; + + m[4] = 0.0f; + m[5] = s[1]; + m[6] = 0.0f; + m[7] = 0.0f; + + m[8] = 0.0f; + m[9] = 0.0f; + m[10] = s[2]; + m[11] = 0.0f; + + m[12] = 0.0f; + m[13] = 0.0f; + m[14] = 0.0f; + m[15] = 1.0f; +} + +void mat4f_LoadXRotation(float radians, float* m) +{ + float cosrad = cosf(radians); + float sinrad = sinf(radians); + + m[0] = 1.0f; + m[1] = 0.0f; + m[2] = 0.0f; + m[3] = 0.0f; + + m[4] = 0.0f; + m[5] = cosrad; + m[6] = sinrad; + m[7] = 0.0f; + + m[8] = 0.0f; + m[9] = -sinrad; + m[10] = cosrad; + m[11] = 0.0f; + + m[12] = 0.0f; + m[13] = 0.0f; + m[14] = 0.0f; + m[15] = 1.0f; +} + +void mat4f_LoadYRotation(float radians, float* mout) +{ + float cosrad = cosf(radians); + float sinrad = sinf(radians); + + mout[0] = cosrad; + mout[1] = 0.0f; + mout[2] = -sinrad; + mout[3] = 0.0f; + + mout[4] = 0.0f; + mout[5] = 1.0f; + mout[6] = 0.0f; + mout[7] = 0.0f; + + mout[8] = sinrad; + mout[9] = 0.0f; + mout[10] = cosrad; + mout[11] = 0.0f; + + mout[12] = 0.0f; + mout[13] = 0.0f; + mout[14] = 0.0f; + mout[15] = 1.0f; +} + +void mat4f_LoadZRotation(float radians, float* mout) +{ + float cosrad = cosf(radians); + float sinrad = sinf(radians); + + mout[0] = cosrad; + mout[1] = sinrad; + mout[2] = 0.0f; + mout[3] = 0.0f; + + mout[4] = -sinrad; + mout[5] = cosrad; + mout[6] = 0.0f; + mout[7] = 0.0f; + + mout[8] = 0.0f; + mout[9] = 0.0f; + mout[10] = 1.0f; + mout[11] = 0.0f; + + mout[12] = 0.0f; + mout[13] = 0.0f; + mout[14] = 0.0f; + mout[15] = 1.0f; +} + +// v is a 3D vector +void mat4f_LoadTranslation(float* v, float* mout) +{ + mout[0] = 1.0f; + mout[1] = 0.0f; + mout[2] = 0.0f; + mout[3] = 0.0f; + + mout[4] = 0.0f; + mout[5] = 1.0f; + mout[6] = 0.0f; + mout[7] = 0.0f; + + mout[8] = 0.0f; + mout[9] = 0.0f; + mout[10] = 1.0f; + mout[11] = 0.0f; + + mout[12] = v[0]; + mout[13] = v[1]; + mout[14] = v[2]; + mout[15] = 1.0f; +} + +void mat4f_LoadPerspective(float fov_radians, float aspect, float zNear, float zFar, float* mout) +{ + float f = 1.0f / tanf(fov_radians/2.0f); + + mout[0] = f / aspect; + mout[1] = 0.0f; + mout[2] = 0.0f; + mout[3] = 0.0f; + + mout[4] = 0.0f; + mout[5] = f; + mout[6] = 0.0f; + mout[7] = 0.0f; + + mout[8] = 0.0f; + mout[9] = 0.0f; + mout[10] = (zFar+zNear) / (zNear-zFar); + mout[11] = -1.0f; + + mout[12] = 0.0f; + mout[13] = 0.0f; + mout[14] = 2 * zFar * zNear / (zNear-zFar); + mout[15] = 0.0f; +} + +void mat4f_LoadOrtho(float left, float right, float bottom, float top, float near, float far, float* mout) +{ + float r_l = right - left; + float t_b = top - bottom; + float f_n = far - near; + float tx = - (right + left) / (right - left); + float ty = - (top + bottom) / (top - bottom); + float tz = - (far + near) / (far - near); + + mout[0] = 2.0f / r_l; + mout[1] = 0.0f; + mout[2] = 0.0f; + mout[3] = 0.0f; + + mout[4] = 0.0f; + mout[5] = 2.0f / t_b; + mout[6] = 0.0f; + mout[7] = 0.0f; + + mout[8] = 0.0f; + mout[9] = 0.0f; + mout[10] = -2.0f / f_n; + mout[11] = 0.0f; + + mout[12] = tx; + mout[13] = ty; + mout[14] = tz; + mout[15] = 1.0f; +} + +void mat4f_MultiplyMat4f(const float* a, const float* b, float* mout) +{ + mout[0] = a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3]; + mout[1] = a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3]; + mout[2] = a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3]; + mout[3] = a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3]; + + mout[4] = a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7]; + mout[5] = a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7]; + mout[6] = a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7]; + mout[7] = a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7]; + + mout[8] = a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11]; + mout[9] = a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11]; + mout[10] = a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11]; + mout[11] = a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11]; + + mout[12] = a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15]; + mout[13] = a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15]; + mout[14] = a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15]; + mout[15] = a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]; +} diff --git a/GLES2Sample/Classes/matrix.h b/GLES2Sample/Classes/matrix.h new file mode 100644 index 0000000..1afa612 --- /dev/null +++ b/GLES2Sample/Classes/matrix.h @@ -0,0 +1,66 @@ +/* + + File: matrix.h + + Abstract: simple 4x4 matrix computations + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + +*/ + +#ifndef MATRIX_H +#define MATRIX_H + +void mat4f_LoadIdentity(float* m); +void mat4f_LoadScale(float* s, float* m); + +void mat4f_LoadXRotation(float radians, float* mout); +void mat4f_LoadYRotation(float radians, float* mout); +void mat4f_LoadZRotation(float radians, float* mout); + +void mat4f_LoadTranslation(float* t, float* mout); + +void mat4f_LoadPerspective(float fov_radians, float aspect, float zNear, float zFar, float* mout); +void mat4f_LoadOrtho(float left, float right, float bottom, float top, float near, float far, float* mout); + +void mat4f_MultiplyMat4f(const float* a, const float* b, float* mout); + +#endif /* MATRIX_H */ \ No newline at end of file diff --git a/GLES2Sample/GLES2Sample-Info.plist b/GLES2Sample/GLES2Sample-Info.plist new file mode 100644 index 0000000..0ba1273 --- /dev/null +++ b/GLES2Sample/GLES2Sample-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/GLES2Sample/GLES2Sample.xcodeproj/lsang.mode1v3 b/GLES2Sample/GLES2Sample.xcodeproj/lsang.mode1v3 new file mode 100644 index 0000000..39df2bb --- /dev/null +++ b/GLES2Sample/GLES2Sample.xcodeproj/lsang.mode1v3 @@ -0,0 +1,1426 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + AF1AED23101E689600EFB8CB + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + active-combo-popup + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-goOrGo + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 296 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + 29B97315FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + AF1AED3F101E69BE00EFB8CB + 29B97323FDCFA39411CA2CEA + 1C37FBAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 17 + 13 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {296, 760}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {313, 778}} + GroupTreeTableConfiguration + + MainColumn + 296 + + RubberWindowFrame + 228 59 1172 819 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 313pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + main.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + main.m + _historyCapacity + 0 + bookmark + AF416C241044ADF600735770 + history + + AF1AED64101E6AEA00EFB8CB + AF1AED90101E6AF900EFB8CB + AF1AED91101E6AF900EFB8CB + AF1AED94101E6AF900EFB8CB + AF1AED95101E6AF900EFB8CB + AF1AEDC6101E6FEE00EFB8CB + AF46FBF8103204F200FB1AF3 + AF46FBF9103204F200FB1AF3 + AF46FC1A1032099400FB1AF3 + AF46FC1B1032099400FB1AF3 + AF46FC1C1032099400FB1AF3 + AF46FC1D1032099400FB1AF3 + AF46FC1E1032099400FB1AF3 + AF46FC1F1032099400FB1AF3 + AF416C211044ADF600735770 + AF416C221044ADF600735770 + + prevStack + + AF1AED2D101E694300EFB8CB + AF1AED4C101E69EA00EFB8CB + AF1AED67101E6AEA00EFB8CB + AF1AED68101E6AEA00EFB8CB + AF1AED69101E6AEA00EFB8CB + AF1AED6A101E6AEA00EFB8CB + AF1AED6B101E6AEA00EFB8CB + AF1AED71101E6AEA00EFB8CB + AF1AED72101E6AEA00EFB8CB + AF1AED73101E6AEA00EFB8CB + AF1AED74101E6AEA00EFB8CB + AF1AED75101E6AEA00EFB8CB + AF46FC241032099400FB1AF3 + AF46FC251032099400FB1AF3 + AF46FC271032099400FB1AF3 + AF416C231044ADF600735770 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {854, 652}} + RubberWindowFrame + 228 59 1172 819 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 652pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 657}, {854, 121}} + RubberWindowFrame + 228 59 1172 819 0 0 1440 878 + + Module + XCDetailModule + Proportion + 121pt + + + Proportion + 854pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + AF416C251044ADF600735770 + 1CE0B1FE06471DED0097A5F4 + AF416C261044ADF600735770 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + /Users/lsang/DTS/SampleCodeEdit/samplecode/G/GLES2Sample/GLES2Sample.xcodeproj + + WindowString + 228 59 1172 819 0 0 1440 878 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 1129 772 500 500 0 0 2560 1578 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 1129 772 500 500 0 0 2560 1578 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + AF1AED50101E69EA00EFB8CB + AF9A70B710320F020087DFF9 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowString + 1129 772 500 500 0 0 2560 1578 + WindowToolGUID + AF1AED50101E69EA00EFB8CB + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 201}} + {{316, 0}, {378, 201}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 201}} + {{0, 201}, {694, 180}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 201}} + RubberWindowFrame + 1129 850 694 422 0 0 2560 1578 + + RubberWindowFrame + 1129 850 694 422 0 0 2560 1578 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + AF9A70B810320F020087DFF9 + 1C162984064C10D400B95A72 + AF9A70B910320F020087DFF9 + AF9A70BA10320F020087DFF9 + AF9A70BB10320F020087DFF9 + AF9A70BC10320F020087DFF9 + AF9A70BD10320F020087DFF9 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 1129 850 694 422 0 0 2560 1578 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 209}} + RubberWindowFrame + 1129 1022 650 250 0 0 2560 1578 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + AF9A70BE10320F020087DFF9 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 1129 1022 650 250 0 0 2560 1578 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/GLES2Sample/GLES2Sample.xcodeproj/project.pbxproj b/GLES2Sample/GLES2Sample.xcodeproj/project.pbxproj new file mode 100755 index 0000000..e833b9a --- /dev/null +++ b/GLES2Sample/GLES2Sample.xcodeproj/project.pbxproj @@ -0,0 +1,324 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* GLES2SampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* GLES2SampleAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28FD14FD0DC6FC130079059D /* EAGLView.m */; }; + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; }; + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; }; + AF1AED39101E699D00EFB8CB /* ES1Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = AF1AED33101E699D00EFB8CB /* ES1Renderer.m */; }; + AF1AED3A101E699D00EFB8CB /* ES2Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = AF1AED35101E699D00EFB8CB /* ES2Renderer.m */; }; + AF1AED3B101E699D00EFB8CB /* Shaders.m in Sources */ = {isa = PBXBuildFile; fileRef = AF1AED38101E699D00EFB8CB /* Shaders.m */; }; + AF1AED3E101E69AD00EFB8CB /* matrix.c in Sources */ = {isa = PBXBuildFile; fileRef = AF1AED3C101E69AD00EFB8CB /* matrix.c */; }; + AF1AED42101E69BE00EFB8CB /* template.fsh in Resources */ = {isa = PBXBuildFile; fileRef = AF1AED40101E69BE00EFB8CB /* template.fsh */; }; + AF1AED43101E69BE00EFB8CB /* template.vsh in Resources */ = {isa = PBXBuildFile; fileRef = AF1AED41101E69BE00EFB8CB /* template.vsh */; }; + AFC29B8911D56BC3006F150F /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8211D56BC3006F150F /* Icon-72.png */; }; + AFC29B8A11D56BC3006F150F /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8311D56BC3006F150F /* Icon-Small-50.png */; }; + AFC29B8B11D56BC3006F150F /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8411D56BC3006F150F /* Icon-Small.png */; }; + AFC29B8C11D56BC3006F150F /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8511D56BC3006F150F /* Icon-Small@2x.png */; }; + AFC29B8D11D56BC3006F150F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8611D56BC3006F150F /* Icon.png */; }; + AFC29B8E11D56BC3006F150F /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8711D56BC3006F150F /* Icon@2x.png */; }; + AFC29B8F11D56BC3006F150F /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = AFC29B8811D56BC3006F150F /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* GLES2SampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLES2SampleAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* GLES2SampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLES2SampleAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* GLES2Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLES2Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 28FD14FC0DC6FC130079059D /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; + 28FD14FD0DC6FC130079059D /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = ""; }; + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* GLES2Sample_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLES2Sample_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* GLES2Sample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GLES2Sample-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + AF1AED32101E699D00EFB8CB /* ES1Renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ES1Renderer.h; sourceTree = ""; }; + AF1AED33101E699D00EFB8CB /* ES1Renderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ES1Renderer.m; sourceTree = ""; }; + AF1AED34101E699D00EFB8CB /* ES2Renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ES2Renderer.h; sourceTree = ""; }; + AF1AED35101E699D00EFB8CB /* ES2Renderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ES2Renderer.m; sourceTree = ""; }; + AF1AED36101E699D00EFB8CB /* ESRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESRenderer.h; sourceTree = ""; }; + AF1AED37101E699D00EFB8CB /* Shaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shaders.h; sourceTree = ""; }; + AF1AED38101E699D00EFB8CB /* Shaders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Shaders.m; sourceTree = ""; }; + AF1AED3C101E69AD00EFB8CB /* matrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = matrix.c; path = Classes/matrix.c; sourceTree = ""; }; + AF1AED3D101E69AD00EFB8CB /* matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = matrix.h; path = Classes/matrix.h; sourceTree = ""; }; + AF1AED40101E69BE00EFB8CB /* template.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = template.fsh; sourceTree = ""; }; + AF1AED41101E69BE00EFB8CB /* template.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = template.vsh; sourceTree = ""; }; + AFC29B8211D56BC3006F150F /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + AFC29B8311D56BC3006F150F /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + AFC29B8411D56BC3006F150F /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + AFC29B8511D56BC3006F150F /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + AFC29B8611D56BC3006F150F /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + AFC29B8711D56BC3006F150F /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + AFC29B8811D56BC3006F150F /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */, + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + AF1AED32101E699D00EFB8CB /* ES1Renderer.h */, + AF1AED33101E699D00EFB8CB /* ES1Renderer.m */, + AF1AED34101E699D00EFB8CB /* ES2Renderer.h */, + AF1AED35101E699D00EFB8CB /* ES2Renderer.m */, + AF1AED36101E699D00EFB8CB /* ESRenderer.h */, + AF1AED37101E699D00EFB8CB /* Shaders.h */, + AF1AED38101E699D00EFB8CB /* Shaders.m */, + 28FD14FC0DC6FC130079059D /* EAGLView.h */, + 28FD14FD0DC6FC130079059D /* EAGLView.m */, + 1D3623240D0F684500981E51 /* GLES2SampleAppDelegate.h */, + 1D3623250D0F684500981E51 /* GLES2SampleAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GLES2Sample.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + AF1AED3D101E69AD00EFB8CB /* matrix.h */, + AF1AED3C101E69AD00EFB8CB /* matrix.c */, + 32CA4F630368D1EE00C91783 /* GLES2Sample_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + AFC29B8211D56BC3006F150F /* Icon-72.png */, + AFC29B8311D56BC3006F150F /* Icon-Small-50.png */, + AFC29B8411D56BC3006F150F /* Icon-Small.png */, + AFC29B8511D56BC3006F150F /* Icon-Small@2x.png */, + AFC29B8611D56BC3006F150F /* Icon.png */, + AFC29B8711D56BC3006F150F /* Icon@2x.png */, + AFC29B8811D56BC3006F150F /* iTunesArtwork */, + AF1AED3F101E69BE00EFB8CB /* Shaders */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* GLES2Sample-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + AF1AED3F101E69BE00EFB8CB /* Shaders */ = { + isa = PBXGroup; + children = ( + AF1AED40101E69BE00EFB8CB /* template.fsh */, + AF1AED41101E69BE00EFB8CB /* template.vsh */, + ); + name = Shaders; + path = Resources/Shaders; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GLES2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLES2" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GLES2; + productName = GLES2Sample; + productReference = 1D6058910D05DD3D006BFB54 /* GLES2Sample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLES2Sample" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GLES2 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + AF1AED42101E69BE00EFB8CB /* template.fsh in Resources */, + AF1AED43101E69BE00EFB8CB /* template.vsh in Resources */, + AFC29B8911D56BC3006F150F /* Icon-72.png in Resources */, + AFC29B8A11D56BC3006F150F /* Icon-Small-50.png in Resources */, + AFC29B8B11D56BC3006F150F /* Icon-Small.png in Resources */, + AFC29B8C11D56BC3006F150F /* Icon-Small@2x.png in Resources */, + AFC29B8D11D56BC3006F150F /* Icon.png in Resources */, + AFC29B8E11D56BC3006F150F /* Icon@2x.png in Resources */, + AFC29B8F11D56BC3006F150F /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* GLES2SampleAppDelegate.m in Sources */, + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */, + AF1AED39101E699D00EFB8CB /* ES1Renderer.m in Sources */, + AF1AED3A101E699D00EFB8CB /* ES2Renderer.m in Sources */, + AF1AED3B101E699D00EFB8CB /* Shaders.m in Sources */, + AF1AED3E101E69AD00EFB8CB /* matrix.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GLES2Sample_Prefix.pch; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "GLES2Sample-Info.plist"; + PRODUCT_NAME = GLES2Sample; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GLES2Sample_Prefix.pch; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "GLES2Sample-Info.plist"; + PRODUCT_NAME = GLES2Sample; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLES2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLES2Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GLES2Sample/GLES2Sample_Prefix.pch b/GLES2Sample/GLES2Sample_Prefix.pch new file mode 100644 index 0000000..e412a3d --- /dev/null +++ b/GLES2Sample/GLES2Sample_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'GLES2Sample' target in the 'GLES2Sample' project +// + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/GLES2Sample/Images/Icon-72.png b/GLES2Sample/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GLES2Sample/Images/Icon-72.png differ diff --git a/GLES2Sample/Images/Icon-Small-50.png b/GLES2Sample/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GLES2Sample/Images/Icon-Small-50.png differ diff --git a/GLES2Sample/Images/Icon-Small.png b/GLES2Sample/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GLES2Sample/Images/Icon-Small.png differ diff --git a/GLES2Sample/Images/Icon-Small@2x.png b/GLES2Sample/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GLES2Sample/Images/Icon-Small@2x.png differ diff --git a/GLES2Sample/Images/Icon.png b/GLES2Sample/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GLES2Sample/Images/Icon.png differ diff --git a/GLES2Sample/Images/Icon@2x.png b/GLES2Sample/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GLES2Sample/Images/Icon@2x.png differ diff --git a/GLES2Sample/Images/iTunesArtwork b/GLES2Sample/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GLES2Sample/Images/iTunesArtwork differ diff --git a/GLES2Sample/MainWindow.xib b/GLES2Sample/MainWindow.xib new file mode 100644 index 0000000..2561da8 --- /dev/null +++ b/GLES2Sample/MainWindow.xib @@ -0,0 +1,233 @@ + + + + 768 + 10A288 + 715 + 1010 + 411.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 46 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + + -1 + + + File's Owner + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLES2SampleAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 9 + + + + YES + + EAGLView + UIView + + IBProjectSource + Classes/EAGLView.h + + + + GLES2SampleAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + EAGLView + UIWindow + + + + IBProjectSource + Classes/GLES2SampleAppDelegate.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + GLES2Sample.xcodeproj + 3 + + diff --git a/GLES2Sample/ReadMe.txt b/GLES2Sample/ReadMe.txt new file mode 100644 index 0000000..485e099 --- /dev/null +++ b/GLES2Sample/ReadMe.txt @@ -0,0 +1,58 @@ +GLES2Sample + +================================================================================ +DESCRIPTION: + +iPhone 3GS supports both OpenGL ES 1.1 and 2.0. This sample demonstrates how to create an OpenGL ES 1.1 and 2.0 compatible project. When running on 1st generation iPhone, iPhone 3G, and 1st and 2nd generation iPod touch the sample draws using OpenGL ES 1.1; when running on iPhone 3GS and 3rd generation iPod touch, the sample draws using OpenGL ES 2.0. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +ESRenderer.h +A protocol that defines the functions the ES1Renderer and ES2Renderer classes must implement. + +ES1Renderer.h +ES1Renderer.m +The ES1Renderer class creates an OpenGL ES 1.1 context and draws using OpenGL ES 1.1 functions. + +ES2Renderer.h +ES2Renderer.m +The ES2Renderer class creates an OpenGL ES 2.0 context and draws using OpenGL ES 2.0 shaders. + +Shaders.h +Shaders.m +Include shader utilities for compiling, linking and validating shaders. It is important to check the result status. + +EAGLView.h +EAGLView.m +The EAGLView class is a UIView subclass that renders OpenGL scene. The sample first tries to allocate an OpenGL ES 2.0 context, if fails it falls back to create an OpenGL ES 1.1 context. + +GLES2SampleAppDelegate.h +GLES2SampleAppDelegate.m +The GLES2SampleAppDelegate class is the app delegate that ties everything together. + +matrix.h +matrix.m +Include wrapper functions to create scaling, rotation and translation matrices, orthographic and perspective projection matrices. Also include a function to compute 4x4 matrix multiplication. + +template.vsh +A vertex shader that implements the drawing in the OpenGL ES project template. + +template.fsh +A fragment shader that implements the drawing in the OpenGL ES project template. + +================================================================================ +REVISION HISTORY: +1.1. Upgraded project to build with the iOS 4.0 SDK +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/GLES2Sample/Resources/Shaders/template.fsh b/GLES2Sample/Resources/Shaders/template.fsh new file mode 100644 index 0000000..8d7e0f0 --- /dev/null +++ b/GLES2Sample/Resources/Shaders/template.fsh @@ -0,0 +1,11 @@ +#ifdef GL_ES +// define default precision for float, vec, mat. +precision highp float; +#endif + +varying vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/GLES2Sample/Resources/Shaders/template.vsh b/GLES2Sample/Resources/Shaders/template.vsh new file mode 100644 index 0000000..b2676c3 --- /dev/null +++ b/GLES2Sample/Resources/Shaders/template.vsh @@ -0,0 +1,12 @@ +attribute vec4 position; +attribute vec4 color; + +uniform mat4 modelViewProjectionMatrix; + +varying vec4 colorVarying; + +void main() +{ + gl_Position = modelViewProjectionMatrix * position; + colorVarying = color; +} diff --git a/GLES2Sample/main.m b/GLES2Sample/main.m new file mode 100644 index 0000000..cdfc93c --- /dev/null +++ b/GLES2Sample/main.m @@ -0,0 +1,54 @@ +// File: main.m +// Abstract: n/a +// Version: 1.1 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +// Inc. ("Apple") in consideration of your agreement to the following +// terms, and your use, installation, modification or redistribution of +// this Apple software constitutes acceptance of these terms. If you do +// not agree with these terms, please do not use, install, modify or +// redistribute this Apple software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non-exclusive +// license, under Apple's copyrights in this original Apple software (the +// "Apple Software"), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and/or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following +// text and disclaimers in all such redistributions of the Apple Software. +// Neither the name, trademarks, service marks or logos of Apple Inc. may +// be used to endorse or promote products derived from the Apple Software +// without specific prior written permission from Apple. Except as +// expressly stated in this notice, no other rights or licenses, express or +// implied, are granted by Apple herein, including but not limited to any +// patent rights that may be infringed by your derivative works or by other +// works in which the Apple Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE +// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (C) 2010 Apple Inc. All Rights Reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GLGravity.zip b/GLGravity.zip new file mode 100644 index 0000000..469376a Binary files /dev/null and b/GLGravity.zip differ diff --git a/GLGravity/Classes/GLGravityAppDelegate.h b/GLGravity/Classes/GLGravityAppDelegate.h new file mode 100644 index 0000000..24d732d --- /dev/null +++ b/GLGravity/Classes/GLGravityAppDelegate.h @@ -0,0 +1,64 @@ +/* + File: GLGravityAppDelegate.h + Abstract: The GLGravityAppDelegate class is the app delegate that ties + everything together. It updates the acceletometer values used to draw + OpenGL content in the GLGravityView class. + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class GLGravityView; + +@interface GLGravityAppDelegate : NSObject { + UIWindow *window; + GLGravityView *glView; + UIAccelerationValue accel[3]; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet GLGravityView *glView; + +@end + diff --git a/GLGravity/Classes/GLGravityAppDelegate.m b/GLGravity/Classes/GLGravityAppDelegate.m new file mode 100644 index 0000000..36f71eb --- /dev/null +++ b/GLGravity/Classes/GLGravityAppDelegate.m @@ -0,0 +1,105 @@ +/* + File: GLGravityAppDelegate.m + Abstract: The GLGravityAppDelegate class is the app delegate that ties + everything together. It updates the acceletometer values used to draw + OpenGL content in the GLGravityView class. + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "GLGravityAppDelegate.h" +#import "GLGravityView.h" + +// CONSTANTS +#define kAccelerometerFrequency 100.0 // Hz +#define kFilteringFactor 0.1 + +@implementation GLGravityAppDelegate + +@synthesize window; +@synthesize glView; + +- (void) applicationDidFinishLaunching:(UIApplication *)application +{ + [glView startAnimation]; + + //Configure and start accelerometer + [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)]; + [[UIAccelerometer sharedAccelerometer] setDelegate:self]; +} + +- (void) applicationWillResignActive:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) applicationDidBecomeActive:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) dealloc +{ + [window release]; + [glView release]; + + [super dealloc]; +} + +- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration +{ + //Use a basic low-pass filter to only keep the gravity in the accelerometer values + accel[0] = acceleration.x * kFilteringFactor + accel[0] * (1.0 - kFilteringFactor); + accel[1] = acceleration.y * kFilteringFactor + accel[1] * (1.0 - kFilteringFactor); + accel[2] = acceleration.z * kFilteringFactor + accel[2] * (1.0 - kFilteringFactor); + + //Update the accelerometer values for the view + [glView setAccel:accel]; +} + +@end diff --git a/GLGravity/Classes/GLGravityView.h b/GLGravity/Classes/GLGravityView.h new file mode 100644 index 0000000..fe22378 --- /dev/null +++ b/GLGravity/Classes/GLGravityView.h @@ -0,0 +1,93 @@ +/* + File: GLGravityView.h + Abstract: This class wraps the CAEAGLLayer from CoreAnimation into a convenient + UIView subclass. The view content is basically an EAGL surface you render your + OpenGL scene into. Note that setting the view non-opaque will only work if the + EAGL surface has an alpha channel. + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import +#import +#import + +@interface GLGravityView : UIView +{ +@private + // The pixel dimensions of the backbuffer + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + + // OpenGL names for the renderbuffer and framebuffers used to render to this view + GLuint viewRenderbuffer, viewFramebuffer; + + // OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) + GLuint depthRenderbuffer; + + BOOL animating; + BOOL displayLinkSupported; + NSInteger animationFrameInterval; + // Use of the CADisplayLink class is the preferred method for controlling your animation timing. + // CADisplayLink will link to the main display and fire every vsync when added to a given run-loop. + // The NSTimer class is used only as fallback when running on a pre 3.1 device where CADisplayLink + // isn't available. + id displayLink; + NSTimer *animationTimer; + + UIAccelerationValue *accel; +} + +@property (readonly, nonatomic, getter=isAnimating) BOOL animating; +@property (nonatomic) NSInteger animationFrameInterval; + +@property (nonatomic) UIAccelerationValue *accel; + +-(void)startAnimation; +-(void)stopAnimation; +-(void)drawView; + +@end diff --git a/GLGravity/Classes/GLGravityView.m b/GLGravity/Classes/GLGravityView.m new file mode 100644 index 0000000..aa27538 --- /dev/null +++ b/GLGravity/Classes/GLGravityView.m @@ -0,0 +1,378 @@ +/* + File: GLGravityView.m + Abstract: This class wraps the CAEAGLLayer from CoreAnimation into a convenient + UIView subclass. The view content is basically an EAGL surface you render your + OpenGL scene into. Note that setting the view non-opaque will only work if the + EAGL surface has an alpha channel. + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "GLGravityView.h" +#import "teapot.h" + +// CONSTANTS +#define kTeapotScale 3.0 + +// MACROS +#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI) + +// A class extension to declare private methods +@interface GLGravityView (private) + +- (BOOL)createFramebuffer; +- (void)destroyFramebuffer; +- (void)setupView; + +@end + +@implementation GLGravityView + +@synthesize animating; +@dynamic animationFrameInterval; +@synthesize accel; + +// Implement this to override the default layer class (which is [CALayer class]). +// We do this so that our view will be backed by a layer that is capable of OpenGL ES rendering. ++ (Class) layerClass +{ + return [CAEAGLLayer class]; +} + +// The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder { + + if ((self = [super initWithCoder:coder])) { + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if (!context || ![EAGLContext setCurrentContext:context]) { + [self release]; + return nil; + } + + animating = FALSE; + displayLinkSupported = FALSE; + animationFrameInterval = 1; + displayLink = nil; + animationTimer = nil; + + // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer + // class is used as fallback when it isn't available. + NSString *reqSysVer = @"3.1"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) + displayLinkSupported = TRUE; + + accel = calloc(3, sizeof(UIAccelerationValue)); + + [self setupView]; + } + + return self; +} + +-(void)setupView +{ + const GLfloat lightAmbient[] = {0.2, 0.2, 0.2, 1.0}; + const GLfloat lightDiffuse[] = {1.0, 0.6, 0.0, 1.0}; + const GLfloat matAmbient[] = {0.6, 0.6, 0.6, 1.0}; + const GLfloat matDiffuse[] = {1.0, 1.0, 1.0, 1.0}; + const GLfloat matSpecular[] = {1.0, 1.0, 1.0, 1.0}; + const GLfloat lightPosition[] = {0.0, 0.0, 1.0, 0.0}; + const GLfloat lightShininess = 100.0, + zNear = 0.1, + zFar = 1000.0, + fieldOfView = 60.0; + GLfloat size; + + //Configure OpenGL lighting + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, lightShininess); + glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + //Configure OpenGL arrays + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glVertexPointer(3 ,GL_FLOAT, 0, teapot_vertices); + glNormalPointer(GL_FLOAT, 0, teapot_normals); + glEnable(GL_NORMALIZE); + + //Set the OpenGL projection matrix + glMatrixMode(GL_PROJECTION); + size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0); + CGRect rect = self.bounds; + glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar); + glViewport(0, 0, rect.size.width, rect.size.height); + + //Make the OpenGL modelview matrix the default + glMatrixMode(GL_MODELVIEW); +} + +// Updates the OpenGL view +- (void)drawView +{ + // Make sure that you are drawing to the current context + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + GLfloat matrix[4][4], length; + + //Make sure we have a big enough acceleration vector + length = sqrtf(accel[0] * accel[0] + accel[1] * accel[1] + accel[2] * accel[2]); + + //Setup model view matrix + glLoadIdentity(); + glTranslatef(0.0, -0.1, -1.0); + glScalef(kTeapotScale, kTeapotScale, kTeapotScale); + + if(length >= 0.1) + { + //Clear matrix to be used to rotate from the current referential to one based on the gravity vector + bzero(matrix, sizeof(matrix)); + matrix[3][3] = 1.0; + + //Setup first matrix column as gravity vector + matrix[0][0] = accel[0] / length; + matrix[0][1] = accel[1] / length; + matrix[0][2] = accel[2] / length; + + //Setup second matrix column as an arbitrary vector in the plane perpendicular to the gravity vector {Gx, Gy, Gz} defined by by the equation "Gx * x + Gy * y + Gz * z = 0" in which we arbitrarily set x=0 and y=1 + matrix[1][0] = 0.0; + matrix[1][1] = 1.0; + matrix[1][2] = -accel[1] / accel[2]; + length = sqrtf(matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1] + matrix[1][2] * matrix[1][2]); + matrix[1][0] /= length; + matrix[1][1] /= length; + matrix[1][2] /= length; + + //Setup third matrix column as the cross product of the first two + matrix[2][0] = matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]; + matrix[2][1] = matrix[1][0] * matrix[0][2] - matrix[1][2] * matrix[0][0]; + matrix[2][2] = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; + + //Finally load matrix + glMultMatrixf((GLfloat*)matrix); + + // Rotate a bit more so that its where we want it. + glRotatef(90.0, 0.0, 0.0, 1.0); + } + // If we're in the simulator we'd like to do something more interesting than just sit there + // But if we're on a device, we want to just let the accelerometer do the work for us without a fallback. +#if TARGET_IPHONE_SIMULATOR + else + { + static GLfloat spinX = 0.0, spinY = 0.0; + glRotatef(spinX, 0.0, 0.0, 1.0); + glRotatef(spinY, 0.0, 1.0, 0.0); + glRotatef(90.0, 1.0, 0.0, 0.0); + spinX += 1.0; + spinY += 0.25; + } +#endif + + // Draw teapot. The new_teapot_indicies array is an RLE (run-length encoded) version of the teapot_indices array in teapot.h + for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) + { + glDrawElements(GL_TRIANGLE_STRIP, new_teapot_indicies[i], GL_UNSIGNED_SHORT, &new_teapot_indicies[i+1]); + } + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +// If our view is resized, we'll be asked to layout subviews. +// This is the perfect opportunity to also update the framebuffer so that it is +// the same size as our display area. +-(void)layoutSubviews +{ + [EAGLContext setCurrentContext:context]; + [self destroyFramebuffer]; + [self createFramebuffer]; + [self drawView]; +} + +- (BOOL)createFramebuffer +{ + // Generate IDs for a framebuffer object and a color renderbuffer + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer) + // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view). + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + // For this sample, we also need a depth buffer, so we'll create and attach one via another renderbuffer. + glGenRenderbuffersOES(1, &depthRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + + if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) + { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + +// Clean up any buffers we have allocated. +- (void)destroyFramebuffer +{ + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if(depthRenderbuffer) + { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + +- (NSInteger) animationFrameInterval +{ + return animationFrameInterval; +} + +- (void) setAnimationFrameInterval:(NSInteger)frameInterval +{ + // Frame interval defines how many display frames must pass between each time the + // display link fires. The display link will only fire 30 times a second when the + // frame internal is two on a display that refreshes 60 times a second. The default + // frame interval setting of one will fire 60 times a second when the display refreshes + // at 60 times a second. A frame interval setting of less than one results in undefined + // behavior. + if (frameInterval >= 1) + { + animationFrameInterval = frameInterval; + + if (animating) + { + [self stopAnimation]; + [self startAnimation]; + } + } +} + +- (void) startAnimation +{ + if (!animating) + { + if (displayLinkSupported) + { + // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed + // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will + // not be called in system versions earlier than 3.1. + + displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView)]; + [displayLink setFrameInterval:animationFrameInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } + else + animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView) userInfo:nil repeats:TRUE]; + + animating = TRUE; + } +} + +- (void)stopAnimation +{ + if (animating) + { + if (displayLinkSupported) + { + [displayLink invalidate]; + displayLink = nil; + } + else + { + [animationTimer invalidate]; + animationTimer = nil; + } + + animating = FALSE; + } +} + +- (void)dealloc +{ + free(accel); + + if([EAGLContext currentContext] == context) + { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + [super dealloc]; +} + +@end diff --git a/GLGravity/Default.png b/GLGravity/Default.png new file mode 100644 index 0000000..11692e0 Binary files /dev/null and b/GLGravity/Default.png differ diff --git a/GLGravity/GLGravity-Info.plist b/GLGravity/GLGravity-Info.plist new file mode 100644 index 0000000..d315e3a --- /dev/null +++ b/GLGravity/GLGravity-Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarHidden + + CFBundleShortVersionString + + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + + diff --git a/GLGravity/GLGravity.xcodeproj/project.pbxproj b/GLGravity/GLGravity.xcodeproj/project.pbxproj new file mode 100755 index 0000000..2ca1e6e --- /dev/null +++ b/GLGravity/GLGravity.xcodeproj/project.pbxproj @@ -0,0 +1,310 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D4F2F9A0D10AC310045FB13 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D4F2F990D10AC310045FB13 /* Default.png */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2D500B940D5A79C200DBA0E3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D500B920D5A79C200DBA0E3 /* OpenGLES.framework */; }; + 2D500B9A0D5A79CF00DBA0E3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D500B990D5A79CF00DBA0E3 /* QuartzCore.framework */; }; + 63E8ED9F0E1ACA88004D3662 /* GLGravityView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E8ED9D0E1ACA88004D3662 /* GLGravityView.m */; }; + AF85818310643D940004D36B /* GLGravityAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AF85818210643D940004D36B /* GLGravityAppDelegate.m */; }; + AF85846C10646AA20004D36B /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF85846B10646AA20004D36B /* MainWindow.xib */; }; + AFE6766D11D968B1004098A2 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766611D968B1004098A2 /* Icon-72.png */; }; + AFE6766E11D968B1004098A2 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766711D968B1004098A2 /* Icon-Small-50.png */; }; + AFE6766F11D968B1004098A2 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766811D968B1004098A2 /* Icon-Small.png */; }; + AFE6767011D968B1004098A2 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766911D968B1004098A2 /* Icon-Small@2x.png */; }; + AFE6767111D968B1004098A2 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766A11D968B1004098A2 /* Icon.png */; }; + AFE6767211D968B1004098A2 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766B11D968B1004098A2 /* Icon@2x.png */; }; + AFE6767311D968B1004098A2 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = AFE6766C11D968B1004098A2 /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1B57FB700DA56F450091B3B1 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D4F2F990D10AC310045FB13 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* GLGravity.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLGravity.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2D500B920D5A79C200DBA0E3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 2D500B990D5A79CF00DBA0E3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 63A452D60E0877A900AA59DC /* teapot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = teapot.h; path = Models/teapot.h; sourceTree = ""; }; + 63E8ED9D0E1ACA88004D3662 /* GLGravityView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GLGravityView.m; path = Classes/GLGravityView.m; sourceTree = ""; }; + 63E8ED9E0E1ACA88004D3662 /* GLGravityView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GLGravityView.h; path = Classes/GLGravityView.h; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* GLGravity-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GLGravity-Info.plist"; sourceTree = ""; }; + AF85818110643D940004D36B /* GLGravityAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GLGravityAppDelegate.h; path = Classes/GLGravityAppDelegate.h; sourceTree = ""; }; + AF85818210643D940004D36B /* GLGravityAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GLGravityAppDelegate.m; path = Classes/GLGravityAppDelegate.m; sourceTree = ""; }; + AF85846B10646AA20004D36B /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + AFE6766611D968B1004098A2 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + AFE6766711D968B1004098A2 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + AFE6766811D968B1004098A2 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + AFE6766911D968B1004098A2 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + AFE6766A11D968B1004098A2 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + AFE6766B11D968B1004098A2 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + AFE6766C11D968B1004098A2 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 2D500B940D5A79C200DBA0E3 /* OpenGLES.framework in Frameworks */, + 2D500B9A0D5A79CF00DBA0E3 /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GLGravity.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 1B57FB700DA56F450091B3B1 /* ReadMe.txt */, + 2D500B1D0D5A766B00DBA0E3 /* Classes */, + 63A452D30E08777A00AA59DC /* Models */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + AFE6766611D968B1004098A2 /* Icon-72.png */, + AFE6766711D968B1004098A2 /* Icon-Small-50.png */, + AFE6766811D968B1004098A2 /* Icon-Small.png */, + AFE6766911D968B1004098A2 /* Icon-Small@2x.png */, + AFE6766A11D968B1004098A2 /* Icon.png */, + AFE6766B11D968B1004098A2 /* Icon@2x.png */, + AFE6766C11D968B1004098A2 /* iTunesArtwork */, + AF85846B10646AA20004D36B /* MainWindow.xib */, + 1D4F2F990D10AC310045FB13 /* Default.png */, + 8D1107310486CEB800E47090 /* GLGravity-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 2D500B990D5A79CF00DBA0E3 /* QuartzCore.framework */, + 2D500B920D5A79C200DBA0E3 /* OpenGLES.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2D500B1D0D5A766B00DBA0E3 /* Classes */ = { + isa = PBXGroup; + children = ( + AF85818110643D940004D36B /* GLGravityAppDelegate.h */, + AF85818210643D940004D36B /* GLGravityAppDelegate.m */, + 63E8ED9E0E1ACA88004D3662 /* GLGravityView.h */, + 63E8ED9D0E1ACA88004D3662 /* GLGravityView.m */, + ); + name = Classes; + sourceTree = ""; + }; + 63A452D30E08777A00AA59DC /* Models */ = { + isa = PBXGroup; + children = ( + 63A452D60E0877A900AA59DC /* teapot.h */, + ); + name = Models; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GLGravity */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLGravity" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GLGravity; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* GLGravity.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLGravity" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GLGravity */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D4F2F9A0D10AC310045FB13 /* Default.png in Resources */, + AF85846C10646AA20004D36B /* MainWindow.xib in Resources */, + AFE6766D11D968B1004098A2 /* Icon-72.png in Resources */, + AFE6766E11D968B1004098A2 /* Icon-Small-50.png in Resources */, + AFE6766F11D968B1004098A2 /* Icon-Small.png in Resources */, + AFE6767011D968B1004098A2 /* Icon-Small@2x.png in Resources */, + AFE6767111D968B1004098A2 /* Icon.png in Resources */, + AFE6767211D968B1004098A2 /* Icon@2x.png in Resources */, + AFE6767311D968B1004098A2 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 63E8ED9F0E1ACA88004D3662 /* GLGravityView.m in Sources */, + AF85818310643D940004D36B /* GLGravityAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = "GLGravity-Info.plist"; + PREBINDING = NO; + PRODUCT_NAME = GLGravity; + WARNING_CFLAGS = "-Wall"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = "GLGravity-Info.plist"; + PREBINDING = NO; + PRODUCT_NAME = GLGravity; + WARNING_CFLAGS = "-Wall"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLGravity" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLGravity" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GLGravity/Images/Icon-72.png b/GLGravity/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GLGravity/Images/Icon-72.png differ diff --git a/GLGravity/Images/Icon-Small-50.png b/GLGravity/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GLGravity/Images/Icon-Small-50.png differ diff --git a/GLGravity/Images/Icon-Small.png b/GLGravity/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GLGravity/Images/Icon-Small.png differ diff --git a/GLGravity/Images/Icon-Small@2x.png b/GLGravity/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GLGravity/Images/Icon-Small@2x.png differ diff --git a/GLGravity/Images/Icon.png b/GLGravity/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GLGravity/Images/Icon.png differ diff --git a/GLGravity/Images/Icon@2x.png b/GLGravity/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GLGravity/Images/Icon@2x.png differ diff --git a/GLGravity/Images/iTunesArtwork b/GLGravity/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GLGravity/Images/iTunesArtwork differ diff --git a/GLGravity/MainWindow.xib b/GLGravity/MainWindow.xib new file mode 100644 index 0000000..7d63473 --- /dev/null +++ b/GLGravity/MainWindow.xib @@ -0,0 +1,414 @@ + + + + 768 + 10B504 + 732 + 1038.2 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + + -1 + + + File's Owner + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{309, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLGravityAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLGravityView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 9 + + + + YES + + GLGravityAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + GLGravityView + UIWindow + + + + IBProjectSource + Classes/GLGravityAppDelegate.h + + + + GLGravityView + UIView + + displayLink + id + + + IBProjectSource + Classes/GLGravityView.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIResponder + NSObject + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + GLGravity.xcodeproj + 3 + 3.1 + + diff --git a/GLGravity/Models/teapot.h b/GLGravity/Models/teapot.h new file mode 100644 index 0000000..2aa6602 --- /dev/null +++ b/GLGravity/Models/teapot.h @@ -0,0 +1,3281 @@ +/* + File: teapot.h + Abstract: Contains data necessary for rendering the teapot model. + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#ifndef TEAPOT_H +#define TEAPOT_H + +const int num_teapot_indices = 2781; +const int num_teapot_vertices = 1364; +const int num_teapot_normals = 1364; + +float teapot_vertices [] = { + 0.0663056, 0.117825, 2.10688e-008, + 0.0672, 0.1152, 2.05994e-008, + 0.0639726, 0.117825, 0.0178043, + 0.0648356, 0.1152, 0.0180445, + 0.0573666, 0.117825, 0.0336931, + 0.0581404, 0.1152, 0.0341476, + 0.0470769, 0.117825, 0.0470769, + 0.047712, 0.1152, 0.047712, + 0.033693, 0.117825, 0.0573666, + 0.0341476, 0.1152, 0.0581404, + 0.0178043, 0.117825, 0.0639726, + 0.0180444, 0.1152, 0.0648356, + 0, 0.117825, 0.0663056, + 0, 0.1152, 0.0672, + 0.0664444, 0.1194, 2.13504e-008, + 0.0641066, 0.1194, 0.0178416, + 0.0574868, 0.1194, 0.0337636, + 0.0471755, 0.1194, 0.0471756, + 0.0337636, 0.1194, 0.0574868, + 0.0178416, 0.1194, 0.0641066, + 0, 0.1194, 0.0664444, + 0.06735, 0.119925, 2.14443e-008, + 0.0649803, 0.119925, 0.0180847, + 0.0582702, 0.119925, 0.0342238, + 0.0478185, 0.119925, 0.0478185, + 0.0342238, 0.119925, 0.0582702, + 0.0180847, 0.119925, 0.0649803, + 0, 0.119925, 0.06735, + 0.0687556, 0.1194, 2.13504e-008, + 0.0663364, 0.1194, 0.0184622, + 0.0594863, 0.1194, 0.034938, + 0.0488164, 0.1194, 0.0488164, + 0.034938, 0.1194, 0.0594863, + 0.0184621, 0.1194, 0.0663364, + 0, 0.1194, 0.0687556, + 0.0703944, 0.117825, 2.10688e-008, + 0.0679176, 0.117825, 0.0189022, + 0.0609042, 0.117825, 0.0357708, + 0.0499801, 0.117825, 0.0499801, + 0.0357708, 0.117825, 0.0609042, + 0.0189022, 0.117825, 0.0679176, + 0, 0.117825, 0.0703944, + 0.072, 0.1152, 2.05994e-008, + 0.0694667, 0.1152, 0.0193333, + 0.0622933, 0.1152, 0.0365867, + 0.05112, 0.1152, 0.05112, + 0.0365867, 0.1152, 0.0622933, + 0.0193333, 0.1152, 0.0694667, + 0, 0.1152, 0.072, + -0.0178043, 0.117825, 0.0639726, + -0.0180444, 0.1152, 0.0648356, + -0.033693, 0.117825, 0.0573666, + -0.0341476, 0.1152, 0.0581404, + -0.0470769, 0.117825, 0.0470769, + -0.047712, 0.1152, 0.047712, + -0.0573666, 0.117825, 0.033693, + -0.0581404, 0.1152, 0.0341476, + -0.0639726, 0.117825, 0.0178043, + -0.0648356, 0.1152, 0.0180445, + -0.0663056, 0.117825, 2.10688e-008, + -0.0672, 0.1152, 2.05994e-008, + -0.0178416, 0.1194, 0.0641066, + -0.0337636, 0.1194, 0.0574867, + -0.0471756, 0.1194, 0.0471756, + -0.0574867, 0.1194, 0.0337636, + -0.0641066, 0.1194, 0.0178416, + -0.0664444, 0.1194, 2.13504e-008, + -0.0180847, 0.119925, 0.0649803, + -0.0342238, 0.119925, 0.0582702, + -0.0478185, 0.119925, 0.0478185, + -0.0582702, 0.119925, 0.0342238, + -0.0649803, 0.119925, 0.0180847, + -0.06735, 0.119925, 2.14443e-008, + 0, 0.1194, 0.0687556, + -0.0184621, 0.1194, 0.0663364, + -0.034938, 0.1194, 0.0594863, + -0.0488164, 0.1194, 0.0488164, + -0.0594863, 0.1194, 0.034938, + -0.0663364, 0.1194, 0.0184621, + -0.0687556, 0.1194, 2.13504e-008, + 0, 0.117825, 0.0703944, + -0.0189022, 0.117825, 0.0679176, + -0.0357708, 0.117825, 0.0609042, + -0.0499801, 0.117825, 0.0499801, + -0.0609042, 0.117825, 0.0357708, + -0.0679176, 0.117825, 0.0189022, + -0.0703944, 0.117825, 2.10688e-008, + -0.0193333, 0.1152, 0.0694667, + -0.0365867, 0.1152, 0.0622933, + -0.05112, 0.1152, 0.05112, + -0.0622933, 0.1152, 0.0365867, + -0.0694667, 0.1152, 0.0193333, + -0.072, 0.1152, 2.05994e-008, + -0.0663055, 0.117825, 2.10688e-008, + -0.0639726, 0.117825, -0.0178043, + -0.0648356, 0.1152, -0.0180444, + -0.0573666, 0.117825, -0.033693, + -0.0581404, 0.1152, -0.0341475, + -0.0470769, 0.117825, -0.0470769, + -0.047712, 0.1152, -0.047712, + -0.033693, 0.117825, -0.0573666, + -0.0341476, 0.1152, -0.0581404, + -0.0178043, 0.117825, -0.0639726, + -0.0180444, 0.1152, -0.0648356, + 0, 0.117825, -0.0663055, + 0, 0.1152, -0.0672, + -0.0664444, 0.1194, 2.13504e-008, + -0.0641066, 0.1194, -0.0178416, + -0.0574867, 0.1194, -0.0337636, + -0.0471756, 0.1194, -0.0471756, + -0.0337636, 0.1194, -0.0574868, + -0.0178416, 0.1194, -0.0641066, + 0, 0.1194, -0.0664444, + -0.0649803, 0.119925, -0.0180847, + -0.0582702, 0.119925, -0.0342238, + -0.0478185, 0.119925, -0.0478185, + -0.0342238, 0.119925, -0.0582702, + -0.0180847, 0.119925, -0.0649803, + 0, 0.119925, -0.06735, + -0.0663364, 0.1194, -0.0184621, + -0.0594863, 0.1194, -0.034938, + -0.0488164, 0.1194, -0.0488164, + -0.034938, 0.1194, -0.0594863, + -0.0184621, 0.1194, -0.0663364, + 0, 0.1194, -0.0687556, + -0.0703944, 0.117825, 2.10688e-008, + -0.0679176, 0.117825, -0.0189022, + -0.0609042, 0.117825, -0.0357708, + -0.0499801, 0.117825, -0.0499801, + -0.0357708, 0.117825, -0.0609042, + -0.0189022, 0.117825, -0.0679176, + 0, 0.117825, -0.0703944, + -0.0694667, 0.1152, -0.0193333, + -0.0622933, 0.1152, -0.0365867, + -0.05112, 0.1152, -0.05112, + -0.0365867, 0.1152, -0.0622933, + -0.0193333, 0.1152, -0.0694667, + 0, 0.1152, -0.072, + 0.0178043, 0.117825, -0.0639726, + 0.0180444, 0.1152, -0.0648356, + 0.033693, 0.117825, -0.0573666, + 0.0341476, 0.1152, -0.0581404, + 0.0470769, 0.117825, -0.0470769, + 0.047712, 0.1152, -0.047712, + 0.0573666, 0.117825, -0.033693, + 0.0581404, 0.1152, -0.0341475, + 0.0639726, 0.117825, -0.0178043, + 0.0648356, 0.1152, -0.0180444, + 0.0663055, 0.117825, 2.10688e-008, + 0.0178416, 0.1194, -0.0641066, + 0.0337636, 0.1194, -0.0574867, + 0.0471756, 0.1194, -0.0471756, + 0.0574868, 0.1194, -0.0337636, + 0.0641066, 0.1194, -0.0178415, + 0.0664444, 0.1194, 2.13504e-008, + 0.0180847, 0.119925, -0.0649803, + 0.0342238, 0.119925, -0.0582702, + 0.0478185, 0.119925, -0.0478185, + 0.0582702, 0.119925, -0.0342238, + 0.0649803, 0.119925, -0.0180847, + 0.0184621, 0.1194, -0.0663364, + 0.034938, 0.1194, -0.0594863, + 0.0488164, 0.1194, -0.0488164, + 0.0594863, 0.1194, -0.034938, + 0.0663364, 0.1194, -0.0184621, + 0.0687556, 0.1194, 2.13504e-008, + 0.0189022, 0.117825, -0.0679176, + 0.0357708, 0.117825, -0.0609042, + 0.0499801, 0.117825, -0.0499801, + 0.0609042, 0.117825, -0.0357708, + 0.0679176, 0.117825, -0.0189022, + 0.0703944, 0.117825, 2.10688e-008, + 0.0193333, 0.1152, -0.0694667, + 0.0365867, 0.1152, -0.0622933, + 0.05112, 0.1152, -0.05112, + 0.0622933, 0.1152, -0.0365867, + 0.0694667, 0.1152, -0.0193333, + 0.0779444, 0.102617, 1.83493e-008, + 0.075202, 0.102617, 0.0209295, + 0.0694667, 0.1152, 0.0193333, + 0.0674364, 0.102617, 0.0396073, + 0.0622933, 0.1152, 0.0365867, + 0.0553406, 0.102617, 0.0553406, + 0.0396073, 0.102617, 0.0674364, + 0.0365867, 0.1152, 0.0622933, + 0.0209296, 0.102617, 0.0752019, + 0.0193334, 0.1152, 0.0694667, + 0, 0.102617, 0.0779444, + 0.0835556, 0.0901333, 1.61171e-008, + 0.0806156, 0.0901333, 0.0224362, + 0.072291, 0.0901333, 0.0424586, + 0.0593244, 0.0901334, 0.0593245, + 0.0424586, 0.0901333, 0.072291, + 0.0224362, 0.0901333, 0.0806156, + 0, 0.0901333, 0.0835556, + 0.0885, 0.07785, 1.39207e-008, + 0.0853861, 0.07785, 0.0237639, + 0.0765689, 0.07785, 0.0449711, + 0.062835, 0.07785, 0.062835, + 0.0449711, 0.07785, 0.0765689, + 0.0237639, 0.07785, 0.0853861, + 0, 0.07785, 0.0885, + 0.0924444, 0.0658667, 1.17779e-008, + 0.0891918, 0.0658667, 0.024823, + 0.0799816, 0.0658667, 0.0469755, + 0.0656356, 0.0658667, 0.0656356, + 0.0469755, 0.0658667, 0.0799816, + 0.0248231, 0.0658667, 0.0891918, + 0, 0.0658667, 0.0924444, + 0.0950556, 0.0542833, 9.7066e-009, + 0.091711, 0.0542833, 0.0255242, + 0.0822407, 0.0542833, 0.0483023, + 0.0674895, 0.0542833, 0.0674895, + 0.0483023, 0.0542833, 0.0822406, + 0.0255242, 0.0542833, 0.091711, + 0, 0.0542833, 0.0950556, + 0.096, 0.0432, 7.72476e-009, + 0.0926222, 0.0432, 0.0257778, + 0.0830578, 0.0432, 0.0487822, + 0.06816, 0.0432, 0.06816, + 0.0487822, 0.0432, 0.0830578, + 0.0257778, 0.0432, 0.0926222, + 0, 0.0432, 0.096, + 0, 0.102617, 0.0779444, + -0.0209295, 0.102617, 0.075202, + -0.0193333, 0.1152, 0.0694667, + -0.0396073, 0.102617, 0.0674364, + -0.0365867, 0.1152, 0.0622933, + -0.0553405, 0.102617, 0.0553405, + -0.0674364, 0.102617, 0.0396073, + -0.0622933, 0.1152, 0.0365867, + -0.075202, 0.102617, 0.0209296, + -0.0694667, 0.1152, 0.0193334, + -0.0779444, 0.102617, 1.83493e-008, + 0, 0.0901333, 0.0835555, + -0.0224362, 0.0901333, 0.0806156, + -0.0424586, 0.0901333, 0.072291, + -0.0593244, 0.0901334, 0.0593244, + -0.072291, 0.0901334, 0.0424586, + -0.0806156, 0.0901333, 0.0224362, + -0.0835555, 0.0901333, 1.61171e-008, + -0.0237639, 0.07785, 0.0853861, + -0.0449711, 0.07785, 0.0765689, + -0.062835, 0.07785, 0.062835, + -0.0765689, 0.07785, 0.0449711, + -0.0853861, 0.07785, 0.0237639, + -0.0885, 0.07785, 1.39207e-008, + 0, 0.0658667, 0.0924444, + -0.024823, 0.0658667, 0.0891918, + -0.0469755, 0.0658667, 0.0799816, + -0.0656356, 0.0658667, 0.0656356, + -0.0799816, 0.0658667, 0.0469755, + -0.0891918, 0.0658667, 0.0248231, + -0.0924444, 0.0658667, 1.17779e-008, + 0, 0.0542833, 0.0950556, + -0.0255242, 0.0542833, 0.091711, + -0.0483023, 0.0542833, 0.0822407, + -0.0674894, 0.0542834, 0.0674894, + -0.0822406, 0.0542834, 0.0483023, + -0.091711, 0.0542833, 0.0255242, + -0.0950556, 0.0542833, 9.70661e-009, + -0.0257778, 0.0432, 0.0926222, + -0.0487822, 0.0432, 0.0830578, + -0.06816, 0.0432, 0.06816, + -0.0830578, 0.0432, 0.0487822, + -0.0926222, 0.0432, 0.0257778, + -0.096, 0.0432, 7.72476e-009, + -0.0779444, 0.102617, 1.83493e-008, + -0.075202, 0.102617, -0.0209295, + -0.0694667, 0.1152, -0.0193333, + -0.0674364, 0.102617, -0.0396073, + -0.0622933, 0.1152, -0.0365866, + -0.0553406, 0.102617, -0.0553406, + -0.0396073, 0.102617, -0.0674364, + -0.0365867, 0.1152, -0.0622933, + -0.0209296, 0.102617, -0.0752019, + -0.0193334, 0.1152, -0.0694667, + 0, 0.102617, -0.0779444, + -0.0835556, 0.0901333, 1.61171e-008, + -0.0806156, 0.0901333, -0.0224362, + -0.072291, 0.0901333, -0.0424586, + -0.0593244, 0.0901333, -0.0593244, + -0.0424586, 0.0901333, -0.072291, + -0.0224362, 0.0901333, -0.0806156, + 0, 0.0901333, -0.0835556, + -0.0853861, 0.07785, -0.0237639, + -0.0765689, 0.07785, -0.0449711, + -0.062835, 0.07785, -0.062835, + -0.0449711, 0.07785, -0.0765689, + -0.0237639, 0.07785, -0.0853861, + 0, 0.07785, -0.0885, + -0.0924444, 0.0658666, 1.17779e-008, + -0.0891918, 0.0658666, -0.024823, + -0.0799816, 0.0658666, -0.0469755, + -0.0656356, 0.0658666, -0.0656356, + -0.0469755, 0.0658666, -0.0799816, + -0.0248231, 0.0658666, -0.0891918, + 0, 0.0658666, -0.0924444, + -0.0950556, 0.0542833, 9.7066e-009, + -0.091711, 0.0542833, -0.0255242, + -0.0822407, 0.0542833, -0.0483023, + -0.0674894, 0.0542833, -0.0674894, + -0.0483023, 0.0542833, -0.0822407, + -0.0255242, 0.0542833, -0.091711, + 0, 0.0542833, -0.0950556, + -0.0926222, 0.0432, -0.0257778, + -0.0830578, 0.0432, -0.0487822, + -0.06816, 0.0432, -0.06816, + -0.0487822, 0.0432, -0.0830578, + -0.0257778, 0.0432, -0.0926222, + 0, 0.0432, -0.096, + 0.0209295, 0.102617, -0.075202, + 0.0193333, 0.1152, -0.0694667, + 0.0396073, 0.102617, -0.0674364, + 0.0365867, 0.1152, -0.0622933, + 0.0553406, 0.102617, -0.0553406, + 0.0674364, 0.102617, -0.0396073, + 0.0622933, 0.1152, -0.0365867, + 0.0752019, 0.102617, -0.0209295, + 0.0694667, 0.1152, -0.0193333, + 0.0779444, 0.102617, 1.83493e-008, + 0.0224362, 0.0901333, -0.0806156, + 0.0424586, 0.0901333, -0.072291, + 0.0593244, 0.0901333, -0.0593244, + 0.072291, 0.0901333, -0.0424586, + 0.0806156, 0.0901333, -0.0224362, + 0.0835556, 0.0901333, 1.61171e-008, + 0.0237639, 0.07785, -0.0853861, + 0.0449711, 0.07785, -0.0765689, + 0.062835, 0.07785, -0.062835, + 0.0765689, 0.07785, -0.0449711, + 0.0853861, 0.07785, -0.0237639, + 0.024823, 0.0658666, -0.0891918, + 0.0469755, 0.0658666, -0.0799816, + 0.0656356, 0.0658666, -0.0656356, + 0.0799816, 0.0658666, -0.0469755, + 0.0891918, 0.0658666, -0.0248231, + 0.0924444, 0.0658666, 1.17779e-008, + 0.0255242, 0.0542833, -0.091711, + 0.0483023, 0.0542833, -0.0822407, + 0.0674894, 0.0542833, -0.0674894, + 0.0822407, 0.0542833, -0.0483023, + 0.091711, 0.0542833, -0.0255242, + 0.0950556, 0.0542833, 9.7066e-009, + 0.0257778, 0.0432, -0.0926222, + 0.0487822, 0.0432, -0.0830578, + 0.06816, 0.0432, -0.06816, + 0.0830578, 0.0432, -0.0487822, + 0.0926222, 0.0432, -0.0257778, + 0.0942222, 0.0332833, 5.95152e-009, + 0.090907, 0.0332833, 0.0253004, + 0.0815197, 0.0332833, 0.0478788, + 0.0668978, 0.0332833, 0.0668978, + 0.0478789, 0.0332833, 0.0815197, + 0.0253004, 0.0332833, 0.090907, + 0, 0.0332833, 0.0942222, + 0.0897778, 0.0250667, 4.48227e-009, + 0.0866189, 0.0250667, 0.024107, + 0.0776744, 0.0250667, 0.0456204, + 0.0637422, 0.0250667, 0.0637422, + 0.0456204, 0.0250667, 0.0776744, + 0.024107, 0.0250667, 0.0866189, + 0, 0.0250667, 0.0897778, + 0.084, 0.01845, 3.29912e-009, + 0.0810445, 0.01845, 0.0225556, + 0.0726756, 0.01845, 0.0426844, + 0.05964, 0.01845, 0.05964, + 0.0426845, 0.01845, 0.0726755, + 0.0225556, 0.01845, 0.0810444, + 0, 0.01845, 0.084, + 0.0782222, 0.0133334, 2.38419e-009, + 0.07547, 0.0133333, 0.0210041, + 0.0676767, 0.0133333, 0.0397485, + 0.0555378, 0.0133333, 0.0555378, + 0.0397485, 0.0133333, 0.0676767, + 0.0210041, 0.0133333, 0.07547, + 0, 0.0133333, 0.0782222, + 0.0737778, 0.00961668, 1.7196e-009, + 0.0711819, 0.00961668, 0.0198107, + 0.0638315, 0.00961668, 0.03749, + 0.0523822, 0.00961668, 0.0523822, + 0.0374901, 0.00961668, 0.0638314, + 0.0198107, 0.00961668, 0.0711819, + 0, 0.00961668, 0.0737778, + 0.072, 0.0072, 1.28746e-009, + 0.0694667, 0.0072, 0.0193333, + 0.0622933, 0.00719999, 0.0365867, + 0.05112, 0.00719999, 0.05112, + 0.0365867, 0.00719999, 0.0622933, + 0.0193334, 0.00719999, 0.0694667, + 0, 0.00719999, 0.072, + -0.0253004, 0.0332833, 0.090907, + -0.0478788, 0.0332833, 0.0815197, + -0.0668978, 0.0332833, 0.0668978, + -0.0815197, 0.0332833, 0.0478789, + -0.090907, 0.0332833, 0.0253004, + -0.0942222, 0.0332833, 5.95152e-009, + -0.024107, 0.0250667, 0.0866189, + -0.0456204, 0.0250667, 0.0776744, + -0.0637422, 0.0250667, 0.0637422, + -0.0776744, 0.0250667, 0.0456204, + -0.0866189, 0.0250667, 0.024107, + -0.0897778, 0.0250667, 4.48227e-009, + -0.0225556, 0.01845, 0.0810445, + -0.0426844, 0.01845, 0.0726756, + -0.05964, 0.01845, 0.05964, + -0.0726755, 0.01845, 0.0426845, + -0.0810444, 0.01845, 0.0225556, + -0.084, 0.01845, 3.29912e-009, + -0.0210041, 0.0133333, 0.07547, + -0.0397485, 0.0133333, 0.0676767, + -0.0555378, 0.0133333, 0.0555378, + -0.0676767, 0.0133333, 0.0397485, + -0.07547, 0.0133333, 0.0210041, + -0.0782222, 0.0133334, 2.38419e-009, + -0.0198107, 0.00961668, 0.0711819, + -0.03749, 0.00961667, 0.0638315, + -0.0523822, 0.00961668, 0.0523822, + -0.0638314, 0.00961668, 0.0374901, + -0.0711819, 0.00961668, 0.0198107, + -0.0737778, 0.00961668, 1.7196e-009, + -0.0193333, 0.00719999, 0.0694667, + -0.0365867, 0.00719999, 0.0622933, + -0.05112, 0.00719999, 0.05112, + -0.0622933, 0.00719999, 0.0365867, + -0.0694667, 0.0072, 0.0193334, + -0.072, 0.0072, 1.28746e-009, + -0.090907, 0.0332833, -0.0253004, + -0.0815197, 0.0332833, -0.0478788, + -0.0668978, 0.0332833, -0.0668978, + -0.0478789, 0.0332833, -0.0815197, + -0.0253004, 0.0332833, -0.090907, + 0, 0.0332833, -0.0942222, + -0.0866189, 0.0250667, -0.024107, + -0.0776744, 0.0250667, -0.0456204, + -0.0637422, 0.0250667, -0.0637422, + -0.0456204, 0.0250667, -0.0776744, + -0.024107, 0.0250667, -0.0866189, + 0, 0.0250667, -0.0897778, + -0.0810445, 0.01845, -0.0225556, + -0.0726756, 0.01845, -0.0426844, + -0.05964, 0.01845, -0.05964, + -0.0426845, 0.01845, -0.0726755, + -0.0225556, 0.01845, -0.0810444, + 0, 0.01845, -0.084, + -0.07547, 0.0133334, -0.0210041, + -0.0676767, 0.0133334, -0.0397485, + -0.0555378, 0.0133334, -0.0555378, + -0.0397485, 0.0133334, -0.0676767, + -0.0210041, 0.0133334, -0.07547, + 0, 0.0133334, -0.0782222, + -0.0711819, 0.00961669, -0.0198107, + -0.0638315, 0.00961669, -0.03749, + -0.0523822, 0.00961669, -0.0523822, + -0.0374901, 0.00961669, -0.0638314, + -0.0198107, 0.00961669, -0.0711819, + 0, 0.00961669, -0.0737778, + -0.0694667, 0.0072, -0.0193333, + -0.0622933, 0.00720001, -0.0365867, + -0.05112, 0.00720001, -0.05112, + -0.0365867, 0.00720001, -0.0622933, + -0.0193334, 0.00720001, -0.0694667, + 0, 0.00720001, -0.072, + 0.0253004, 0.0332833, -0.090907, + 0.0478788, 0.0332833, -0.0815197, + 0.0668978, 0.0332833, -0.0668978, + 0.0815197, 0.0332833, -0.0478789, + 0.090907, 0.0332833, -0.0253004, + 0.024107, 0.0250667, -0.0866189, + 0.0456204, 0.0250667, -0.0776744, + 0.0637422, 0.0250667, -0.0637422, + 0.0776744, 0.0250667, -0.0456204, + 0.0866189, 0.0250667, -0.024107, + 0.0225556, 0.01845, -0.0810445, + 0.0426844, 0.01845, -0.0726756, + 0.05964, 0.01845, -0.05964, + 0.0726755, 0.01845, -0.0426845, + 0.0810444, 0.01845, -0.0225556, + 0.0210041, 0.0133334, -0.07547, + 0.0397485, 0.0133334, -0.0676767, + 0.0555378, 0.0133334, -0.0555378, + 0.0676767, 0.0133334, -0.0397485, + 0.07547, 0.0133334, -0.0210041, + 0.0198107, 0.00961669, -0.0711819, + 0.03749, 0.00961669, -0.0638315, + 0.0523822, 0.00961669, -0.0523822, + 0.0638314, 0.00961669, -0.0374901, + 0.0711819, 0.00961668, -0.0198107, + 0.0193333, 0.00720001, -0.0694667, + 0.0365867, 0.00720001, -0.0622933, + 0.05112, 0.00720001, -0.05112, + 0.0622933, 0.00720001, -0.0365867, + 0.0694667, 0.0072, -0.0193334, + -0.0923778, 0.09715, 1.73718e-008, + -0.0768, 0.0972, 1.73807e-008, + -0.0924979, 0.0979463, 0.00600001, + -0.0764444, 0.098, 0.00600001, + -0.0927984, 0.099937, 0.00960001, + -0.0755556, 0.1, 0.00960001, + -0.0931889, 0.102525, 0.0108, + -0.0744, 0.1026, 0.0108, + -0.0935794, 0.105113, 0.0096, + -0.0732444, 0.1052, 0.0096, + -0.0938798, 0.107104, 0.006, + -0.0723556, 0.1072, 0.006, + -0.094, 0.1079, 1.9294e-008, + -0.072, 0.108, 1.93119e-008, + -0.105422, 0.0968, 1.73092e-008, + -0.105909, 0.0975704, 0.00600001, + -0.107128, 0.0994963, 0.00960001, + -0.108711, 0.102, 0.0108, + -0.110295, 0.104504, 0.0096, + -0.111513, 0.10643, 0.006, + -0.112, 0.1072, 1.91688e-008, + -0.1158, 0.09585, 1.71393e-008, + -0.116556, 0.09655, 0.00600001, + -0.118444, 0.0983, 0.00960001, + -0.1209, 0.100575, 0.0108, + -0.123356, 0.10285, 0.0096, + -0.125244, 0.1046, 0.006, + -0.126, 0.1053, 1.88291e-008, + -0.123378, 0.094, 1.68085e-008, + -0.124313, 0.094563, 0.00600001, + -0.12665, 0.0959704, 0.00960001, + -0.129689, 0.0978, 0.0108, + -0.132728, 0.0996296, 0.0096, + -0.135065, 0.101037, 0.006, + -0.136, 0.1016, 1.81675e-008, + -0.128022, 0.09095, 1.62631e-008, + -0.129058, 0.091287, 0.00600001, + -0.131646, 0.0921296, 0.00960001, + -0.135011, 0.093225, 0.0108, + -0.138376, 0.0943204, 0.0096, + -0.140965, 0.095163, 0.006, + -0.142, 0.0955, 1.70767e-008, + -0.1296, 0.0864, 1.54495e-008, + -0.130667, 0.0864, 0.00600001, + -0.133333, 0.0864, 0.00960001, + -0.1368, 0.0864, 0.0108, + -0.140267, 0.0864, 0.0096, + -0.142933, 0.0864, 0.006, + -0.144, 0.0864, 1.54495e-008, + -0.0938798, 0.107104, -0.00599999, + -0.0723556, 0.1072, -0.00599999, + -0.0935794, 0.105113, -0.0096, + -0.0732444, 0.1052, -0.0096, + -0.0931889, 0.102525, -0.0108, + -0.0744, 0.1026, -0.0108, + -0.0927983, 0.099937, -0.00959999, + -0.0755556, 0.1, -0.00959999, + -0.0924979, 0.0979463, -0.00599998, + -0.0764444, 0.098, -0.00599998, + -0.0923778, 0.09715, 1.73718e-008, + -0.112, 0.1072, 1.91688e-008, + -0.111513, 0.10643, -0.00599999, + -0.110295, 0.104504, -0.00959999, + -0.108711, 0.102, -0.0108, + -0.107128, 0.0994963, -0.00959999, + -0.105909, 0.0975704, -0.00599998, + -0.105422, 0.0968, 1.73092e-008, + -0.125244, 0.1046, -0.00599999, + -0.123356, 0.10285, -0.0096, + -0.1209, 0.100575, -0.0108, + -0.118444, 0.0983, -0.00959999, + -0.116556, 0.09655, -0.00599998, + -0.136, 0.1016, 1.81675e-008, + -0.135065, 0.101037, -0.00599999, + -0.132728, 0.0996296, -0.0096, + -0.129689, 0.0978, -0.0108, + -0.12665, 0.0959704, -0.00959999, + -0.124313, 0.094563, -0.00599998, + -0.123378, 0.094, 1.68085e-008, + -0.142, 0.0955, 1.70767e-008, + -0.140965, 0.095163, -0.00599999, + -0.138376, 0.0943204, -0.0096, + -0.135011, 0.093225, -0.0108, + -0.131646, 0.0921296, -0.00959999, + -0.129058, 0.091287, -0.00599998, + -0.128022, 0.09095, 1.62631e-008, + -0.142933, 0.0864, -0.00599999, + -0.140267, 0.0864, -0.0096, + -0.1368, 0.0864, -0.0108, + -0.133333, 0.0864, -0.00959999, + -0.130667, 0.0864, -0.00599998, + -0.128778, 0.0802, 1.43409e-008, + -0.129801, 0.079871, 0.00600001, + -0.132358, 0.0790484, 0.00960001, + -0.135683, 0.0779792, 0.0108, + -0.139008, 0.0769099, 0.0096, + -0.141566, 0.0760873, 0.006, + -0.142589, 0.0757583, 1.35466e-008, + -0.126222, 0.0728, 1.30176e-008, + -0.127118, 0.0722568, 0.00600001, + -0.129356, 0.0708988, 0.00960001, + -0.132267, 0.0691333, 0.0108, + -0.135177, 0.0673679, 0.0096, + -0.137416, 0.0660099, 0.00599999, + -0.138311, 0.0654667, 1.17063e-008, + -0.1218, 0.0648, 1.15871e-008, + -0.122489, 0.0641167, 0.00600001, + -0.124211, 0.0624083, 0.00960001, + -0.12645, 0.0601875, 0.0108, + -0.128689, 0.0579667, 0.0096, + -0.130411, 0.0562583, 0.00599999, + -0.1311, 0.055575, 9.93757e-009, + -0.115378, 0.0568, 1.01566e-008, + -0.115786, 0.0560099, 0.00600001, + -0.116807, 0.0540345, 0.0096, + -0.118133, 0.0514667, 0.0108, + -0.11946, 0.0488987, 0.0096, + -0.120481, 0.0469234, 0.00599999, + -0.120889, 0.0461333, 8.24927e-009, + -0.106822, 0.0494, 8.8334e-009, + -0.106881, 0.0484957, 0.00600001, + -0.107027, 0.0462349, 0.00960001, + -0.107217, 0.0432958, 0.0108, + -0.107407, 0.0403568, 0.0096, + -0.107553, 0.038096, 0.00599999, + -0.107611, 0.0371916, 6.65038e-009, + -0.0956444, 0.0421333, 0.00600001, + -0.0947556, 0.0394667, 0.0096, + -0.0936, 0.036, 0.0108, + -0.0924444, 0.0325333, 0.0096, + -0.0915556, 0.0298667, 0.00599999, + -0.0912, 0.0288, 5.14984e-009, + -0.141566, 0.0760873, -0.00599999, + -0.139008, 0.0769099, -0.0096, + -0.135683, 0.0779792, -0.0108, + -0.132358, 0.0790484, -0.00959999, + -0.129801, 0.079871, -0.00599998, + -0.137416, 0.0660099, -0.006, + -0.135177, 0.0673679, -0.0096, + -0.132267, 0.0691333, -0.0108, + -0.129356, 0.0708988, -0.00959999, + -0.127118, 0.0722568, -0.00599998, + -0.130411, 0.0562583, -0.006, + -0.128689, 0.0579667, -0.0096, + -0.12645, 0.0601875, -0.0108, + -0.124211, 0.0624083, -0.00959999, + -0.122489, 0.0641167, -0.00599998, + -0.120481, 0.0469234, -0.006, + -0.11946, 0.0488988, -0.0096, + -0.118133, 0.0514667, -0.0108, + -0.116807, 0.0540346, -0.00959999, + -0.115786, 0.0560099, -0.00599998, + -0.107553, 0.038096, -0.006, + -0.107407, 0.0403568, -0.0096, + -0.107217, 0.0432958, -0.0108, + -0.107027, 0.0462349, -0.00959999, + -0.106881, 0.0484957, -0.00599998, + -0.0915556, 0.0298667, -0.006, + -0.0924444, 0.0325333, -0.0096, + -0.0936, 0.036, -0.0108, + -0.0947556, 0.0394667, -0.00959999, + -0.0956445, 0.0421333, -0.00599998, + 0.0988222, 0.0708667, 1.2672e-008, + 0.0816, 0.0684, 1.22309e-008, + 0.0994741, 0.0684099, 0.0125926, + 0.0816, 0.0654667, 0.0132, + 0.101104, 0.0622679, 0.0201482, + 0.0816, 0.0581333, 0.02112, + 0.103222, 0.0542833, 0.0226667, + 0.0816, 0.0486, 0.02376, + 0.105341, 0.0462987, 0.0201481, + 0.0816, 0.0390666, 0.02112, + 0.10697, 0.0401568, 0.0125926, + 0.0816, 0.0317333, 0.0132, + 0.107622, 0.0377, 6.74128e-009, + 0.0816, 0.0288, 5.14984e-009, + 0.108978, 0.0773333, 1.38283e-008, + 0.109926, 0.0754568, 0.0110741, + 0.112296, 0.0707654, 0.0177185, + 0.115378, 0.0646667, 0.0199333, + 0.118459, 0.0585679, 0.0177185, + 0.12083, 0.0538765, 0.0110741, + 0.121778, 0.052, 9.29832e-009, + 0.1146, 0.0864, 1.54495e-008, + 0.115667, 0.0851333, 0.00910001, + 0.118333, 0.0819667, 0.01456, + 0.1218, 0.07785, 0.01638, + 0.125267, 0.0737333, 0.01456, + 0.127933, 0.0705667, 0.00909999, + 0.129, 0.0693, 1.23918e-008, + 0.118222, 0.0966667, 1.72853e-008, + 0.119407, 0.0959654, 0.00712594, + 0.12237, 0.0942123, 0.0114015, + 0.126222, 0.0919333, 0.0128267, + 0.130074, 0.0896543, 0.0114015, + 0.133037, 0.0879012, 0.00712592, + 0.134222, 0.0872, 1.55926e-008, + 0.122378, 0.106733, 1.90854e-008, + 0.123859, 0.106479, 0.00560742, + 0.127563, 0.105843, 0.00897186, + 0.132378, 0.105017, 0.0100933, + 0.137193, 0.10419, 0.00897185, + 0.140896, 0.103554, 0.00560741, + 0.142378, 0.1033, 1.84715e-008, + 0.1296, 0.1152, 2.05994e-008, + 0.131733, 0.1152, 0.00500001, + 0.137067, 0.1152, 0.00800001, + 0.144, 0.1152, 0.00900001, + 0.150933, 0.1152, 0.008, + 0.156267, 0.1152, 0.005, + 0.1584, 0.1152, 2.05994e-008, + 0.107622, 0.0377, 6.74128e-009, + 0.10697, 0.0401568, -0.0125926, + 0.0816, 0.0317333, -0.0132, + 0.105341, 0.0462988, -0.0201482, + 0.0816, 0.0390667, -0.02112, + 0.103222, 0.0542833, -0.0226667, + 0.0816, 0.0486, -0.02376, + 0.101104, 0.0622679, -0.0201481, + 0.0816, 0.0581334, -0.02112, + 0.0994741, 0.0684099, -0.0125926, + 0.0816, 0.0654667, -0.0132, + 0.0988222, 0.0708667, 1.2672e-008, + 0.121778, 0.052, 9.29832e-009, + 0.12083, 0.0538765, -0.0110741, + 0.118459, 0.0585679, -0.0177185, + 0.115378, 0.0646667, -0.0199333, + 0.112296, 0.0707654, -0.0177185, + 0.109926, 0.0754568, -0.011074, + 0.127933, 0.0705667, -0.0091, + 0.125267, 0.0737333, -0.01456, + 0.1218, 0.07785, -0.01638, + 0.118333, 0.0819667, -0.01456, + 0.115667, 0.0851333, -0.00909997, + 0.134222, 0.0872, 1.55926e-008, + 0.133037, 0.0879012, -0.00712592, + 0.130074, 0.0896543, -0.0114015, + 0.126222, 0.0919333, -0.0128267, + 0.12237, 0.0942123, -0.0114015, + 0.119407, 0.0959654, -0.0071259, + 0.118222, 0.0966667, 1.72853e-008, + 0.142378, 0.1033, 1.84715e-008, + 0.140896, 0.103554, -0.0056074, + 0.137193, 0.10419, -0.00897185, + 0.132378, 0.105017, -0.0100933, + 0.127563, 0.105843, -0.00897184, + 0.123859, 0.106479, -0.00560739, + 0.122378, 0.106733, 1.90854e-008, + 0.156267, 0.1152, -0.00499999, + 0.150933, 0.1152, -0.00799999, + 0.144, 0.1152, -0.00899999, + 0.137067, 0.1152, -0.00799999, + 0.131733, 0.1152, -0.00499998, + 0.131956, 0.1167, 2.08676e-008, + 0.134228, 0.116732, 0.00485187, + 0.139908, 0.116813, 0.00776297, + 0.147292, 0.116919, 0.00873334, + 0.154676, 0.117024, 0.00776297, + 0.160356, 0.117105, 0.00485185, + 0.162628, 0.117137, 2.09458e-008, + 0.134044, 0.1176, 2.10285e-008, + 0.136309, 0.117659, 0.0044815, + 0.141972, 0.117807, 0.00717038, + 0.149333, 0.118, 0.00806668, + 0.156695, 0.118193, 0.00717038, + 0.162357, 0.118341, 0.00448149, + 0.164622, 0.1184, 2.11716e-008, + 0.1356, 0.1179, 2.10822e-008, + 0.137744, 0.117975, 0.00400002, + 0.143106, 0.118162, 0.00640002, + 0.150075, 0.118406, 0.00720001, + 0.157044, 0.11865, 0.00640001, + 0.162406, 0.118838, 0.00400001, + 0.16455, 0.118912, 2.12632e-008, + 0.136356, 0.1176, 2.10285e-008, + 0.138298, 0.117674, 0.00351854, + 0.143154, 0.117859, 0.00562965, + 0.149467, 0.1181, 0.00633335, + 0.155779, 0.118341, 0.00562964, + 0.160635, 0.118526, 0.00351853, + 0.162578, 0.1186, 2.12074e-008, + 0.136044, 0.1167, 2.08676e-008, + 0.137735, 0.116751, 0.00314817, + 0.141963, 0.116878, 0.00503706, + 0.147458, 0.117044, 0.00566668, + 0.152954, 0.117209, 0.00503705, + 0.157181, 0.117337, 0.00314816, + 0.158872, 0.117387, 2.09906e-008, + 0.1344, 0.1152, 2.05994e-008, + 0.135822, 0.1152, 0.00300002, + 0.139378, 0.1152, 0.00480002, + 0.144, 0.1152, 0.00540002, + 0.148622, 0.1152, 0.00480002, + 0.152178, 0.1152, 0.00300001, + 0.1536, 0.1152, 2.05994e-008, + 0.160356, 0.117105, -0.00485184, + 0.154676, 0.117024, -0.00776296, + 0.147292, 0.116919, -0.00873333, + 0.139908, 0.116813, -0.00776295, + 0.134228, 0.116732, -0.00485183, + 0.162357, 0.118341, -0.00448147, + 0.156695, 0.118193, -0.00717036, + 0.149333, 0.118, -0.00806666, + 0.141972, 0.117807, -0.00717036, + 0.136309, 0.117659, -0.00448146, + 0.162406, 0.118837, -0.00399998, + 0.157044, 0.11865, -0.00639999, + 0.150075, 0.118406, -0.00719999, + 0.143106, 0.118162, -0.00639998, + 0.137744, 0.117975, -0.00399998, + 0.160635, 0.118526, -0.0035185, + 0.155779, 0.118341, -0.00562961, + 0.149467, 0.1181, -0.00633332, + 0.143154, 0.117859, -0.00562961, + 0.138298, 0.117674, -0.00351849, + 0.157181, 0.117337, -0.00314813, + 0.152954, 0.117209, -0.00503702, + 0.147458, 0.117044, -0.00566665, + 0.141963, 0.116878, -0.00503701, + 0.137735, 0.116751, -0.00314812, + 0.152178, 0.1152, -0.00299998, + 0.148622, 0.1152, -0.00479998, + 0.144, 0.1152, -0.00539998, + 0.139378, 0.1152, -0.00479998, + 0.135822, 0.1152, -0.00299997, + 0.0133778, 0.1501, 2.684e-008, + 0, 0.1512, 2.70367e-008, + 0.0129094, 0.1501, 0.00360378, + 0, 0.1512, 2.70367e-008, + 0.0115817, 0.1501, 0.00681272, + 0, 0.1512, 2.70367e-008, + 0.00951072, 0.1501, 0.00951074, + 0.00681272, 0.1501, 0.0115817, + 0.00360377, 0.1501, 0.0129094, + 0, 0.1501, 0.0133778, + 0.0174222, 0.1472, 2.63214e-008, + 0.0168122, 0.1472, 0.00469302, + 0.0150829, 0.1472, 0.00887204, + 0.0123858, 0.1472, 0.0123858, + 0.00887205, 0.1472, 0.0150829, + 0.00469303, 0.1472, 0.0168122, + 0, 0.1472, 0.0174222, + 0.0156, 0.1431, 2.55883e-008, + 0.0150536, 0.1431, 0.00420141, + 0.0135049, 0.1431, 0.00794312, + 0.0110895, 0.1431, 0.0110895, + 0.00794312, 0.1431, 0.0135049, + 0.00420141, 0.1431, 0.0150536, + 0, 0.1431, 0.0156, + 0.0113778, 0.1384, 2.47478e-008, + 0.0109789, 0.1384, 0.00306257, + 0.00984863, 0.1384, 0.00579109, + 0.00808622, 0.1384, 0.00808624, + 0.00579109, 0.1384, 0.00984864, + 0.00306257, 0.1384, 0.0109789, + 0, 0.1384, 0.0113778, + 0.00822222, 0.1337, 2.39074e-008, + 0.00793338, 0.1337, 0.00221015, + 0.00711523, 0.1337, 0.00418109, + 0.00584028, 0.1337, 0.0058403, + 0.00418108, 0.1337, 0.00711524, + 0.00221014, 0.1337, 0.0079334, + 0, 0.1337, 0.00822224, + 0.0096, 0.1296, 2.31743e-008, + 0.00926222, 0.1296, 0.0025778, + 0.00830578, 0.1296, 0.00487824, + 0.006816, 0.1296, 0.00681602, + 0.00487823, 0.1296, 0.00830579, + 0.00257779, 0.1296, 0.00926224, + 0, 0.1296, 0.00960002, + 0, 0.1501, 0.0133778, + -0.00360375, 0.1501, 0.0129094, + -0.0068127, 0.1501, 0.0115817, + -0.00951072, 0.1501, 0.00951074, + -0.0115817, 0.1501, 0.00681274, + -0.0129094, 0.1501, 0.00360379, + -0.0133778, 0.1501, 2.684e-008, + 0, 0.1472, 0.0174222, + -0.004693, 0.1472, 0.0168122, + -0.00887203, 0.1472, 0.0150829, + -0.0123858, 0.1472, 0.0123858, + -0.0150829, 0.1472, 0.00887207, + -0.0168122, 0.1472, 0.00469305, + -0.0174222, 0.1472, 2.63214e-008, + -0.00420139, 0.1431, 0.0150536, + -0.0079431, 0.1431, 0.0135049, + -0.0110895, 0.1431, 0.0110895, + -0.0135049, 0.1431, 0.00794314, + -0.0150536, 0.1431, 0.00420143, + -0.0156, 0.1431, 2.55883e-008, + 0, 0.1384, 0.0113778, + -0.00306255, 0.1384, 0.010979, + -0.00579108, 0.1384, 0.00984865, + -0.00808623, 0.1384, 0.00808624, + -0.00984862, 0.1384, 0.00579111, + -0.0109789, 0.1384, 0.00306259, + -0.0113778, 0.1384, 2.47478e-008, + 0, 0.1337, 0.00822224, + -0.00221013, 0.1337, 0.00793341, + -0.00418107, 0.1337, 0.00711525, + -0.00584028, 0.1337, 0.0058403, + -0.00711522, 0.1337, 0.0041811, + -0.00793338, 0.1337, 0.00221017, + -0.00822222, 0.1337, 2.39074e-008, + -0.00257778, 0.1296, 0.00926224, + -0.00487822, 0.1296, 0.0083058, + -0.006816, 0.1296, 0.00681602, + -0.00830577, 0.1296, 0.00487825, + -0.00926222, 0.1296, 0.00257781, + -0.0096, 0.1296, 2.31743e-008, + -0.0133778, 0.1501, 2.684e-008, + -0.0129094, 0.1501, -0.00360373, + -0.0115817, 0.1501, -0.00681268, + -0.00951073, 0.1501, -0.00951071, + -0.00681272, 0.1501, -0.0115816, + -0.00360377, 0.1501, -0.0129094, + 0, 0.1501, -0.0133778, + -0.0174222, 0.1472, 2.63214e-008, + -0.0168122, 0.1472, -0.00469298, + -0.0150829, 0.1472, -0.00887201, + -0.0123858, 0.1472, -0.0123858, + -0.00887205, 0.1472, -0.0150829, + -0.00469303, 0.1472, -0.0168122, + 0, 0.1472, -0.0174222, + -0.0150536, 0.1431, -0.00420136, + -0.0135049, 0.1431, -0.00794309, + -0.0110895, 0.1431, -0.0110895, + -0.00794312, 0.1431, -0.0135049, + -0.00420141, 0.1431, -0.0150536, + 0, 0.1431, -0.0156, + -0.0113778, 0.1384, 2.47478e-008, + -0.0109789, 0.1384, -0.00306252, + -0.00984862, 0.1384, -0.00579105, + -0.00808622, 0.1384, -0.0080862, + -0.00579108, 0.1384, -0.0098486, + -0.00306256, 0.1384, -0.0109789, + 0, 0.1384, -0.0113778, + -0.00822222, 0.1337, 2.39074e-008, + -0.00793338, 0.1337, -0.00221011, + -0.00711523, 0.1337, -0.00418104, + -0.00584028, 0.1337, -0.00584025, + -0.00418108, 0.1337, -0.0071152, + -0.00221014, 0.1337, -0.00793336, + 0, 0.1337, -0.0082222, + -0.00926222, 0.1296, -0.00257775, + -0.00830578, 0.1296, -0.0048782, + -0.006816, 0.1296, -0.00681598, + -0.00487823, 0.1296, -0.00830575, + -0.00257779, 0.1296, -0.0092622, + 0, 0.1296, -0.00959998, + 0.00360375, 0.1501, -0.0129094, + 0.0068127, 0.1501, -0.0115817, + 0.00951073, 0.1501, -0.00951071, + 0.0115817, 0.1501, -0.0068127, + 0.0129094, 0.1501, -0.00360375, + 0.0133778, 0.1501, 2.684e-008, + 0.004693, 0.1472, -0.0168122, + 0.00887203, 0.1472, -0.0150829, + 0.0123858, 0.1472, -0.0123858, + 0.0150829, 0.1472, -0.00887203, + 0.0168122, 0.1472, -0.004693, + 0.0174222, 0.1472, 2.63214e-008, + 0.00420139, 0.1431, -0.0150536, + 0.0079431, 0.1431, -0.0135049, + 0.0110895, 0.1431, -0.0110895, + 0.0135049, 0.1431, -0.00794311, + 0.0150536, 0.1431, -0.00420139, + 0.00306255, 0.1384, -0.0109789, + 0.00579107, 0.1384, -0.0098486, + 0.00808622, 0.1384, -0.0080862, + 0.00984861, 0.1384, -0.00579106, + 0.0109789, 0.1384, -0.00306254, + 0.0113778, 0.1384, 2.47478e-008, + 0.00221013, 0.1337, -0.00793336, + 0.00418106, 0.1337, -0.00711521, + 0.00584028, 0.1337, -0.00584025, + 0.00711522, 0.1337, -0.00418105, + 0.00793338, 0.1337, -0.00221012, + 0.00822222, 0.1337, 2.39074e-008, + 0.00257778, 0.1296, -0.0092622, + 0.00487822, 0.1296, -0.00830576, + 0.006816, 0.1296, -0.00681598, + 0.00830577, 0.1296, -0.00487821, + 0.00926222, 0.1296, -0.00257777, + 0.0168444, 0.126533, 2.26259e-008, + 0.0162518, 0.126533, 0.00452306, + 0.0145736, 0.126533, 0.00855948, + 0.0119595, 0.126533, 0.0119596, + 0.00855948, 0.126533, 0.0145736, + 0.00452306, 0.126533, 0.0162518, + 0, 0.126533, 0.0168444, + 0.0275555, 0.124267, 2.22206e-008, + 0.026586, 0.124267, 0.00739918, + 0.0238406, 0.124267, 0.0140023, + 0.0195644, 0.124267, 0.0195644, + 0.0140023, 0.124267, 0.0238406, + 0.0073992, 0.124267, 0.026586, + 0, 0.124267, 0.0275555, + 0.0396, 0.1224, 2.18868e-008, + 0.0382067, 0.1224, 0.0106333, + 0.0342613, 0.1224, 0.0201227, + 0.028116, 0.1224, 0.028116, + 0.0201227, 0.1224, 0.0342613, + 0.0106334, 0.1224, 0.0382067, + 0, 0.1224, 0.0396, + 0.0508444, 0.120533, 2.1553e-008, + 0.0490554, 0.120533, 0.0136527, + 0.0439898, 0.120533, 0.0258365, + 0.0360995, 0.120533, 0.0360995, + 0.0258365, 0.120533, 0.0439898, + 0.0136527, 0.120533, 0.0490554, + 0, 0.120533, 0.0508444, + 0.0591555, 0.118267, 2.11477e-008, + 0.0570741, 0.118267, 0.0158844, + 0.0511805, 0.118267, 0.0300598, + 0.0420004, 0.118267, 0.0420004, + 0.0300598, 0.118267, 0.0511805, + 0.0158844, 0.118267, 0.0570741, + 0, 0.118267, 0.0591555, + 0.0624, 0.1152, 2.05994e-008, + 0.0602044, 0.1152, 0.0167556, + 0.0539876, 0.1152, 0.0317084, + 0.044304, 0.1152, 0.044304, + 0.0317085, 0.1152, 0.0539875, + 0.0167556, 0.1152, 0.0602044, + 0, 0.1152, 0.0624, + -0.00452304, 0.126533, 0.0162518, + -0.00855946, 0.126533, 0.0145736, + -0.0119595, 0.126533, 0.0119596, + -0.0145735, 0.126533, 0.0085595, + -0.0162518, 0.126533, 0.00452308, + -0.0168444, 0.126533, 2.26259e-008, + -0.00739916, 0.124267, 0.026586, + -0.0140023, 0.124267, 0.0238407, + -0.0195644, 0.124267, 0.0195644, + -0.0238406, 0.124267, 0.0140023, + -0.026586, 0.124267, 0.00739922, + -0.0275555, 0.124267, 2.22206e-008, + -0.0106333, 0.1224, 0.0382067, + -0.0201227, 0.1224, 0.0342613, + -0.028116, 0.1224, 0.028116, + -0.0342613, 0.1224, 0.0201227, + -0.0382067, 0.1224, 0.0106334, + -0.0396, 0.1224, 2.18868e-008, + -0.0136527, 0.120533, 0.0490554, + -0.0258365, 0.120533, 0.0439898, + -0.0360995, 0.120533, 0.0360995, + -0.0439898, 0.120533, 0.0258365, + -0.0490554, 0.120533, 0.0136527, + -0.0508444, 0.120533, 2.1553e-008, + -0.0158843, 0.118267, 0.0570741, + -0.0300597, 0.118267, 0.0511805, + -0.0420004, 0.118267, 0.0420004, + -0.0511805, 0.118267, 0.0300598, + -0.0570741, 0.118267, 0.0158844, + -0.0591555, 0.118267, 2.11477e-008, + -0.0167555, 0.1152, 0.0602044, + -0.0317084, 0.1152, 0.0539876, + -0.044304, 0.1152, 0.044304, + -0.0539875, 0.1152, 0.0317085, + -0.0602044, 0.1152, 0.0167556, + -0.0624, 0.1152, 2.05994e-008, + -0.0162518, 0.126533, -0.00452302, + -0.0145736, 0.126533, -0.00855945, + -0.0119595, 0.126533, -0.0119595, + -0.00855948, 0.126533, -0.0145735, + -0.00452306, 0.126533, -0.0162517, + 0, 0.126533, -0.0168444, + -0.026586, 0.124267, -0.00739915, + -0.0238406, 0.124267, -0.0140023, + -0.0195644, 0.124267, -0.0195644, + -0.0140023, 0.124267, -0.0238406, + -0.0073992, 0.124267, -0.026586, + 0, 0.124267, -0.0275555, + -0.0382067, 0.1224, -0.0106333, + -0.0342613, 0.1224, -0.0201226, + -0.028116, 0.1224, -0.028116, + -0.0201227, 0.1224, -0.0342613, + -0.0106334, 0.1224, -0.0382066, + 0, 0.1224, -0.0396, + -0.0490554, 0.120533, -0.0136526, + -0.0439898, 0.120533, -0.0258365, + -0.0360995, 0.120533, -0.0360995, + -0.0258365, 0.120533, -0.0439898, + -0.0136527, 0.120533, -0.0490554, + 0, 0.120533, -0.0508444, + -0.0570741, 0.118267, -0.0158843, + -0.0511805, 0.118267, -0.0300597, + -0.0420004, 0.118267, -0.0420004, + -0.0300598, 0.118267, -0.0511805, + -0.0158844, 0.118267, -0.0570741, + 0, 0.118267, -0.0591555, + -0.0602044, 0.1152, -0.0167555, + -0.0539876, 0.1152, -0.0317084, + -0.044304, 0.1152, -0.044304, + -0.0317085, 0.1152, -0.0539875, + -0.0167556, 0.1152, -0.0602044, + 0, 0.1152, -0.0624, + 0.00452304, 0.126533, -0.0162517, + 0.00855946, 0.126533, -0.0145735, + 0.0119595, 0.126533, -0.0119595, + 0.0145735, 0.126533, -0.00855947, + 0.0162518, 0.126533, -0.00452304, + 0.00739916, 0.124267, -0.026586, + 0.0140023, 0.124267, -0.0238406, + 0.0195644, 0.124267, -0.0195644, + 0.0238406, 0.124267, -0.0140023, + 0.026586, 0.124267, -0.00739919, + 0.0106333, 0.1224, -0.0382067, + 0.0201227, 0.1224, -0.0342613, + 0.028116, 0.1224, -0.028116, + 0.0342613, 0.1224, -0.0201227, + 0.0382067, 0.1224, -0.0106334, + 0.0136527, 0.120533, -0.0490554, + 0.0258365, 0.120533, -0.0439898, + 0.0360995, 0.120533, -0.0360995, + 0.0439898, 0.120533, -0.0258365, + 0.0490554, 0.120533, -0.0136527, + 0.0158843, 0.118267, -0.0570741, + 0.0300597, 0.118267, -0.0511805, + 0.0420004, 0.118267, -0.0420004, + 0.0511805, 0.118267, -0.0300598, + 0.0570741, 0.118267, -0.0158844, + 0.0167555, 0.1152, -0.0602044, + 0.0317084, 0.1152, -0.0539876, + 0.044304, 0.1152, -0.044304, + 0.0539875, 0.1152, -0.0317085, + 0.0602044, 0.1152, -0.0167556, + 0.0290833, 0.000283333, 5.06639e-011, + 0, 0, 0, + 0.02806, 0.000283335, -0.00780941, + 0.0251625, 0.000283336, -0.0147786, + 0.0206492, 0.000283337, -0.0206492, + 0.0147787, 0.000283338, -0.0251625, + 0.00780945, 0.000283338, -0.02806, + 0, 0.000283338, -0.0290833, + 0.0490667, 0.00106667, 1.90735e-010, + 0.0473403, 0.00106667, -0.0131753, + 0.0424518, 0.00106667, -0.0249331, + 0.0348373, 0.00106667, -0.0348373, + 0.0249332, 0.00106667, -0.0424517, + 0.0131754, 0.00106667, -0.0473402, + 0, 0.00106667, -0.0490667, + 0.06165, 0.00225, 4.02331e-010, + 0.0594808, 0.00225, -0.0165542, + 0.0533387, 0.00225001, -0.0313273, + 0.0437715, 0.00225001, -0.0437715, + 0.0313274, 0.00225001, -0.0533386, + 0.0165542, 0.00225001, -0.0594808, + 0, 0.00225001, -0.06165, + 0.0685333, 0.00373333, 6.67572e-010, + 0.066122, 0.00373334, -0.0184025, + 0.059294, 0.00373334, -0.0348251, + 0.0486587, 0.00373334, -0.0486587, + 0.0348251, 0.00373334, -0.059294, + 0.0184026, 0.00373334, -0.066122, + 0, 0.00373334, -0.0685333, + 0.0714167, 0.00541667, 9.68575e-010, + 0.0689039, 0.00541667, -0.0191767, + 0.0617887, 0.00541667, -0.0362902, + 0.0507058, 0.00541668, -0.0507058, + 0.0362903, 0.00541668, -0.0617886, + 0.0191768, 0.00541668, -0.0689038, + 0, 0.00541668, -0.0714167, + 0.0694667, 0.0072, -0.0193333, + 0.0622933, 0.00720001, -0.0365866, + 0.0365867, 0.00720001, -0.0622933, + 0.0193334, 0.00720001, -0.0694666, + 0, 0.000283338, -0.0290833, + -0.0078094, 0.000283338, -0.02806, + -0.0147786, 0.000283338, -0.0251625, + -0.0206492, 0.000283337, -0.0206492, + -0.0251624, 0.000283336, -0.0147787, + -0.02806, 0.000283335, -0.00780945, + -0.0290833, 0.000283333, 5.06639e-011, + 0, 0.00106667, -0.0490667, + -0.0131753, 0.00106667, -0.0473402, + -0.0249331, 0.00106667, -0.0424518, + -0.0348373, 0.00106667, -0.0348373, + -0.0424517, 0.00106667, -0.0249332, + -0.0473402, 0.00106667, -0.0131754, + -0.0490667, 0.00106667, 1.90735e-010, + -0.0165542, 0.00225001, -0.0594808, + -0.0313273, 0.00225001, -0.0533387, + -0.0437715, 0.00225001, -0.0437715, + -0.0533386, 0.00225001, -0.0313274, + -0.0594808, 0.00225, -0.0165542, + -0.06165, 0.00225, 4.02331e-010, + 0, 0.00373334, -0.0685333, + -0.0184024, 0.00373334, -0.066122, + -0.0348251, 0.00373334, -0.059294, + -0.0486587, 0.00373334, -0.0486587, + -0.059294, 0.00373334, -0.0348251, + -0.0661219, 0.00373334, -0.0184026, + -0.0685333, 0.00373333, 6.67572e-010, + 0, 0.00541667, -0.0714167, + -0.0191767, 0.00541668, -0.0689039, + -0.0362902, 0.00541667, -0.0617887, + -0.0507058, 0.00541667, -0.0507058, + -0.0617886, 0.00541667, -0.0362903, + -0.0689038, 0.00541667, -0.0191768, + -0.0714167, 0.00541666, 9.68575e-010, + -0.0193333, 0.00720001, -0.0694667, + -0.0365866, 0.00720001, -0.0622933, + -0.0622933, 0.00720001, -0.0365867, + -0.0694666, 0.0072, -0.0193334, + -0.0290833, 0.000283334, 5.0664e-011, + -0.02806, 0.000283332, 0.00780941, + -0.0251625, 0.000283331, 0.0147786, + -0.0206492, 0.00028333, 0.0206492, + -0.0147787, 0.000283329, 0.0251625, + -0.00780945, 0.000283329, 0.02806, + 0, 0.000283329, 0.0290833, + -0.0490667, 0.00106667, 1.90735e-010, + -0.0473403, 0.00106667, 0.0131753, + -0.0424518, 0.00106666, 0.0249331, + -0.0348374, 0.00106666, 0.0348374, + -0.0249332, 0.00106666, 0.0424517, + -0.0131754, 0.00106666, 0.0473402, + 0, 0.00106666, 0.0490667, + -0.0594808, 0.00225, 0.0165542, + -0.0533387, 0.00224999, 0.0313273, + -0.0437715, 0.00224999, 0.0437715, + -0.0313274, 0.00224999, 0.0533386, + -0.0165542, 0.00224999, 0.0594808, + 0, 0.00224999, 0.06165, + -0.0685333, 0.00373334, 6.67572e-010, + -0.066122, 0.00373333, 0.0184025, + -0.059294, 0.00373333, 0.0348251, + -0.0486587, 0.00373333, 0.0486587, + -0.0348251, 0.00373333, 0.059294, + -0.0184026, 0.00373333, 0.066122, + 0, 0.00373333, 0.0685333, + -0.0714167, 0.00541667, 9.68576e-010, + -0.0689039, 0.00541667, 0.0191767, + -0.0617887, 0.00541666, 0.0362902, + -0.0507058, 0.00541666, 0.0507058, + -0.0362903, 0.00541666, 0.0617886, + -0.0191768, 0.00541666, 0.0689038, + 0, 0.00541666, 0.0714167, + -0.0694667, 0.0072, 0.0193333, + -0.0622933, 0.00719999, 0.0365866, + -0.05112, 0.00719999, 0.05112, + -0.0365867, 0.00719999, 0.0622933, + -0.0193334, 0.00719999, 0.0694666, + 0.00780941, 0.000283329, 0.02806, + 0.0147786, 0.000283329, 0.0251625, + 0.0206492, 0.00028333, 0.0206492, + 0.0251625, 0.000283331, 0.0147787, + 0.02806, 0.000283332, 0.00780945, + 0.0290833, 0.000283334, 5.0664e-011, + 0.0131753, 0.00106666, 0.0473403, + 0.0249331, 0.00106666, 0.0424518, + 0.0348374, 0.00106666, 0.0348374, + 0.0424517, 0.00106666, 0.0249332, + 0.0473402, 0.00106666, 0.0131754, + 0.0490667, 0.00106667, 1.90735e-010, + 0.0165542, 0.00224999, 0.0594808, + 0.0313273, 0.00224999, 0.0533387, + 0.0437715, 0.00224999, 0.0437715, + 0.0533386, 0.00224999, 0.0313274, + 0.0594808, 0.00225, 0.0165542, + 0.0184025, 0.00373333, 0.066122, + 0.0348251, 0.00373333, 0.059294, + 0.0486587, 0.00373333, 0.0486587, + 0.059294, 0.00373333, 0.0348251, + 0.066122, 0.00373333, 0.0184026, + 0.0685333, 0.00373334, 6.67572e-010, + 0.0191767, 0.00541666, 0.0689039, + 0.0362902, 0.00541666, 0.0617887, + 0.0507058, 0.00541666, 0.0507058, + 0.0617886, 0.00541666, 0.0362903, + 0.0689038, 0.00541667, 0.0191768, + 0.0714167, 0.00541667, 9.68576e-010, + 0.0193333, 0.00719999, 0.0694667, + 0.0365866, 0.00719999, 0.0622933, + 0.05112, 0.00719999, 0.05112, + 0.0622933, 0.00719999, 0.0365867, + 0.0694666, 0.0072, 0.0193334, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + -0.06165, 0.00225, 4.02331e-010, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0.06165, 0.00225, 4.02331e-010, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0.006816, 0.1296, 0.00681602, + 0.00487823, 0.1296, 0.00830579, + 0.00257779, 0.1296, 0.00926224, + 0, 0.1296, 0.00960002, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0.00830577, 0.1296, -0.00487821, + 0.00487822, 0.1296, -0.00830576, + 0.00257778, 0.1296, -0.0092622, + 0, 0.1296, -0.00959998, + -0.00257779, 0.1296, -0.0092622, + -0.00487823, 0.1296, -0.00830575, + -0.00830578, 0.1296, -0.0048782, + -0.00257778, 0.1296, 0.00926224, + -0.00487822, 0.1296, 0.0083058, + -0.006816, 0.1296, 0.00681602, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0, 0.1512, 2.70367e-008, + 0.156267, 0.1152, -0.00499999, + 0.131733, 0.1152, -0.00499998, + 0.1296, 0.1152, 2.05994e-008, + 0.137067, 0.1152, 0.00800001, + -0.094, 0.1079, 1.9294e-008, + -0.096, 0.0432, 7.72476e-009, + -0.0897778, 0.0250667, 4.48227e-009, + 0.0897778, 0.0250667, 4.48227e-009, + -0.084, 0.01845, 3.29912e-009, + 0.084, 0.01845, 3.29912e-009, + -0.0782222, 0.0133334, 2.38419e-009, + 0.0782222, 0.0133334, 2.38419e-009, + -0.0737778, 0.00961668, 1.7196e-009, + 0.0737778, 0.00961668, 1.7196e-009, + 0.0926222, 0.0432, 0.0257778, + 0.072, 0.1152, 2.05994e-008, + 0.05112, 0.1152, -0.05112, + 0, 0.1152, -0.072, + -0.05112, 0.1152, -0.05112, + -0.072, 0.1152, 2.05994e-008, + 0, 0.1152, 0.072, + -0.05112, 0.1152, 0.05112, + -0.0687556, 0.1194, 2.13504e-008, + 0.05112, 0.1152, 0.05112, + 0, 0.117825, 0.0663056, + -0.0396, 0.1224, 2.18868e-008, + 0.0396, 0.1224, 2.18868e-008}; + +float teapot_normals[] = { + -0.987635, -0.156768, 0, + -0.902861, -0.429933, 0, + -0.953562, -0.156989, -0.257047, + -0.871509, -0.430441, -0.234929, + -0.854265, -0.157281, -0.495474, + -0.780517, -0.431109, -0.4527, + -0.698293, -0.157393, -0.698294, + -0.637936, -0.431366, -0.637936, + -0.495474, -0.157281, -0.854265, + -0.4527, -0.431109, -0.780517, + -0.257047, -0.156989, -0.953562, + -0.234929, -0.430441, -0.871509, + 0, -0.156767, -0.987636, + 0, -0.429933, -0.902861, + -0.880022, 0.474932, 0, + -0.849414, 0.475466, -0.228973, + -0.76067, 0.476166, -0.441189, + -0.621695, 0.476435, -0.621695, + -0.441189, 0.476166, -0.76067, + -0.228972, 0.475466, -0.849414, + 0, 0.474932, -0.880022, + 0, 1, 0, + -3.12489e-007, 1, -4.53013e-008, + -4.74898e-007, 1, -2.15741e-007, + 0, 1, 0, + -1.19502e-007, 1, -2.57504e-007, + -5.01339e-008, 1, -1.37835e-007, + 0, 1, 0, + 0.556738, 0.830688, 0, + 0.537013, 0.831061, 0.14476, + 0.480481, 0.83155, 0.278679, + 0.392564, 0.831738, 0.392564, + 0.278679, 0.83155, 0.480481, + 0.14476, 0.831061, 0.537012, + 0, 0.830688, 0.556738, + 0.783289, 0.621658, 0, + 0.755869, 0.622211, 0.203756, + 0.67669, 0.622937, 0.39248, + 0.552994, 0.623214, 0.552994, + 0.39248, 0.622936, 0.676691, + 0.203756, 0.62221, 0.755869, + 0, 0.621658, 0.783289, + 0.90286, 0.429934, 0, + 0.871509, 0.430442, 0.234929, + 0.780517, 0.431109, 0.4527, + 0.637935, 0.431366, 0.637936, + 0.4527, 0.431109, 0.780517, + 0.234929, 0.430441, 0.87151, + 0, 0.429934, 0.90286, + 0.257047, -0.156989, -0.953562, + 0.234929, -0.430441, -0.871509, + 0.495474, -0.157281, -0.854265, + 0.4527, -0.431109, -0.780517, + 0.698293, -0.157393, -0.698294, + 0.637936, -0.431366, -0.637936, + 0.854265, -0.157281, -0.495474, + 0.780517, -0.431109, -0.4527, + 0.953562, -0.156989, -0.257047, + 0.871509, -0.430441, -0.234929, + 0.987636, -0.156767, 0, + 0.902861, -0.429933, 0, + 0.228973, 0.475465, -0.849414, + 0.441188, 0.476167, -0.760669, + 0.621695, 0.476434, -0.621696, + 0.76067, 0.476167, -0.441188, + 0.849414, 0.475466, -0.228972, + 0.880022, 0.474932, 0, + 4.53013e-008, 1, -3.12489e-007, + 2.15741e-007, 1, -4.74898e-007, + 0, 1, 0, + 2.57504e-007, 1, -1.19502e-007, + 1.37835e-007, 1, -5.01339e-008, + 0, 1, 0, + 0, 0.830689, 0.556737, + -0.14476, 0.831061, 0.537012, + -0.278679, 0.83155, 0.480481, + -0.392563, 0.831738, 0.392563, + -0.480482, 0.83155, 0.27868, + -0.537012, 0.831061, 0.14476, + -0.556738, 0.830688, 0, + 0, 0.621658, 0.783289, + -0.203756, 0.62221, 0.755869, + -0.39248, 0.622937, 0.67669, + -0.552993, 0.623215, 0.552993, + -0.67669, 0.622937, 0.39248, + -0.755869, 0.62221, 0.203756, + -0.783289, 0.621658, 0, + -0.234929, 0.430442, 0.871509, + -0.4527, 0.431109, 0.780517, + -0.637935, 0.431366, 0.637936, + -0.780517, 0.431109, 0.4527, + -0.87151, 0.430441, 0.234929, + -0.90286, 0.429934, 0, + 0.987636, -0.156767, 0, + 0.953562, -0.156989, 0.257047, + 0.871509, -0.430441, 0.234929, + 0.854265, -0.15728, 0.495474, + 0.780517, -0.431109, 0.4527, + 0.698294, -0.157393, 0.698293, + 0.637936, -0.431366, 0.637936, + 0.495474, -0.157281, 0.854265, + 0.4527, -0.431109, 0.780517, + 0.257047, -0.156989, 0.953562, + 0.234929, -0.430441, 0.871509, + 0, -0.156767, 0.987636, + 0, -0.429933, 0.902861, + 0.880022, 0.474934, 0, + 0.849413, 0.475467, 0.228972, + 0.760669, 0.476167, 0.441188, + 0.621695, 0.476436, 0.621695, + 0.441188, 0.476167, 0.760669, + 0.228972, 0.475466, 0.849414, + 0, 0.474934, 0.880022, + 3.12489e-007, 1, 4.53013e-008, + 4.74898e-007, 1, 2.15741e-007, + 0, 1, 0, + 1.19502e-007, 1, 2.57504e-007, + 5.01339e-008, 1, 1.37835e-007, + 0, 1, 0, + -0.537013, 0.831061, -0.14476, + -0.480482, 0.83155, -0.27868, + -0.392566, 0.831735, -0.392566, + -0.27868, 0.83155, -0.480482, + -0.14476, 0.831061, -0.537012, + 0, 0.830688, -0.556738, + -0.783289, 0.621657, 0, + -0.755869, 0.62221, -0.203756, + -0.676691, 0.622936, -0.39248, + -0.552994, 0.623215, -0.552993, + -0.392481, 0.622936, -0.676691, + -0.203756, 0.622209, -0.75587, + 0, 0.621657, -0.783289, + -0.871509, 0.430442, -0.234929, + -0.780517, 0.431109, -0.4527, + -0.637936, 0.431366, -0.637935, + -0.4527, 0.431109, -0.780517, + -0.234929, 0.430441, -0.87151, + 0, 0.429934, -0.90286, + -0.257047, -0.156989, 0.953562, + -0.234929, -0.430441, 0.871509, + -0.495474, -0.15728, 0.854265, + -0.4527, -0.431109, 0.780517, + -0.698294, -0.157393, 0.698293, + -0.637936, -0.431366, 0.637936, + -0.854265, -0.157281, 0.495474, + -0.780517, -0.431109, 0.4527, + -0.953562, -0.156989, 0.257047, + -0.871509, -0.430442, 0.234928, + -0.987636, -0.156767, 0, + -0.228972, 0.475467, 0.849413, + -0.441188, 0.476167, 0.760669, + -0.621695, 0.476436, 0.621695, + -0.76067, 0.476167, 0.441188, + -0.849414, 0.475466, 0.228972, + -0.880022, 0.474934, 0, + -4.53013e-008, 1, 3.12489e-007, + -2.15741e-007, 1, 4.74898e-007, + 0, 1, 0, + -2.57504e-007, 1, 1.19502e-007, + -1.37835e-007, 1, 5.01339e-008, + 0.14476, 0.831061, -0.537013, + 0.27868, 0.83155, -0.480482, + 0.392566, 0.831735, -0.392566, + 0.480482, 0.83155, -0.27868, + 0.537012, 0.831061, -0.14476, + 0.556738, 0.830688, 0, + 0.203756, 0.62221, -0.755869, + 0.392481, 0.622936, -0.67669, + 0.552994, 0.623215, -0.552993, + 0.676691, 0.622936, -0.39248, + 0.75587, 0.622209, -0.203756, + 0.783289, 0.621657, 0, + 0.234929, 0.430442, -0.871509, + 0.4527, 0.431109, -0.780517, + 0.637936, 0.431366, -0.637935, + 0.780517, 0.431109, -0.4527, + 0.87151, 0.430441, -0.234928, + 0.906828, 0.421501, 0, + 0.875348, 0.422003, 0.235963, + 0.871509, 0.430442, 0.234929, + 0.783966, 0.422664, 0.4547, + 0.780517, 0.43111, 0.4527, + 0.640758, 0.422917, 0.640758, + 0.4547, 0.422664, 0.783966, + 0.4527, 0.43111, 0.780517, + 0.235964, 0.422003, 0.875348, + 0.234929, 0.430442, 0.871509, + 0, 0.421501, 0.906828, + 0.918633, 0.395111, 0, + 0.886771, 0.395595, 0.239043, + 0.794229, 0.39623, 0.460653, + 0.649156, 0.396474, 0.649157, + 0.460653, 0.39623, 0.794229, + 0.239043, 0.395595, 0.886771, + 0, 0.395111, 0.918633, + 0.937749, 0.347314, 0, + 0.905271, 0.347757, 0.244029, + 0.810853, 0.34834, 0.470295, + 0.662761, 0.348563, 0.662761, + 0.470295, 0.34834, 0.810853, + 0.24403, 0.347757, 0.90527, + 0, 0.347314, 0.937749, + 0.96234, 0.271848, 0, + 0.929073, 0.272213, 0.250446, + 0.832247, 0.272693, 0.482704, + 0.680271, 0.272877, 0.680271, + 0.482704, 0.272693, 0.832247, + 0.250446, 0.272213, 0.929073, + 0, 0.271848, 0.96234, + 0.987204, 0.15946, 0, + 0.953145, 0.159686, 0.256935, + 0.85389, 0.159982, 0.495256, + 0.697986, 0.160096, 0.697986, + 0.495256, 0.159982, 0.853889, + 0.256935, 0.159686, 0.953145, + 0, 0.15946, 0.987204, + 1, 0, 0, + 0.965535, -2.69333e-008, 0.260275, + 0.865031, -2.6582e-008, 0.501718, + 0.707107, -1.58051e-008, 0.707107, + 0.501718, -5.72888e-009, 0.865031, + 0.260275, -7.99313e-010, 0.965535, + 0, 0, 1, + 0, 0.421501, 0.906828, + -0.235963, 0.422003, 0.875348, + -0.234928, 0.430442, 0.871509, + -0.4547, 0.422664, 0.783966, + -0.4527, 0.43111, 0.780517, + -0.640758, 0.422917, 0.640758, + -0.783966, 0.422664, 0.454701, + -0.780517, 0.43111, 0.4527, + -0.875348, 0.422003, 0.235964, + -0.871509, 0.430442, 0.234929, + -0.906828, 0.421501, 0, + 0, 0.395111, 0.918633, + -0.239043, 0.395595, 0.886771, + -0.460653, 0.39623, 0.794229, + -0.649157, 0.396474, 0.649157, + -0.794229, 0.39623, 0.460653, + -0.886771, 0.395595, 0.239043, + -0.918633, 0.395111, 0, + -0.244029, 0.347757, 0.905271, + -0.470295, 0.34834, 0.810853, + -0.662761, 0.348563, 0.662761, + -0.810853, 0.34834, 0.470295, + -0.90527, 0.347757, 0.24403, + -0.937749, 0.347314, 0, + 0, 0.271848, 0.96234, + -0.250446, 0.272213, 0.929073, + -0.482703, 0.272693, 0.832248, + -0.680271, 0.272877, 0.680271, + -0.832247, 0.272693, 0.482704, + -0.929073, 0.272213, 0.250446, + -0.96234, 0.271848, 0, + 0, 0.159461, 0.987204, + -0.256935, 0.159686, 0.953145, + -0.495256, 0.159983, 0.853889, + -0.697986, 0.160096, 0.697986, + -0.853889, 0.159982, 0.495256, + -0.953145, 0.159686, 0.256935, + -0.987204, 0.159461, 0, + -0.260274, -7.9931e-010, 0.965535, + -0.501718, -5.72887e-009, 0.865031, + -0.707107, -1.58051e-008, 0.707107, + -0.865031, -2.6582e-008, 0.501718, + -0.965535, -2.69333e-008, 0.260275, + 0.410365, 0.911921, 0, + -0.906828, 0.421501, 0, + -0.875348, 0.422003, -0.235963, + -0.871509, 0.430442, -0.234928, + -0.783966, 0.422664, -0.4547, + -0.780517, 0.43111, -0.4527, + -0.640758, 0.422917, -0.640758, + -0.454701, 0.422664, -0.783966, + -0.4527, 0.43111, -0.780517, + -0.235964, 0.422003, -0.875348, + -0.234929, 0.430442, -0.871509, + 0, 0.421501, -0.906828, + -0.918633, 0.395111, 0, + -0.886771, 0.395595, -0.239043, + -0.794229, 0.39623, -0.460653, + -0.649157, 0.396474, -0.649156, + -0.460653, 0.39623, -0.794229, + -0.239043, 0.395595, -0.886771, + 0, 0.395111, -0.918633, + -0.905271, 0.347757, -0.244029, + -0.810853, 0.34834, -0.470295, + -0.662761, 0.348563, -0.662761, + -0.470295, 0.34834, -0.810853, + -0.24403, 0.347757, -0.90527, + 0, 0.347314, -0.937749, + -0.96234, 0.271847, 0, + -0.929073, 0.272213, -0.250446, + -0.832248, 0.272693, -0.482703, + -0.680271, 0.272877, -0.680271, + -0.482704, 0.272693, -0.832247, + -0.250446, 0.272213, -0.929073, + 0, 0.271847, -0.96234, + -0.987204, 0.15946, 0, + -0.953145, 0.159685, -0.256935, + -0.85389, 0.159982, -0.495256, + -0.697986, 0.160096, -0.697986, + -0.495256, 0.159982, -0.853889, + -0.256935, 0.159685, -0.953145, + 0, 0.15946, -0.987204, + -0.965535, 2.69333e-008, -0.260274, + -0.865031, 2.6582e-008, -0.501718, + -0.707107, 1.58051e-008, -0.707107, + -0.501718, 5.72888e-009, -0.865031, + -0.260275, 7.99313e-010, -0.965535, + 0, 0 , -1, + 0.235963, 0.422003, -0.875348, + 0.234928, 0.430442, -0.871509, + 0.4547, 0.422664, -0.783966, + 0.4527, 0.43111, -0.780517, + 0.640758, 0.422917, -0.640758, + 0.783966, 0.422664, -0.4547, + 0.780517, 0.43111, -0.4527, + 0.875348, 0.422003, -0.235964, + 0.871509, 0.430442, -0.234929, + 0.906828, 0.421501, 0, + 0.239043, 0.395595, -0.886771, + 0.460653, 0.39623, -0.794229, + 0.649157, 0.396474, -0.649156, + 0.794229, 0.39623, -0.460653, + 0.886771, 0.395595, -0.239043, + 0.918633, 0.395111, 0, + 0.244029, 0.347757, -0.905271, + 0.470295, 0.34834, -0.810853, + 0.662761, 0.348563, -0.662761, + 0.810853, 0.34834, -0.470295, + 0.90527, 0.347757, -0.24403, + 0.250446, 0.272213, -0.929073, + 0.482704, 0.272693, -0.832247, + 0.680271, 0.272877, -0.680271, + 0.832247, 0.272693, -0.482704, + 0.929073, 0.272213, -0.250446, + 0.96234, 0.271847, 0, + 0.256935, 0.159685, -0.953145, + 0.495256, 0.159982, -0.85389, + 0.697986, 0.160096, -0.697986, + 0.853889, 0.159982, -0.495256, + 0.953145, 0.159685, -0.256935, + 0.987204, 0.15946, 0, + 0.260274, 7.9931e-010, -0.965535, + 0.501718, 5.72887e-009, -0.865031, + 0.707107, 1.58051e-008, -0.707107, + 0.865031, 2.6582e-008, -0.501718, + 0.965535, 2.69333e-008, -0.260275, + 0.938373, -0.345625, -3.10672e-010, + 0.905874, -0.346066, 0.244192, + 0.811396, -0.346647, 0.470609, + 0.663205, -0.346869, 0.663205, + 0.47061, -0.346647, 0.811395, + 0.244192, -0.346066, 0.905874, + 0, -0.345625, 0.938373, + 0.811257, -0.584689, -4.41262e-009, + 0.782908, -0.585247, 0.211045, + 0.700957, -0.58598, 0.406555, + 0.572843, -0.586261, 0.572843, + 0.406555, -0.58598, 0.700957, + 0.211045, -0.585247, 0.782908, + 0, -0.584689, 0.811257, + 0.6981, -0.716, -1.94916e-008, + 0.673539, -0.716506, 0.181563, + 0.602839, -0.717169, 0.349647, + 0.492597, -0.717423, 0.492597, + 0.349647, -0.717169, 0.602839, + 0.181563, -0.716506, 0.673539, + 0, -0.716, 0.6981, + 0.636383, -0.771373, -5.3452e-008, + 0.61392, -0.771826, 0.165491, + 0.549392, -0.772419, 0.318648, + 0.448897, -0.772647, 0.448897, + 0.318648, -0.772419, 0.549392, + 0.165492, -0.771826, 0.61392, + 0, -0.771373, 0.636383, + 0.675056, -0.737767, -1.05865e-007, + 0.651275, -0.738254, 0.175561, + 0.582878, -0.738893, 0.338069, + 0.476275, -0.739138, 0.476275, + 0.338069, -0.738893, 0.582878, + 0.175561, -0.738254, 0.651275, + 0, -0.737767, 0.675056, + 1, 0, 0, + 0.965535, -2.69332e-008, 0.260274, + 0.865031, -2.65819e-008, 0.501718, + 0.707107, -1.5805e-008, 0.707107, + 0.501718, -5.72887e-009, 0.865031, + 0.260275, -7.99311e-010, 0.965535, + 0, 0, 1, + -0.244192, -0.346066, 0.905874, + -0.470609, -0.346647, 0.811396, + -0.663205, -0.346869, 0.663205, + -0.811395, -0.346647, 0.47061, + -0.905874, -0.346066, 0.244193, + -0.938373, -0.345625, -3.10672e-010, + -0.211045, -0.585247, 0.782908, + -0.406555, -0.58598, 0.700957, + -0.572843, -0.586261, 0.572843, + -0.700957, -0.58598, 0.406555, + -0.782908, -0.585247, 0.211045, + -0.811257, -0.584689, -4.41262e-009, + -0.181563, -0.716506, 0.673539, + -0.349647, -0.717169, 0.602839, + -0.492597, -0.717423, 0.492597, + -0.602839, -0.717169, 0.349647, + -0.673539, -0.716506, 0.181563, + -0.6981, -0.716, -1.94916e-008, + -0.165491, -0.771826, 0.61392, + -0.318648, -0.772419, 0.549393, + -0.448897, -0.772647, 0.448897, + -0.549392, -0.772419, 0.318648, + -0.61392, -0.771826, 0.165492, + -0.636383, -0.771373, -5.3452e-008, + -0.175561, -0.738254, 0.651275, + -0.338069, -0.738893, 0.582878, + -0.476275, -0.739138, 0.476275, + -0.582878, -0.738893, 0.338069, + -0.651275, -0.738254, 0.175561, + -0.675056, -0.737767, -1.05865e-007, + -0.260274, -7.99309e-010, 0.965535, + -0.501718, -5.72886e-009, 0.865031, + -0.707107, -1.5805e-008, 0.707107, + -0.865031, -2.65819e-008, 0.501718, + -0.965535, -2.69333e-008, 0.260275, + -1, 0, 0, + -0.905874, -0.346066, -0.244192, + -0.811396, -0.346647, -0.470609, + -0.663205, -0.346869, -0.663205, + -0.47061, -0.346647, -0.811395, + -0.244192, -0.346066, -0.905874, + 0, -0.345625, -0.938373, + -0.782908, -0.585247, -0.211045, + -0.700957, -0.58598, -0.406555, + -0.572843, -0.586261, -0.572843, + -0.406555, -0.58598, -0.700957, + -0.211045, -0.585247, -0.782908, + 0, -0.584689, -0.811257, + -0.673539, -0.716506, -0.181563, + -0.602839, -0.717169, -0.349647, + -0.492597, -0.717423, -0.492597, + -0.349647, -0.717169, -0.602839, + -0.181563, -0.716506, -0.673539, + 0, -0.716, -0.6981, + -0.61392, -0.771826, -0.165491, + -0.549392, -0.77242, -0.318647, + -0.448897, -0.772647, -0.448897, + -0.318648, -0.77242, -0.549392, + -0.165492, -0.771826, -0.61392, + 0, -0.771373, -0.636383, + -0.651275, -0.738254, -0.175561, + -0.582877, -0.738894, -0.338069, + -0.476274, -0.739138, -0.476274, + -0.338069, -0.738894, -0.582877, + -0.175561, -0.738255, -0.651275, + 0, -0.737767, -0.675055, + -0.965535, 2.69333e-008, -0.260274, + -0.865031, 2.6582e-008, -0.501718, + -0.707107, 1.58051e-008, -0.707107, + -0.501718, 5.7289e-009, -0.865031, + -0.260275, 7.99315e-010, -0.965535, + 0, 0 , -1, + 0.244192, -0.346066, -0.905874, + 0.470609, -0.346647, -0.811396, + 0.663205, -0.346869, -0.663205, + 0.811395, -0.346647, -0.47061, + 0.905874, -0.346066, -0.244192, + 0.211045, -0.585247, -0.782908, + 0.406555, -0.58598, -0.700957, + 0.572843, -0.586261, -0.572843, + 0.700957, -0.58598, -0.406555, + 0.782908, -0.585247, -0.211045, + 0.181563, -0.716506, -0.673539, + 0.349647, -0.717169, -0.602839, + 0.492597, -0.717423, -0.492597, + 0.602839, -0.717169, -0.349647, + 0.673539, -0.716506, -0.181563, + 0.165491, -0.771826, -0.61392, + 0.318647, -0.77242, -0.549392, + 0.448897, -0.772647, -0.448897, + 0.549392, -0.77242, -0.318648, + 0.61392, -0.771826, -0.165492, + 0.175561, -0.738255, -0.651275, + 0.338069, -0.738894, -0.582877, + 0.476274, -0.739138, -0.476274, + 0.582877, -0.738894, -0.338069, + 0.651275, -0.738254, -0.175561, + 0.260274, 7.99314e-010, -0.965535, + 0.501718, 5.72889e-009, -0.865031, + 0.707107, 1.58051e-008, -0.707107, + 0.865031, 2.6582e-008, -0.501718, + 0.965535, 2.69333e-008, -0.260275, + 0.0104645, -0.999945, 0, + 0 , -1, 0, + 0.0104255, -0.954681, 0.297447, + 2.56825e-008, -0.95448, 0.298276, + 0.00846391, -0.708083, 0.706078, + 1.14879e-007, -0.707106, 0.707108, + -2.9238e-009, -8.98486e-008, 1, + 8.16344e-015, -8.94074e-008, 1, + -0.00997561, 0.707961, 0.706181, + 5.80084e-008, 0.707107, 0.707107, + -0.0140841, 0.95459, 0.297589, + 1.94189e-007, 0.95448, 0.298275, + -0.0149982, 0.999888, 0, + 0, 1, 0, + 0.0510697, -0.998695, 0, + 0.0510028, -0.953615, 0.296676, + 0.0415993, -0.706917, 0.706072, + -2.78701e-009, -9.11701e-008, 1, + -0.0493858, 0.704244, 0.708239, + -0.0701018, 0.951466, 0.299663, + -0.07479, 0.997199, 0, + 0.14834, -0.988936, 0, + 0.148104, -0.941964, 0.30128, + 0.119688, -0.688399, 0.715389, + 7.13598e-009, -8.17051e-008, 1, + -0.141352, 0.675015, 0.724137, + -0.204668, 0.927128, 0.313917, + -0.219512, 0.97561, 0, + 0.364399, -0.931243, 0, + 0.359682, -0.875088, 0.323804, + 0.275915, -0.604128, 0.747597, + 1.54202e-008, -6.37972e-008, 1, + -0.313659, 0.564289, 0.763672, + -0.474611, 0.807244, 0.350859, + -0.514496, 0.857493, 0, + 0.767382, -0.64119, 0, + 0.727532, -0.577566, 0.37029, + 0.497151, -0.35353, 0.792374, + 1.10972e-008, -5.53164e-008, 1, + -0.519904, 0.300684, 0.799556, + -0.810111, 0.441475, 0.385771, + -0.882353, 0.470588, 0, + 1, 0, 0, + 0.923077, -3.76483e-008, 0.384616, + 0.599999, -4.20741e-008, 0.8, + 0, -4.47037e-008, 1, + -0.600001, -5.17421e-008, 0.799999, + -0.923077, -4.14964e-008, 0.384614, + -1, 0, 0, + -0.014084, 0.95459, -0.297589, + 5.67983e-008, 0.95448, -0.298275, + -0.00997558, 0.707961, -0.706182, + -4.84905e-008, 0.707107, -0.707107, + 5.84773e-010, 8.94956e-008 , -1, + -8.16344e-015, 8.94074e-008 , -1, + 0.0084637, -0.708085, -0.706076, + 3.66172e-008, -0.707108, -0.707106, + 0.0104256, -0.954682, -0.297445, + 7.36826e-009, -0.95448, -0.298274, + 0.0104646, -0.999945, 0, + -0.07479, 0.997199, 0, + -0.0701018, 0.951466, -0.299663, + -0.0493858, 0.704243, -0.708239, + -8.36107e-009, 8.41192e-008 , -1, + 0.0415994, -0.706919, -0.70607, + 0.0510028, -0.953616, -0.296674, + 0.0510696, -0.998695, 0, + -0.204668, 0.927128, -0.313917, + -0.141352, 0.675015, -0.724137, + -7.13598e-009, 8.17051e-008 , -1, + 0.119688, -0.688401, -0.715387, + 0.148104, -0.941964, -0.301278, + -0.514495, 0.857493, 0, + -0.47461, 0.807244, -0.350859, + -0.313658, 0.564289, -0.763673, + -9.25216e-009, 7.40412e-008 , -1, + 0.275916, -0.60413, -0.747595, + 0.359681, -0.875089, -0.323802, + 0.364399, -0.931243, 0, + -0.882353, 0.470589, 0, + -0.810111, 0.441477, -0.385771, + -0.519903, 0.300684, -0.799556, + -1.01322e-008, 5.82809e-008 , -1, + 0.497153, -0.353532, -0.792373, + 0.727532, -0.577567, -0.370288, + 0.767381, -0.641191, 0, + -0.923077, 4.14963e-008, -0.384615, + -0.6, 5.17421e-008, -0.8, + 0, 4.47037e-008 , -1, + 0.600002, 4.2074e-008, -0.799999, + 0.923078, 3.76482e-008, -0.384614, + 0.972045, 0.234794, 0, + 0.895972, 0.219226, 0.38623, + 0.57987, 0.145888, 0.801541, + -1.56774e-008, -4.06593e-008, 1, + -0.577708, -0.153129, 0.801751, + -0.890548, -0.23959, 0.386678, + -0.965311, -0.261102, 0, + 0.913811, 0.406139, 0, + 0.842942, 0.38439, 0.376421, + 0.548194, 0.264706, 0.793356, + -1.8594e-008, -5.87553e-008, 1, + -0.534196, -0.289235, 0.794341, + -0.807437, -0.452559, 0.378465, + -0.869653, -0.493664, 0, + 0.83205, 0.5547, 0, + 0.772293, 0.530527, 0.349435, + 0.515845, 0.379263, 0.768156, + -2.48164e-008, -6.43889e-008, 1, + -0.486434, -0.411777, 0.770598, + -0.700515, -0.619694, 0.353919, + -0.743581, -0.668646, 0, + 0.722373, 0.691503, 0, + 0.676612, 0.666255, 0.31353, + 0.471519, 0.495195, 0.729693, + -2.71577e-008, -7.53755e-008, 1, + -0.433172, -0.52092, 0.73553, + -0.589822, -0.740319, 0.322549, + -0.617031, -0.786939, 0, + 0.580972, 0.813923, 0, + 0.548733, 0.784249, 0.289562, + 0.396971, 0.593617, 0.700024, + -2.572e-008, -8.77449e-008, 1, + -0.367048, -0.602921, 0.708352, + -0.485318, -0.820874, 0.301051, + -0.504835, -0.863216, 0, + 0.390503, 0.867784, 0.307341, + 0.285351, 0.634113, 0.718663, + -2.36665e-008, -9.72958e-008, 1, + -0.285351, -0.634114, 0.718661, + -0.390503, -0.867784, 0.30734, + -0.410365, -0.911921, 0, + -0.890548, -0.23959, -0.386679, + -0.577707, -0.153129, -0.801752, + 1.08654e-008, 5.5622e-008 , -1, + 0.579872, 0.145888, -0.801539, + 0.895973, 0.219227, -0.386228, + -0.807437, -0.452558, -0.378466, + -0.534196, -0.289235, -0.794341, + 2.27516e-008, 5.19016e-008 , -1, + 0.548196, 0.264707, -0.793355, + 0.842943, 0.384391, -0.376419, + -0.700515, -0.619694, -0.353919, + -0.486433, -0.411777, -0.770599, + 2.48164e-008, 6.43889e-008 , -1, + 0.515847, 0.379264, -0.768154, + 0.772293, 0.530528, -0.349433, + -0.589822, -0.740319, -0.322549, + -0.433171, -0.520919, -0.735531, + 2.71577e-008, 7.53755e-008 , -1, + 0.47152, 0.495196, -0.729691, + 0.676612, 0.666255, -0.313529, + -0.485318, -0.820874, -0.301052, + -0.367047, -0.60292, -0.708353, + 2.88747e-008, 8.75411e-008 , -1, + 0.396972, 0.593619, -0.700022, + 0.548733, 0.784249, -0.289561, + -0.390503, -0.867784, -0.30734, + -0.285351, -0.634113, -0.718662, + 2.36665e-008, 9.72958e-008 , -1, + 0.285351, 0.634114, -0.718661, + 0.390503, 0.867785, -0.307339, + -0.333935, 0.942596, 0, + 0, 1, 0, + -0.291732, 0.855995, 0.426808, + -0.0157731, 0.886804, 0.461877, + -0.135103, 0.53438, 0.834377, + -0.0291362, 0.514277, 0.857129, + 0.110195, 0.0292375, 0.99348, + 4.3732e-009, -8.94073e-008, 1, + 0.348602, -0.464039, 0.814337, + 0.0673463, -0.513328, 0.855546, + 0.492146, -0.767551, 0.410679, + 0.134339, -0.878875, 0.457746, + 0.528678, -0.848822, 0, + 0.158678, -0.98733, 0, + -0.731055, 0.682318, 0, + -0.64585, 0.656206, 0.390219, + -0.31251, 0.484842, 0.816864, + 0.215359, 0.108813, 0.970454, + 0.627608, -0.260237, 0.733747, + 0.813963, -0.465103, 0.348055, + 0.854063, -0.52017, 0, + -0.920582, 0.39055, 0, + -0.835236, 0.412221, 0.363943, + -0.451322, 0.38916, 0.803034, + 0.214084, 0.180281, 0.960035, + 0.705425, -0.0805069, 0.704198, + 0.913262, -0.239978, 0.329185, + 0.957826, -0.287348, 0, + -0.948683, 0.316228, 0, + -0.842821, 0.34961, 0.409177, + -0.452672, 0.347535, 0.821162, + 0.113546, 0.191909, 0.974822, + 0.60461, -0.0547987, 0.794634, + 0.880145, -0.253261, 0.401503, + 0.947589, -0.319493, 0, + -0.874591, 0.484861, 0, + -0.723794, 0.476715, 0.498864, + -0.365377, 0.375544, 0.851743, + 0.0260102, 0.151516, 0.988113, + 0.417243, -0.185123, 0.88974, + 0.70819, -0.506054, 0.492318, + 0.787582, -0.61621, 0, + -0.600001, 0.799999, 0, + -0.497164, 0.711095, 0.497165, + -0.267367, 0.443286, 0.855577, + 0, -4.47006e-008, 1, + 0.250514, -0.54278, 0.801644, + 0.366221, -0.855433, 0.36622, + 0.384615, -0.923077, 0, + 0.528678, -0.848822, 0, + 0.492146, -0.767551, -0.41068, + 0.134339, -0.878875, -0.457747, + 0.348602, -0.464038, -0.814337, + 0.0673462, -0.513327, -0.855546, + 0.110195, 0.0292377, -0.99348, + -4.3732e-009, 8.94073e-008 , -1, + -0.135104, 0.534382, -0.834376, + -0.0291362, 0.514278, -0.857128, + -0.291732, 0.855996, -0.426806, + -0.0157731, 0.886804, -0.461876, + -0.333935, 0.942596, 0, + 0.854063, -0.52017, 0, + 0.813963, -0.465103, -0.348056, + 0.627607, -0.260237, -0.733748, + 0.215359, 0.108813, -0.970454, + -0.312512, 0.484843, -0.816862, + -0.645851, 0.656206, -0.390218, + 0.913262, -0.239977, -0.329185, + 0.705424, -0.0805064, -0.704199, + 0.214084, 0.180281, -0.960035, + -0.451324, 0.38916, -0.803032, + -0.835237, 0.412221, -0.363941, + 0.947589, -0.319493, 0, + 0.880144, -0.253261, -0.401503, + 0.60461, -0.0547981, -0.794635, + 0.113546, 0.191909, -0.974822, + -0.452675, 0.347535, -0.821161, + -0.842822, 0.34961, -0.409175, + -0.948683, 0.316228, 0, + 0.787582, -0.61621, 0, + 0.70819, -0.506053, -0.492318, + 0.417243, -0.185122, -0.88974, + 0.0260103, 0.151516, -0.988113, + -0.365379, 0.375545, -0.851742, + -0.723796, 0.476715, -0.498861, + -0.874591, 0.484861, 0, + 0.36622, -0.855433, -0.36622, + 0.250514, -0.54278, -0.801644, + 0, 4.47006e-008 , -1, + -0.267368, 0.443289, -0.855575, + -0.497165, 0.711096, -0.497162, + -0.467888, 0.883788, 0, + -0.387053, 0.824948, 0.411887, + -0.215548, 0.655025, 0.72421, + -0.00489616, 0.343259, 0.939228, + 0.269127, -0.23781, 0.933283, + 0.442187, -0.761825, 0.473385, + 0.463425, -0.886136, 0, + -0.306008, 0.952029, 0, + -0.253998, 0.928137, 0.272115, + -0.14959, 0.863647, 0.481391, + -0.0195232, 0.746219, 0.665414, + 0.218115, 0.441118, 0.870541, + 0.612385, -0.337374, 0.714957, + 0.694135, -0.719844, 0, + 0, 1, 0, + -0.0182315, 0.999613, -0.0210205, + -0.0369304, 0.999286, 0.00796664, + -0.0348909, 0.997622, 0.059444, + -0.00787177, 0.994104, 0.108145, + 0.0539575, 0.992309, 0.111405, + 0.106533, 0.994309, 0, + 0.913813, 0.406135, 0, + 0.507716, 0.52532, -0.682835, + 0.148478, 0.676273, -0.721533, + -0.0300304, 0.787464, -0.615629, + -0.144372, 0.876436, -0.459366, + -0.223743, 0.943891, -0.242919, + -0.253109, 0.967438, 0, + 0.789351, -0.613942, 0, + 0.577415, -0.400033, -0.711734, + 0.241288, -0.0136421, -0.970358, + -0.0103803, 0.344669, -0.938667, + -0.199105, 0.663018, -0.72164, + -0.316295, 0.875642, -0.364979, + -0.349987, 0.936755, 0, + 0.6, -0.8, 0, + 0.483629, -0.690899, -0.537366, + 0.247465, -0.40568, -0.879878, + 0, 4.47028e-008 , -1, + -0.236617, 0.486025, -0.841304, + -0.378646, 0.824393, -0.420717, + -0.410365, 0.911921, 0, + 0.442188, -0.761824, -0.473386, + 0.269127, -0.237807, -0.933284, + -0.0048962, 0.343262, -0.939227, + -0.215548, 0.655028, -0.724208, + -0.387053, 0.82495, -0.411884, + 0.612385, -0.337369, -0.714959, + 0.218114, 0.441124, -0.870538, + -0.0195232, 0.746221, -0.665412, + -0.14959, 0.863648, -0.481389, + -0.253997, 0.928138, -0.272112, + 0.0539562, 0.992309, -0.111404, + -0.00787199, 0.994104, -0.108144, + -0.0348909, 0.997622, -0.0594425, + -0.0369306, 0.999286, -0.00796709, + -0.0182318, 0.999613, 0.0210199, + -0.223743, 0.943891, 0.242919, + -0.144372, 0.876437, 0.459364, + -0.0300305, 0.787466, 0.615626, + 0.148478, 0.676276, 0.721529, + 0.507717, 0.525323, 0.682832, + -0.316294, 0.875642, 0.364979, + -0.199104, 0.663019, 0.72164, + -0.0103804, 0.344672, 0.938666, + 0.241289, -0.0136406, 0.970357, + 0.577417, -0.400034, 0.711732, + -0.378646, 0.824393, 0.420718, + -0.236617, 0.486023, 0.841305, + 0, -4.47028e-008, 1, + 0.247466, -0.405682, 0.879877, + 0.48363, -0.690899, 0.537365, + 0.249998, 0.968246, 0, + 0.001257, 0.999999, 0, + 0.241077, 0.968356, 0.0645611, + 0.00120899, 0.999999, 0.000335259, + 0.215548, 0.968509, 0.124615, + 0.00108352, 0.999999, 0.000626407, + 0.175886, 0.96857, 0.175886, + 0.124616, 0.968509, 0.215548, + 0.0645611, 0.968356, 0.241077, + 0, 0.968246, 0.249998, + 0.989204, 0.146548, 0, + 0.955495, 0.146755, 0.255913, + 0.856312, 0.147029, 0.495088, + 0.699411, 0.147135, 0.699411, + 0.495089, 0.147029, 0.856312, + 0.255914, 0.146754, 0.955495, + 0, 0.146548, 0.989204, + 0.780869, -0.624695, 0, + 0.753687, -0.625441, 0.201937, + 0.674735, -0.626493, 0.390178, + 0.550895, -0.62692, 0.550896, + 0.390179, -0.626493, 0.674734, + 0.201938, -0.625441, 0.753688, + 0, -0.624695, 0.780869, + 0.747409, -0.664364, 0, + 0.721243, -0.665116, 0.193465, + 0.645526, -0.66618, 0.373497, + 0.527081, -0.666611, 0.527081, + 0.373498, -0.66618, 0.645526, + 0.193466, -0.665116, 0.721243, + 0, -0.664364, 0.747409, + 0.950775, -0.309882, 0, + 0.917897, -0.310647, 0.246906, + 0.822132, -0.311772, 0.476337, + 0.671753, -0.312241, 0.671754, + 0.476338, -0.311771, 0.822132, + 0.246907, -0.310647, 0.917897, + 0, -0.309882, 0.950775, + 0.6, 0.8, 0, + 0.578783, 0.800417, 0.15602, + 0.517905, 0.800964, 0.300385, + 0.423156, 0.801173, 0.423156, + 0.300386, 0.800964, 0.517904, + 0.156021, 0.800416, 0.578784, + 0, 0.799999, 0.600001, + 0, 0.968246, 0.249998, + -0.064561, 0.968356, 0.241077, + -0.124615, 0.968509, 0.215548, + -0.175885, 0.968571, 0.175885, + -0.215548, 0.968509, 0.124616, + -0.241076, 0.968356, 0.064561, + -0.249998, 0.968246, 0, + 0, 0.146549, 0.989203, + -0.255913, 0.146755, 0.955495, + -0.495088, 0.14703, 0.856312, + -0.699411, 0.147136, 0.699411, + -0.856311, 0.14703, 0.495089, + -0.955495, 0.146755, 0.255914, + -0.989203, 0.146549, 0, + -0.201937, -0.625441, 0.753688, + -0.390178, -0.626493, 0.674735, + -0.550895, -0.62692, 0.550896, + -0.674734, -0.626493, 0.390179, + -0.753687, -0.625441, 0.201939, + -0.780869, -0.624695, 0, + 0, -0.664364, 0.747409, + -0.193465, -0.665116, 0.721244, + -0.373497, -0.66618, 0.645527, + -0.527081, -0.666611, 0.527081, + -0.645526, -0.66618, 0.373498, + -0.721243, -0.665116, 0.193466, + -0.747409, -0.664364, 0, + 0, -0.309883, 0.950775, + -0.246906, -0.310648, 0.917897, + -0.476336, -0.311773, 0.822132, + -0.671753, -0.312242, 0.671753, + -0.822131, -0.311773, 0.476338, + -0.917897, -0.310648, 0.246907, + -0.950775, -0.309883, 0, + -0.15602, 0.800417, 0.578784, + -0.300385, 0.800964, 0.517905, + -0.423156, 0.801173, 0.423156, + -0.517904, 0.800964, 0.300386, + -0.578783, 0.800417, 0.15602, + -0.6, 0.8, 0, + -0.249998, 0.968246, 0, + -0.241077, 0.968356, -0.064561, + -0.215548, 0.968509, -0.124615, + -0.175885, 0.968571, -0.175885, + -0.124616, 0.968509, -0.215548, + -0.064561, 0.968356, -0.241077, + 0, 0.968246, -0.249998, + -0.989204, 0.146547, 0, + -0.955496, 0.146753, -0.255912, + -0.856312, 0.147028, -0.495088, + -0.699411, 0.147134, -0.699411, + -0.495089, 0.147028, -0.856312, + -0.255914, 0.146753, -0.955495, + 0, 0.146547, -0.989204, + -0.753688, -0.625441, -0.201937, + -0.674735, -0.626494, -0.390178, + -0.550896, -0.62692, -0.550895, + -0.390179, -0.626494, -0.674734, + -0.201938, -0.625441, -0.753687, + 0, -0.624695, -0.780869, + -0.747409, -0.664364, 0, + -0.721244, -0.665116, -0.193465, + -0.645526, -0.66618, -0.373497, + -0.527081, -0.666612, -0.527081, + -0.373498, -0.66618, -0.645526, + -0.193466, -0.665116, -0.721243, + 0, -0.664364, -0.747409, + -0.950776, -0.30988, 0, + -0.917898, -0.310645, -0.246906, + -0.822133, -0.31177, -0.476337, + -0.671754, -0.312239, -0.671754, + -0.476338, -0.31177, -0.822132, + -0.246907, -0.310646, -0.917898, + 0, -0.309881, -0.950775, + -0.578783, 0.800417, -0.15602, + -0.517905, 0.800964, -0.300384, + -0.423155, 0.801174, -0.423155, + -0.300386, 0.800964, -0.517904, + -0.15602, 0.800417, -0.578783, + 0, 0.8, -0.6, + 0.064561, 0.968356, -0.241077, + 0.124615, 0.968509, -0.215548, + 0.175885, 0.968571, -0.175885, + 0.215549, 0.968509, -0.124616, + 0.241077, 0.968356, -0.064561, + 0.249998, 0.968246, 0, + 0.255913, 0.146754, -0.955496, + 0.495088, 0.147028, -0.856312, + 0.699411, 0.147134, -0.699411, + 0.856312, 0.147028, -0.495089, + 0.955495, 0.146753, -0.255914, + 0.989204, 0.146547, 0, + 0.201937, -0.625441, -0.753687, + 0.390178, -0.626494, -0.674735, + 0.550896, -0.62692, -0.550895, + 0.674734, -0.626494, -0.390179, + 0.753687, -0.625441, -0.201938, + 0.193465, -0.665116, -0.721243, + 0.373497, -0.66618, -0.645526, + 0.527081, -0.666612, -0.527081, + 0.645526, -0.66618, -0.373498, + 0.721244, -0.665116, -0.193466, + 0.747409, -0.664364, 0, + 0.246906, -0.310646, -0.917898, + 0.476337, -0.31177, -0.822133, + 0.671754, -0.312239, -0.671754, + 0.822133, -0.31177, -0.476338, + 0.917898, -0.310646, -0.246907, + 0.950776, -0.30988, 0, + 0.15602, 0.800417, -0.578783, + 0.300384, 0.800964, -0.517905, + 0.423155, 0.801174, -0.423155, + 0.517904, 0.800964, -0.300386, + 0.578783, 0.800417, -0.15602, + 0.268354, 0.96332, 0, + 0.258757, 0.963421, 0.0697519, + 0.231413, 0.963552, 0.134219, + 0.189037, 0.963603, 0.189037, + 0.13422, 0.963552, 0.231413, + 0.0697519, 0.963421, 0.258756, + 0, 0.96332, 0.268354, + 0.168031, 0.985782, 0, + 0.162012, 0.985822, 0.0436728, + 0.144879, 0.985875, 0.0840299, + 0.118345, 0.985895, 0.118345, + 0.0840302, 0.985875, 0.144879, + 0.0436728, 0.985822, 0.162011, + 0, 0.985782, 0.168031, + 0.14834, 0.988936, 0, + 0.143025, 0.988968, 0.0385546, + 0.127899, 0.989009, 0.0741814, + 0.104474, 0.989025, 0.104474, + 0.0741816, 0.989009, 0.127899, + 0.0385547, 0.988968, 0.143025, + 0, 0.988936, 0.148341, + 0.193633, 0.981074, 0, + 0.186698, 0.981127, 0.0503274, + 0.166959, 0.981197, 0.0968359, + 0.136382, 0.981224, 0.136382, + 0.0968361, 0.981197, 0.166958, + 0.0503276, 0.981127, 0.186699, + 0, 0.981074, 0.193633, + 0.390291, 0.920691, 0, + 0.376377, 0.920895, 0.101458, + 0.336655, 0.921161, 0.19526, + 0.275023, 0.921262, 0.275023, + 0.19526, 0.921161, 0.336655, + 0.101459, 0.920894, 0.376377, + 0, 0.920691, 0.390291, + 1, 0, 0, + 0.965535, -2.6932e-008, 0.260274, + 0.865031, -2.65808e-008, 0.501718, + 0.707107, -1.58043e-008, 0.707107, + 0.501719, -5.72865e-009, 0.865031, + 0.260276, -7.99283e-010, 0.965534, + 0, 0, 1, + -0.0697519, 0.963421, 0.258757, + -0.134219, 0.963552, 0.231413, + -0.189037, 0.963603, 0.189037, + -0.231413, 0.963552, 0.13422, + -0.258756, 0.963421, 0.0697519, + -0.268354, 0.96332, 0, + -0.0436727, 0.985822, 0.162012, + -0.0840298, 0.985875, 0.144879, + -0.118345, 0.985895, 0.118345, + -0.144879, 0.985875, 0.0840302, + -0.162011, 0.985822, 0.0436728, + -0.168031, 0.985782, 0, + -0.0385546, 0.988968, 0.143025, + -0.0741813, 0.989009, 0.127899, + -0.104474, 0.989025, 0.104474, + -0.127899, 0.989009, 0.0741816, + -0.143025, 0.988968, 0.0385547, + -0.14834, 0.988936, 0, + -0.0503274, 0.981127, 0.186698, + -0.0968359, 0.981197, 0.166959, + -0.136382, 0.981224, 0.136382, + -0.166958, 0.981197, 0.0968361, + -0.186699, 0.981127, 0.0503276, + -0.193633, 0.981074, 0, + -0.101458, 0.920895, 0.376377, + -0.19526, 0.921161, 0.336655, + -0.275023, 0.921262, 0.275023, + -0.336655, 0.921161, 0.19526, + -0.376377, 0.920894, 0.101459, + -0.390291, 0.920691, 0, + -0.260274, -7.99271e-010, 0.965535, + -0.501718, -5.72859e-009, 0.865031, + -0.707107, -1.58043e-008, 0.707107, + -0.865031, -2.65808e-008, 0.501719, + -0.965534, -2.69321e-008, 0.260276, + -1, 0, 0, + -0.258757, 0.963421, -0.0697518, + -0.231413, 0.963552, -0.134219, + -0.189037, 0.963603, -0.189037, + -0.13422, 0.963552, -0.231413, + -0.0697518, 0.963421, -0.258756, + 0, 0.96332, -0.268354, + -0.162012, 0.985822, -0.0436727, + -0.144879, 0.985875, -0.0840298, + -0.118345, 0.985895, -0.118345, + -0.0840302, 0.985875, -0.144879, + -0.0436727, 0.985822, -0.162011, + 0, 0.985782, -0.168031, + -0.143025, 0.988968, -0.0385546, + -0.127899, 0.989009, -0.0741813, + -0.104474, 0.989025, -0.104474, + -0.0741816, 0.989009, -0.127899, + -0.0385547, 0.988968, -0.143025, + 0, 0.988936, -0.14834, + -0.186698, 0.981127, -0.0503273, + -0.166959, 0.981197, -0.0968358, + -0.136382, 0.981224, -0.136382, + -0.0968361, 0.981197, -0.166958, + -0.0503276, 0.981127, -0.186699, + 0, 0.981074, -0.193633, + -0.376377, 0.920895, -0.101458, + -0.336655, 0.921161, -0.19526, + -0.275023, 0.921262, -0.275023, + -0.19526, 0.921161, -0.336655, + -0.101459, 0.920894, -0.376377, + 0, 0.920691, -0.390291, + -0.965535, 2.6932e-008, -0.260274, + -0.865031, 2.65807e-008, -0.501718, + -0.707107, 1.58043e-008, -0.707107, + -0.501719, 5.72864e-009, -0.865031, + -0.260276, 7.99283e-010, -0.965534, + 0, 0 , -1, + 0.0697518, 0.963421, -0.258757, + 0.134219, 0.963552, -0.231413, + 0.189037, 0.963603, -0.189037, + 0.231413, 0.963552, -0.13422, + 0.258756, 0.963421, -0.0697518, + 0.0436727, 0.985822, -0.162012, + 0.0840298, 0.985875, -0.144879, + 0.118345, 0.985895, -0.118345, + 0.144879, 0.985875, -0.0840302, + 0.162011, 0.985822, -0.0436727, + 0.0385546, 0.988968, -0.143025, + 0.0741813, 0.989009, -0.127899, + 0.104474, 0.989025, -0.104474, + 0.127899, 0.989009, -0.0741816, + 0.143025, 0.988968, -0.0385547, + 0.0503274, 0.981127, -0.186698, + 0.0968359, 0.981197, -0.166959, + 0.136382, 0.981224, -0.136382, + 0.166958, 0.981197, -0.0968361, + 0.186699, 0.981127, -0.0503276, + 0.101458, 0.920895, -0.376377, + 0.19526, 0.921161, -0.336655, + 0.275023, 0.921262, -0.275023, + 0.336655, 0.921161, -0.19526, + 0.376377, 0.920894, -0.101459, + 0.260274, 7.99271e-010, -0.965535, + 0.501718, 5.72859e-009, -0.865031, + 0.707107, 1.58043e-008, -0.707107, + 0.865031, 2.65807e-008, -0.501719, + 0.965534, 2.6932e-008, -0.260276, + 0.0226746, -0.999743, -1.91575e-007, + 0.00017586 , -1, -1.78936e-007, + 0.0218614, -0.999744, -0.00589325, + 0.0195486, -0.999745, -0.0113383, + 0.0159681, -0.999745, -0.0159682, + 0.0113382, -0.999745, -0.0195487, + 0.0058931, -0.999744, -0.0218616, + 0, -0.999743, -0.0226747, + 0.0623783, -0.998053, -2.05165e-007, + 0.0601415, -0.998058, -0.0162122, + 0.0537792, -0.998066, -0.0311921, + 0.0439291, -0.998068, -0.0439292, + 0.031192, -0.998066, -0.0537793, + 0.0162121, -0.998058, -0.0601416, + 0, -0.998053, -0.0623784, + 0.141421, -0.98995, -2.16354e-007, + 0.136353, -0.989978, -0.0367563, + 0.121933, -0.990016, -0.0707209, + 0.0996006, -0.99003, -0.0996008, + 0.070721, -0.990016, -0.121933, + 0.0367563, -0.989978, -0.136353, + 0, -0.98995, -0.141421, + 0.328521, -0.944497, -2.21665e-007, + 0.316788, -0.944644, -0.0853952, + 0.283332, -0.944838, -0.164332, + 0.231454, -0.944912, -0.231454, + 0.164333, -0.944838, -0.283331, + 0.0853954, -0.944644, -0.316788, + 0, -0.944497, -0.328521, + 0.770022, -0.638017, -1.57624e-007, + 0.743044, -0.638566, -0.200299, + 0.665183, -0.639286, -0.385806, + 0.543581, -0.639561, -0.543581, + 0.385806, -0.639286, -0.665182, + 0.2003, -0.638566, -0.743044, + 0, -0.638017, -0.770022, + 0.965535, 2.69333e-008, -0.260274, + 0.865031, 2.6582e-008, -0.501718, + 0.501719, 5.7289e-009, -0.865031, + 0.260276, 7.9932e-010, -0.965534, + 0, -0.999743, -0.0226747, + -0.00589307, -0.999744, -0.0218616, + -0.0113382, -0.999745, -0.0195487, + -0.015968, -0.999745, -0.0159682, + -0.0195486, -0.999745, -0.0113384, + -0.0218614, -0.999744, -0.00589328, + -0.0226746, -0.999743, -1.91575e-007, + 0, -0.998053, -0.0623784, + -0.016212, -0.998058, -0.0601416, + -0.0311919, -0.998066, -0.0537794, + -0.0439291, -0.998068, -0.0439292, + -0.0537792, -0.998066, -0.0311922, + -0.0601415, -0.998058, -0.0162123, + -0.0623783, -0.998053, -2.05165e-007, + -0.0367561, -0.989978, -0.136353, + -0.0707208, -0.990016, -0.121933, + -0.0996006, -0.99003, -0.0996008, + -0.121932, -0.990016, -0.0707211, + -0.136353, -0.989978, -0.0367565, + -0.141421, -0.98995, -2.16354e-007, + 0, -0.944497, -0.32852, + -0.0853949, -0.944644, -0.316788, + -0.164332, -0.944838, -0.283331, + -0.231454, -0.944912, -0.231454, + -0.283331, -0.944838, -0.164333, + -0.316788, -0.944644, -0.0853956, + -0.32852, -0.944497, -2.21665e-007, + 0, -0.638018, -0.770021, + -0.200298, -0.638567, -0.743043, + -0.385805, -0.639287, -0.665182, + -0.543581, -0.639562, -0.543581, + -0.665181, -0.639287, -0.385806, + -0.743043, -0.638567, -0.2003, + -0.770021, -0.638018, -1.57625e-007, + -0.260274, 7.99307e-010, -0.965535, + -0.501718, 5.72886e-009, -0.865031, + -0.865031, 2.65819e-008, -0.501719, + -0.965534, 2.69333e-008, -0.260276, + -0.0226746, -0.999743, -1.91442e-007, + -0.0218614, -0.999744, 0.00589289, + -0.0195486, -0.999745, 0.011338, + -0.0159681, -0.999745, 0.0159679, + -0.0113382, -0.999745, 0.0195484, + -0.0058931, -0.999744, 0.0218612, + 0, -0.999743, 0.0226744, + -0.0623783, -0.998053, -2.04538e-007, + -0.0601415, -0.998058, 0.0162119, + -0.0537793, -0.998066, 0.0311918, + -0.0439291, -0.998068, 0.0439289, + -0.031192, -0.998066, 0.0537791, + -0.0162121, -0.998058, 0.0601414, + 0, -0.998053, 0.0623782, + -0.136353, -0.989978, 0.0367559, + -0.121932, -0.990016, 0.0707206, + -0.0996006, -0.99003, 0.0996005, + -0.0707209, -0.990016, 0.121932, + -0.0367563, -0.989978, 0.136353, + 0, -0.98995, 0.141421, + -0.328521, -0.944497, -2.1827e-007, + -0.316789, -0.944644, 0.0853949, + -0.283332, -0.944838, 0.164332, + -0.231455, -0.944911, 0.231454, + -0.164333, -0.944837, 0.283332, + -0.0853956, -0.944644, 0.316789, + 0, -0.944497, 0.328521, + -0.770023, -0.638016, -1.53325e-007, + -0.743045, -0.638564, 0.200299, + -0.665184, -0.639284, 0.385806, + -0.543582, -0.63956, 0.543582, + -0.385807, -0.639284, 0.665183, + -0.2003, -0.638564, 0.743045, + 0, -0.638016, 0.770023, + -0.965535, -2.69333e-008, 0.260274, + -0.865031, -2.6582e-008, 0.501718, + -0.707107, -1.58051e-008, 0.707107, + -0.501719, -5.7289e-009, 0.865031, + -0.260276, -7.9932e-010, 0.965534, + 0.00589307, -0.999744, 0.0218612, + 0.0113382, -0.999745, 0.0195484, + 0.0159681, -0.999745, 0.0159679, + 0.0195486, -0.999745, 0.011338, + 0.0218614, -0.999744, 0.00589292, + 0.0226746, -0.999743, -1.91442e-007, + 0.016212, -0.998058, 0.0601414, + 0.0311919, -0.998066, 0.0537791, + 0.0439291, -0.998068, 0.0439289, + 0.0537792, -0.998066, 0.0311918, + 0.0601415, -0.998058, 0.016212, + 0.0623783, -0.998053, -2.04538e-007, + 0.0367561, -0.989978, 0.136353, + 0.0707208, -0.990016, 0.121932, + 0.0996006, -0.99003, 0.0996005, + 0.121932, -0.990016, 0.0707208, + 0.136353, -0.989978, 0.0367561, + 0.0853951, -0.944644, 0.316789, + 0.164332, -0.944838, 0.283332, + 0.231455, -0.944911, 0.231454, + 0.283332, -0.944837, 0.164333, + 0.316789, -0.944644, 0.0853954, + 0.328521, -0.944497, -2.1827e-007, + 0.200299, -0.638564, 0.743045, + 0.385806, -0.639284, 0.665184, + 0.543582, -0.63956, 0.543582, + 0.665183, -0.639284, 0.385807, + 0.743045, -0.638565, 0.2003, + 0.770023, -0.638016, -1.53325e-007, + 0.260274, -7.99307e-010, 0.965535, + 0.501718, -5.72886e-009, 0.865031, + 0.707107, -1.58051e-008, 0.707107, + 0.865031, -2.65819e-008, 0.501719, + 0.965534, -2.69333e-008, 0.260276, + 0.000169553 , -1, 4.55269e-005, + 0.000151615 , -1, 8.7758e-005, + 0.000123845 , -1, 0.000123666, + 8.79365e-005 , -1, 0.000151436, + 4.57054e-005 , -1, 0.000169374, + 0 , -1, 0.000175681, + -4.57057e-005 , -1, 0.000169374, + -8.79367e-005 , -1, 0.000151436, + -0.000123845 , -1, 0.000123666, + -0.000151615 , -1, 8.77577e-005, + -0.000169553 , -1, 4.55266e-005, + -0.00017586 , -1, -1.78936e-007, + -0.141421, -0.98995, -2.18023e-007, + 0 , -1, -0.000176026, + -4.57022e-005 , -1, -0.000169719, + -8.79303e-005 , -1, -0.000151783, + -0.000123836 , -1, -0.000124015, + -0.000151604 , -1, -8.81092e-005, + -0.00016954 , -1, -4.58813e-005, + -0.000175847 , -1, -1.78936e-007, + 0.141421, -0.98995, -2.18023e-007, + 0.000175847 , -1, -1.78936e-007, + 0.000169541 , -1, -4.58811e-005, + 0.000151604 , -1, -8.81091e-005, + 0.000123836 , -1, -0.000124015, + 8.79306e-005 , -1, -0.000151783, + 4.57025e-005 , -1, -0.000169719, + 0.423155, 0.801174, 0.423155, + 0.300386, 0.800964, 0.517905, + 0.15602, 0.800417, 0.578784, + 0, 0.8, 0.6, + 0.000884181, 0.999999, 0.000884182, + 0.0006461, 0.999999, 0.00107175, + 0.000305924, 0.999999, 0.00121748, + 0, 0.999999, 0.001257, + 0.00125688, 0.999999, 0, + 0.00121716, 0.999999, -0.000305839, + 0.00107193, 0.999999, -0.000646202, + 0.00088386, 0.999999, -0.00088386, + 0.000626479, 0.999999, -0.00108364, + 0.000335298, 0.999999, -0.00120914, + 0, 0.999999, -0.00125688, + -0.000305839, 0.999999, -0.00121716, + -0.000646202, 0.999999, -0.00107193, + -0.00088386, 0.999999, -0.00088386, + -0.00108364, 0.999999, -0.000626479, + -0.00120914, 0.999999, -0.000335298, + -0.00125688, 0.999999, 0, + 0.517904, 0.800965, -0.300385, + 0.300384, 0.800965, -0.517904, + 0.15602, 0.800418, -0.578782, + 0, 0.800001, -0.599999, + -0.15602, 0.800418, -0.578783, + -0.300385, 0.800965, -0.517903, + -0.517904, 0.800965, -0.300384, + -0.15602, 0.800417, 0.578783, + -0.300384, 0.800964, 0.517905, + -0.423155, 0.801174, 0.423155, + 0, 0.999999, 0.00125701, + -0.000335262, 0.999999, 0.00120901, + -0.000626413, 0.999999, 0.00108353, + -0.00088419, 0.999999, 0.00088419, + -0.00107176, 0.999999, 0.000646106, + -0.00121749, 0.999999, 0.000305927, + -0.00125701, 0.999999, 0, + 0.366221, -0.855433, -0.36622, + -0.497164, 0.711096, -0.497162, + -0.6, 0.8, 0, + -0.267367, 0.443287, 0.855577, + -0.0149983, 0.999888, 0, + -1, 0, 0, + -0.811257, -0.584689, -4.21204e-009, + 0.811257, -0.584689, -4.21204e-009, + -0.6981, -0.716, -1.86057e-008, + 0.6981, -0.716, -1.86057e-008, + -0.636383, -0.771373, -5.10224e-008, + 0.636383, -0.771373, -5.10224e-008, + -0.675056, -0.737767, -1.01053e-007, + 0.675056, -0.737767, -1.01053e-007, + 0.965535, -2.6933e-008, 0.260274, + 0.902861, 0.429933, 0, + 0.637936, 0.431366, -0.637936, + 0, 0.429933, -0.902861, + -0.637936, 0.431366, -0.637936, + -0.902861, 0.429933, 0, + 0, 0.429933, 0.902861, + -0.637936, 0.431366, 0.637936, + -0.556737, 0.830689, 0, + 0.637936, 0.431366, 0.637936, + 0, -0.156768, -0.987635, + -0.148341, 0.988936, 0, + 0.148341, 0.988936, 0}; + +short teapot_indices[] = { + 1122, 1243, 1272, 1242, 1273, 1241, 1274, 1240, + 1275, 1239, 1276, 1238, 1277, 1205, 1278, 1204, + 1279, 1203, 1280, 1202, 1281, 1201, 1282, 1200, + 1283, 1199, -1, 1243, 1249, 1242, 1248, 1241, 1247, + 1240, 1246, 1239, 1245, 1238, 1244, 1205, 1212, + 1204, 1211, 1203, 1210, 1202, 1209, 1201, 1208, + 1200, 1207, 1199, 1206, -1, 1249, 1136, 1248, 1254, + 1247, 1253, 1246, 1252, 1245, 1251, 1244, 1250, + 1212, 1218, 1211, 1217, 1210, 1216, 1209, 1215, + 1208, 1214, 1207, 1213, 1206, 1180, -1, 1136, 1260, + 1254, 1259, 1253, 1258, 1252, 1257, 1251, 1256, + 1250, 1255, 1218, 1225, 1217, 1224, 1216, 1223, + 1215, 1222, 1214, 1221, 1213, 1220, 1180, 1219, + -1, 1260, 1266, 1259, 1265, 1258, 1264, 1257, 1263, + 1256, 1262, 1255, 1261, 1225, 1232, 1224, 1231, + 1223, 1230, 1222, 1229, 1221, 1228, 1220, 1227, + 1219, 1226, -1, 1266, 384, 1265, 1271, 1264, 1270, + 1263, 1269, 1262, 1268, 1261, 1267, 1232, 390, + 1231, 1237, 1230, 1236, 1229, 1235, 1228, 1234, + 1227, 1233, 1226, 426, -1, 462, 1188, 1195, 1189, + 1196, 1190, 459, 1191, 1197, 1192, 1198, 1193, + 426, 1194, -1, 1188, 1181, 1189, 1182, 1190, 1183, + 1191, 1184, 1192, 1185, 1193, 1186, 1194, 1187, + -1, 1181, 1142, 1182, 1175, 1183, 1176, 1184, 1177, + 1185, 1178, 1186, 1179, 1187, 1284, -1, 1142, 1168, + 1175, 1169, 1176, 1170, 1177, 1171, 1178, 1172, + 1179, 1173, 1284, 1174, -1, 1168, 1161, 1169, 1162, + 1170, 1163, 1171, 1164, 1172, 1165, 1173, 1166, + 1174, 1167, -1, 1161, 1285, 1162, 1286, 1163, 1287, + 1164, 1288, 1165, 1289, 1166, 1290, 1167, 1291, + -1, 384, 1150, 1157, 1151, 1158, 1152, 490, 1153, + 1159, 1154, 1160, 1155, 462, 1156, -1, 1150, 1143, + 1151, 1144, 1152, 1145, 1153, 1146, 1154, 1147, + 1155, 1148, 1156, 1149, -1, 1143, 1292, 1144, 1137, + 1145, 1138, 1146, 1139, 1147, 1140, 1148, 1141, + 1149, 1142, -1, 1292, 1129, 1137, 1130, 1138, 1131, + 1139, 1132, 1140, 1133, 1141, 1134, 1142, 1135, + -1, 1129, 1121, 1130, 1123, 1131, 1124, 1132, 1125, + 1133, 1126, 1134, 1127, 1135, 1128, -1, 1121, 1293, + 1123, 1294, 1124, 1295, 1125, 1296, 1126, 1297, + 1127, 1298, 1128, 1285, -1, 902, 1024, 901, 1023, + 900, 1022, 899, 1021, 898, 1020, 897, 1019, + 862, 983, 861, 982, 860, 981, 859, 980, + 858, 979, 857, 978, 856, 977, -1, 856, 849, + 857, 850, 858, 851, 1299, 852, 1300, 853, + 1301, 854, 1302, 855, -1, 849, 842, 850, 843, + 851, 844, 852, 845, 853, 846, 854, 847, + 855, 848, -1, 842, 835, 843, 836, 844, 837, + 845, 838, 846, 839, 847, 840, 848, 841, + -1, 835, 828, 836, 829, 837, 830, 838, 831, + 839, 832, 840, 833, 841, 834, -1, 828, 818, + 829, 820, 830, 822, 831, 824, 832, 825, + 833, 826, 834, 827, -1, 818, 819, 820, 821, + 822, 823, 824, 1303, 825, 1304, 826, 1305, + 827, 1306, -1, 1307, 948, 1308, 947, 1309, 946, + 1310, 945, 1311, 944, 1312, 943, 1313, 909, + 1314, 908, 1315, 907, 1316, 906, 1317, 905, + 1318, 904, 1319, 903, -1, 948, 954, 947, 953, + 946, 952, 945, 951, 944, 950, 943, 949, + 909, 916, 908, 915, 907, 914, 906, 913, + 905, 912, 904, 911, 903, 910, -1, 954, 835, + 953, 959, 952, 958, 951, 957, 950, 956, + 949, 955, 916, 922, 915, 921, 914, 920, + 913, 919, 912, 918, 911, 917, 910, 882, + -1, 835, 965, 959, 964, 958, 963, 957, 962, + 956, 961, 955, 960, 922, 929, 921, 928, + 920, 927, 919, 926, 918, 925, 917, 924, + 882, 923, -1, 965, 971, 964, 970, 963, 969, + 962, 968, 961, 967, 960, 966, 929, 936, + 928, 935, 927, 934, 926, 933, 925, 932, + 924, 931, 923, 930, -1, 971, 856, 970, 976, + 969, 975, 968, 974, 967, 973, 966, 972, + 936, 942, 935, 941, 934, 940, 933, 939, + 932, 938, 931, 937, 930, 902, -1, 856, 977, + 976, 1095, 1320, 1094, 974, 1093, 1321, 1092, + 1322, 1091, 1323, 1060, 1324, 1059, 1325, 1058, + 939, 1057, 1326, 1056, 937, 1055, 902, 1024, + -1, 1302, 890, 1327, 891, 1328, 892, 1329, 893, + 900, 894, 901, 895, 902, 896, -1, 890, 883, + 891, 884, 892, 885, 893, 886, 894, 887, + 895, 888, 896, 889, -1, 883, 841, 884, 877, + 885, 878, 886, 879, 887, 880, 888, 881, + 889, 882, -1, 841, 870, 877, 871, 878, 872, + 879, 873, 880, 874, 881, 875, 882, 876, + -1, 870, 863, 871, 864, 872, 865, 873, 866, + 874, 867, 875, 868, 876, 869, -1, 863, 1330, + 864, 1331, 865, 1332, 866, 1333, 867, 1334, + 868, 1335, 869, 1336, -1, 787, 780, 813, 808, + 814, 809, 815, 810, 816, 811, 817, 812, + 781, 774, 782, 775, 783, 776, 784, 777, + 785, 778, 786, 779, 787, 780, -1, 774, 767, + 775, 768, 776, 769, 777, 770, 778, 771, + 779, 772, 780, 773, -1, 767, 760, 768, 761, + 769, 762, 770, 763, 771, 764, 772, 765, + 773, 766, 803, 798, 804, 799, 805, 800, + 806, 801, 807, 802, 767, 760, -1, 767, 774, + 807, 812, 806, 811, 805, 810, 804, 809, + 803, 808, 773, 780, -1, 760, 753, 761, 754, + 762, 755, 763, 756, 764, 757, 765, 758, + 766, 759, 798, 793, 799, 794, 800, 795, + 801, 796, 802, 797, 760, 753, -1, 759, 752, + 793, 788, 794, 789, 795, 790, 796, 791, + 797, 792, 753, 746, -1, 752, 703, 788, 741, + 789, 742, 790, 743, 791, 744, 792, 745, + 746, 697, 747, 698, 748, 699, 749, 700, + 750, 701, 751, 702, 752, 703, -1, 752, 759, + 751, 758, 750, 757, 749, 756, 748, 755, + 747, 754, 746, 753, -1, 703, 734, 1337, 735, + 742, 736, 743, 737, 744, 738, 1338, 739, + 1339, 740, -1, 734, 727, 735, 728, 736, 729, + 737, 730, 738, 731, 739, 732, 740, 733, + -1, 727, 682, 728, 722, 729, 723, 730, 724, + 731, 725, 732, 726, 733, 676, -1, 682, 716, + 722, 717, 723, 718, 724, 719, 725, 720, + 726, 721, 676, 669, -1, 716, 704, 717, 705, + 718, 707, 719, 709, 720, 711, 721, 713, + 669, 715, -1, 704, 668, 705, 706, 707, 708, + 709, 710, 711, 712, 713, 714, 715, 656, + -1, 1339, 690, 698, 691, 1340, 692, 700, 693, + 701, 694, 702, 695, 703, 696, -1, 690, 683, + 691, 684, 692, 685, 693, 686, 694, 687, + 695, 688, 696, 689, -1, 683, 676, 684, 677, + 685, 678, 686, 679, 687, 680, 688, 681, + 689, 682, -1, 676, 669, 677, 670, 678, 671, + 679, 672, 680, 673, 681, 674, 682, 675, + -1, 669, 655, 670, 657, 671, 659, 672, 661, + 673, 663, 674, 665, 675, 667, -1, 655, 656, + 657, 658, 659, 660, 661, 662, 663, 664, + 665, 666, 667, 668, -1, 624, 618, 650, 645, + 651, 646, 652, 647, 653, 648, 654, 649, + 266, 612, -1, 266, 612, 619, 613, 620, 614, + 621, 615, 622, 616, 623, 617, 624, 618, + -1, 612, 605, 613, 606, 614, 607, 615, 608, + 616, 609, 617, 610, 618, 611, 645, 640, + 646, 641, 647, 642, 648, 643, 649, 644, + 612, 605, -1, 605, 598, 606, 599, 607, 600, + 608, 601, 609, 602, 610, 603, 611, 604, + 640, 635, 641, 636, 642, 637, 643, 638, + 644, 639, 605, 598, -1, 604, 597, 635, 630, + 636, 631, 637, 632, 638, 633, 639, 634, + 598, 591, -1, 597, 590, 630, 625, 631, 626, + 632, 627, 633, 628, 634, 629, 591, 584, + -1, 590, 541, 625, 579, 626, 580, 627, 581, + 628, 582, 629, 583, 584, 535, 585, 536, + 586, 537, 587, 538, 588, 539, 589, 540, + 590, 541, -1, 590, 597, 589, 596, 588, 595, + 587, 594, 586, 593, 585, 592, 584, 591, + -1, 597, 604, 596, 603, 595, 602, 594, 601, + 593, 600, 592, 599, 591, 598, -1, 541, 572, + 579, 573, 580, 574, 581, 575, 582, 576, + 583, 577, 535, 578, -1, 572, 565, 573, 566, + 574, 567, 575, 568, 576, 569, 577, 570, + 578, 571, -1, 565, 520, 566, 560, 567, 561, + 568, 562, 569, 563, 570, 564, 571, 514, + -1, 520, 553, 560, 554, 561, 555, 562, 556, + 563, 557, 564, 558, 514, 559, -1, 553, 505, + 554, 542, 555, 544, 556, 546, 557, 548, + 558, 550, 559, 552, -1, 505, 506, 542, 543, + 544, 545, 546, 547, 548, 549, 550, 551, + 552, 494, -1, 535, 528, 536, 529, 537, 530, + 538, 531, 539, 532, 540, 533, 541, 534, + -1, 528, 521, 529, 522, 530, 523, 531, 524, + 532, 525, 533, 526, 534, 527, -1, 521, 514, + 522, 515, 523, 516, 524, 517, 525, 518, + 526, 519, 527, 520, -1, 514, 507, 515, 508, + 516, 509, 517, 510, 518, 511, 519, 512, + 520, 513, -1, 507, 493, 508, 495, 509, 497, + 510, 499, 511, 501, 512, 503, 513, 1341, + -1, 493, 494, 495, 496, 497, 498, 499, 500, + 501, 502, 503, 504, 1341, 506, -1, 216, 349, + 348, 467, 347, 466, 346, 465, 345, 464, + 344, 463, 310, 432, 309, 431, 308, 430, + 307, 429, 306, 428, 305, 427, 1342, 396, + -1, 349, 356, 467, 472, 466, 471, 465, 470, + 464, 469, 463, 468, 432, 438, 431, 437, + 430, 436, 429, 435, 428, 434, 427, 433, + 396, 402, -1, 356, 363, 472, 477, 471, 476, + 470, 475, 469, 474, 468, 473, 438, 444, + 437, 443, 436, 442, 435, 441, 434, 440, + 433, 439, 402, 408, -1, 363, 370, 477, 482, + 476, 481, 475, 480, 474, 479, 473, 478, + 444, 450, 443, 449, 442, 448, 441, 447, + 440, 446, 439, 445, 408, 414, -1, 370, 377, + 482, 487, 481, 486, 480, 485, 479, 484, + 478, 483, 450, 456, 449, 455, 448, 454, + 447, 453, 446, 452, 445, 451, 414, 420, + -1, 377, 384, 487, 492, 486, 491, 485, 490, + 484, 489, 483, 488, 456, 462, 455, 461, + 454, 460, 453, 459, 452, 458, 451, 457, + 420, 426, -1, 1342, 396, 265, 395, 264, 394, + 263, 393, 262, 392, 261, 391, 222, 355, + 221, 354, 220, 353, 219, 352, 218, 351, + 217, 350, 216, 349, -1, 396, 1343, 395, 401, + 394, 400, 393, 399, 392, 398, 391, 397, + 355, 362, 354, 361, 353, 360, 352, 359, + 351, 358, 350, 357, 349, 1344, -1, 1343, 1345, + 401, 407, 400, 406, 399, 405, 398, 404, + 397, 403, 362, 369, 361, 368, 360, 367, + 359, 366, 358, 365, 357, 364, 1344, 1346, + -1, 1345, 1347, 407, 413, 406, 412, 405, 411, + 404, 410, 403, 409, 369, 376, 368, 375, + 367, 374, 366, 373, 365, 372, 364, 371, + 1346, 1348, -1, 1347, 1349, 413, 419, 412, 418, + 411, 417, 410, 416, 409, 415, 376, 383, + 375, 382, 374, 381, 373, 380, 372, 379, + 371, 378, 1348, 1350, -1, 1349, 426, 419, 425, + 418, 424, 417, 423, 416, 422, 415, 421, + 383, 390, 382, 389, 381, 388, 380, 387, + 379, 386, 378, 385, 1350, 384, -1, 42, 320, + 319, 318, 317, 316, 174, 315, 314, 313, + 312, 311, 137, 277, 276, 275, 274, 273, + 134, 272, 271, 270, 269, 268, 92, 267, + -1, 320, 326, 318, 325, 316, 324, 315, 323, + 313, 322, 311, 321, 277, 284, 275, 283, + 273, 282, 272, 281, 270, 280, 268, 279, + 267, 278, -1, 326, 195, 325, 331, 324, 330, + 323, 329, 322, 328, 321, 327, 284, 290, + 283, 289, 282, 288, 281, 287, 280, 286, + 279, 285, 278, 246, -1, 195, 337, 331, 336, + 330, 335, 329, 334, 328, 333, 327, 332, + 290, 297, 289, 296, 288, 295, 287, 294, + 286, 293, 285, 292, 246, 291, -1, 337, 343, + 336, 342, 335, 341, 334, 340, 333, 339, + 332, 338, 297, 304, 296, 303, 295, 302, + 294, 301, 293, 300, 292, 299, 291, 298, + -1, 343, 216, 342, 348, 341, 347, 340, 346, + 339, 345, 338, 344, 304, 310, 303, 309, + 302, 308, 301, 307, 300, 306, 299, 305, + 298, 1342, -1, 222, 254, 261, 255, 262, 256, + 263, 257, 264, 258, 265, 259, 1342, 260, + -1, 254, 247, 255, 248, 256, 249, 257, 250, + 258, 251, 259, 252, 260, 253, -1, 247, 201, + 248, 241, 249, 242, 250, 243, 251, 244, + 252, 245, 253, 246, -1, 201, 234, 241, 235, + 242, 236, 243, 237, 244, 238, 245, 239, + 246, 240, -1, 234, 223, 235, 224, 236, 226, + 237, 228, 238, 229, 239, 231, 240, 233, + -1, 223, 48, 224, 225, 226, 227, 228, 89, + 229, 230, 231, 232, 233, 92, -1, 216, 209, + 1351, 210, 218, 211, 219, 212, 220, 213, + 221, 214, 222, 215, -1, 209, 202, 210, 203, + 211, 204, 212, 205, 213, 206, 214, 207, + 215, 208, -1, 202, 195, 203, 196, 204, 197, + 205, 198, 206, 199, 207, 200, 208, 201, + -1, 195, 188, 196, 189, 197, 190, 198, 191, + 199, 192, 200, 193, 201, 194, -1, 188, 177, + 189, 178, 190, 180, 191, 182, 192, 183, + 193, 185, 194, 187, -1, 177, 42, 178, 179, + 180, 181, 182, 45, 183, 184, 185, 186, + 187, 48, -1, 1, 148, 147, 146, 145, 144, + 143, 142, 141, 140, 139, 138, 105, 104, + 103, 102, 101, 100, 99, 98, 97, 96, + 95, 94, 60, 93, -1, 148, 154, 146, 153, + 144, 152, 142, 151, 140, 150, 138, 149, + 104, 112, 102, 111, 100, 110, 98, 109, + 96, 108, 94, 107, 93, 106, -1, 154, 21, + 153, 159, 152, 158, 151, 157, 150, 156, + 149, 155, 112, 118, 111, 117, 110, 116, + 109, 115, 108, 114, 107, 113, 106, 72, + -1, 21, 165, 159, 164, 158, 163, 157, 162, + 156, 161, 155, 160, 118, 124, 117, 123, + 116, 122, 115, 121, 114, 120, 113, 119, + 72, 79, -1, 165, 171, 164, 170, 163, 169, + 162, 168, 161, 167, 160, 166, 124, 131, + 123, 130, 122, 129, 121, 128, 120, 127, + 119, 126, 79, 125, -1, 171, 1352, 170, 176, + 169, 175, 168, 1353, 167, 173, 166, 172, + 131, 1354, 130, 136, 129, 135, 128, 1355, + 127, 133, 126, 132, 125, 1356, -1, 1357, 80, + 87, 81, 88, 82, 1358, 83, 90, 84, + 91, 85, 1356, 86, -1, 80, 73, 81, 74, + 82, 75, 83, 76, 84, 77, 85, 78, + 86, 1359, -1, 73, 27, 74, 67, 75, 68, + 76, 69, 77, 70, 78, 71, 1359, 72, + -1, 27, 20, 67, 61, 68, 62, 69, 63, + 70, 64, 71, 65, 72, 66, -1, 20, 12, + 61, 49, 62, 51, 63, 53, 64, 55, + 65, 57, 66, 59, -1, 12, 13, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, -1, 1352, 35, 43, 36, 44, 37, + 1360, 38, 46, 39, 47, 40, 1357, 41, + -1, 35, 28, 36, 29, 37, 30, 38, 31, + 39, 32, 40, 33, 41, 34, -1, 28, 21, + 29, 22, 30, 23, 31, 24, 32, 25, + 33, 26, 34, 27, -1, 21, 14, 22, 15, + 23, 16, 24, 17, 25, 18, 26, 19, + 27, 20, -1, 14, 0, 15, 2, 16, 4, + 17, 6, 18, 8, 19, 10, 20, 1361, + -1, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 1361, 13, -1, 1024, 1055, + 1061, 1062, 1068, 1069, 1075, 1076, 1082, 1083, + 1089, 1090, -1, 1089, 1088, 1082, 1081, 1075, 1074, + 1068, 1067, 1061, 1030, 1024, 1023, -1, 1030, 1067, + 1036, 1073, 1042, 1079, 1048, 1085, 1054, -1, 1085, + 1079, 1086, 1080, 1087, 1081, 1088, -1, 1081, 1080, + 1074, 1073, 1067, -1, 1080, 1079, 1073, -1, 1055, 1056, + 1062, 1063, 1069, 1070, 1076, 1077, 1083, 1084, + 1090, 1116, -1, 1056, 1057, 1063, 1064, 1070, 1071, + 1077, 1078, 1084, 1111, 1116, 1117, -1, 1057, 1058, + 1064, 1065, 1071, 1072, 1078, 1106, 1111, 1112, + 1117, 1118, -1, 1058, 1059, 1065, 1066, 1072, 1101, + 1106, 1107, 1112, 1113, 1118, 1119, -1, 1059, 1060, + 1066, 1096, 1101, 1102, 1107, 1108, 1113, 1114, + 1119, 1120, -1, 1060, 1091, 1096, 1097, 1102, 1103, + 1108, 1109, 1114, 1115, 1120, 1012, -1, 1091, 1092, + 1097, 1098, 1103, 1104, 1109, 1110, 1115, 1005, + 1012, 1013, -1, 1092, 1093, 1098, 1099, 1104, 1105, + 1110, 998, 1005, 1006, 1013, 1014, -1, 998, 1105, + 991, 1100, 984, 1095, 977, -1, 1095, 1100, 1094, + 1099, 1093, -1, 1100, 1105, 1099, -1, 984, 977, 985, + 978, 986, 979, 987, 980, 988, 981, 989, + 982, 990, 983, 1025, 1019, 1026, 1020, 1027, + 1021, 1028, 1022, 1029, 1023, 1030, -1, 1030, 1362, + 1029, 1035, 1028, 1034, 1027, 1033, 1026, 1032, + 1025, 1031, 990, 997, 989, 996, 988, 995, + 987, 994, 986, 993, 985, 992, 984, 1363, + -1, 1362, 1042, 1035, 1041, 1034, 1040, 1033, 1039, + 1032, 1038, 1031, 1037, 997, 1004, 996, 1003, + 995, 1002, 994, 1001, 993, 1000, 992, 999, + 1363, 998, -1, 998, 999, 1006, 1007, 1014, 1015, + -1, 999, 1000, 1007, 1008, 1015, 1016, -1, 1000, 1001, + 1008, 1009, 1016, 1017, -1, 1001, 1002, 1009, 1010, + 1017, 1018, -1, 1002, 1003, 1010, 1011, 1018, 1049, + -1, 1003, 1004, 1011, 1043, 1049, 1050, -1, 1004, 1037, + 1043, 1044, 1050, 1051, -1, 1037, 1038, 1044, 1045, + 1051, 1052, -1, 1038, 1039, 1045, 1046, 1052, 1053, + -1, 1039, 1040, 1046, 1047, 1053, 1054, -1, 1054, 1047, + 1048, 1041, 1042, -1, 1041, 1047, 1040, -1, + }; + +// Simpler to draw count/data format of the teapot_indicies array above. +short new_teapot_indicies[] = { + 26, 1122, 1243, 1272, 1242, 1273, 1241, 1274, 1240, 1275, 1239, 1276, 1238, 1277, 1205, 1278, 1204, 1279, 1203, 1280, 1202, 1281, 1201, 1282, 1200, 1283, 1199, + 26, 1243, 1249, 1242, 1248, 1241, 1247, 1240, 1246, 1239, 1245, 1238, 1244, 1205, 1212, 1204, 1211, 1203, 1210, 1202, 1209, 1201, 1208, 1200, 1207, 1199, 1206, + 26, 1249, 1136, 1248, 1254, 1247, 1253, 1246, 1252, 1245, 1251, 1244, 1250, 1212, 1218, 1211, 1217, 1210, 1216, 1209, 1215, 1208, 1214, 1207, 1213, 1206, 1180, + 26, 1136, 1260, 1254, 1259, 1253, 1258, 1252, 1257, 1251, 1256, 1250, 1255, 1218, 1225, 1217, 1224, 1216, 1223, 1215, 1222, 1214, 1221, 1213, 1220, 1180, 1219, + 26, 1260, 1266, 1259, 1265, 1258, 1264, 1257, 1263, 1256, 1262, 1255, 1261, 1225, 1232, 1224, 1231, 1223, 1230, 1222, 1229, 1221, 1228, 1220, 1227, 1219, 1226, + 26, 1266, 384, 1265, 1271, 1264, 1270, 1263, 1269, 1262, 1268, 1261, 1267, 1232, 390, 1231, 1237, 1230, 1236, 1229, 1235, 1228, 1234, 1227, 1233, 1226, 426, + 14, 462, 1188, 1195, 1189, 1196, 1190, 459, 1191, 1197, 1192, 1198, 1193, 426, 1194, + 14, 1188, 1181, 1189, 1182, 1190, 1183, 1191, 1184, 1192, 1185, 1193, 1186, 1194, 1187, + 14, 1181, 1142, 1182, 1175, 1183, 1176, 1184, 1177, 1185, 1178, 1186, 1179, 1187, 1284, + 14, 1142, 1168, 1175, 1169, 1176, 1170, 1177, 1171, 1178, 1172, 1179, 1173, 1284, 1174, + 14, 1168, 1161, 1169, 1162, 1170, 1163, 1171, 1164, 1172, 1165, 1173, 1166, 1174, 1167, + 14, 1161, 1285, 1162, 1286, 1163, 1287, 1164, 1288, 1165, 1289, 1166, 1290, 1167, 1291, + 14, 384, 1150, 1157, 1151, 1158, 1152, 490, 1153, 1159, 1154, 1160, 1155, 462, 1156, + 14, 1150, 1143, 1151, 1144, 1152, 1145, 1153, 1146, 1154, 1147, 1155, 1148, 1156, 1149, + 14, 1143, 1292, 1144, 1137, 1145, 1138, 1146, 1139, 1147, 1140, 1148, 1141, 1149, 1142, + 14, 1292, 1129, 1137, 1130, 1138, 1131, 1139, 1132, 1140, 1133, 1141, 1134, 1142, 1135, + 14, 1129, 1121, 1130, 1123, 1131, 1124, 1132, 1125, 1133, 1126, 1134, 1127, 1135, 1128, + 14, 1121, 1293, 1123, 1294, 1124, 1295, 1125, 1296, 1126, 1297, 1127, 1298, 1128, 1285, + 26, 902, 1024, 901, 1023, 900, 1022, 899, 1021, 898, 1020, 897, 1019, 862, 983, 861, 982, 860, 981, 859, 980, 858, 979, 857, 978, 856, 977, + 14, 856, 849, 857, 850, 858, 851, 1299, 852, 1300, 853, 1301, 854, 1302, 855, + 14, 849, 842, 850, 843, 851, 844, 852, 845, 853, 846, 854, 847, 855, 848, + 14, 842, 835, 843, 836, 844, 837, 845, 838, 846, 839, 847, 840, 848, 841, + 14, 835, 828, 836, 829, 837, 830, 838, 831, 839, 832, 840, 833, 841, 834, + 14, 828, 818, 829, 820, 830, 822, 831, 824, 832, 825, 833, 826, 834, 827, + 14, 818, 819, 820, 821, 822, 823, 824, 1303, 825, 1304, 826, 1305, 827, 1306, + 26, 1307, 948, 1308, 947, 1309, 946, 1310, 945, 1311, 944, 1312, 943, 1313, 909, 1314, 908, 1315, 907, 1316, 906, 1317, 905, 1318, 904, 1319, 903, + 26, 948, 954, 947, 953, 946, 952, 945, 951, 944, 950, 943, 949, 909, 916, 908, 915, 907, 914, 906, 913, 905, 912, 904, 911, 903, 910, + 26, 954, 835, 953, 959, 952, 958, 951, 957, 950, 956, 949, 955, 916, 922, 915, 921, 914, 920, 913, 919, 912, 918, 911, 917, 910, 882, + 26, 835, 965, 959, 964, 958, 963, 957, 962, 956, 961, 955, 960, 922, 929, 921, 928, 920, 927, 919, 926, 918, 925, 917, 924, 882, 923, + 26, 965, 971, 964, 970, 963, 969, 962, 968, 961, 967, 960, 966, 929, 936, 928, 935, 927, 934, 926, 933, 925, 932, 924, 931, 923, 930, + 26, 971, 856, 970, 976, 969, 975, 968, 974, 967, 973, 966, 972, 936, 942, 935, 941, 934, 940, 933, 939, 932, 938, 931, 937, 930, 902, + 26, 856, 977, 976, 1095, 1320, 1094, 974, 1093, 1321, 1092, 1322, 1091, 1323, 1060, 1324, 1059, 1325, 1058, 939, 1057, 1326, 1056, 937, 1055, 902, 1024, + 14, 1302, 890, 1327, 891, 1328, 892, 1329, 893, 900, 894, 901, 895, 902, 896, + 14, 890, 883, 891, 884, 892, 885, 893, 886, 894, 887, 895, 888, 896, 889, + 14, 883, 841, 884, 877, 885, 878, 886, 879, 887, 880, 888, 881, 889, 882, + 14, 841, 870, 877, 871, 878, 872, 879, 873, 880, 874, 881, 875, 882, 876, + 14, 870, 863, 871, 864, 872, 865, 873, 866, 874, 867, 875, 868, 876, 869, + 14, 863, 1330, 864, 1331, 865, 1332, 866, 1333, 867, 1334, 868, 1335, 869, 1336, + 26, 787, 780, 813, 808, 814, 809, 815, 810, 816, 811, 817, 812, 781, 774, 782, 775, 783, 776, 784, 777, 785, 778, 786, 779, 787, 780, + 14, 774, 767, 775, 768, 776, 769, 777, 770, 778, 771, 779, 772, 780, 773, + 26, 767, 760, 768, 761, 769, 762, 770, 763, 771, 764, 772, 765, 773, 766, 803, 798, 804, 799, 805, 800, 806, 801, 807, 802, 767, 760, + 14, 767, 774, 807, 812, 806, 811, 805, 810, 804, 809, 803, 808, 773, 780, + 26, 760, 753, 761, 754, 762, 755, 763, 756, 764, 757, 765, 758, 766, 759, 798, 793, 799, 794, 800, 795, 801, 796, 802, 797, 760, 753, + 14, 759, 752, 793, 788, 794, 789, 795, 790, 796, 791, 797, 792, 753, 746, + 26, 752, 703, 788, 741, 789, 742, 790, 743, 791, 744, 792, 745, 746, 697, 747, 698, 748, 699, 749, 700, 750, 701, 751, 702, 752, 703, + 14, 752, 759, 751, 758, 750, 757, 749, 756, 748, 755, 747, 754, 746, 753, + 14, 703, 734, 1337, 735, 742, 736, 743, 737, 744, 738, 1338, 739, 1339, 740, + 14, 734, 727, 735, 728, 736, 729, 737, 730, 738, 731, 739, 732, 740, 733, + 14, 727, 682, 728, 722, 729, 723, 730, 724, 731, 725, 732, 726, 733, 676, + 14, 682, 716, 722, 717, 723, 718, 724, 719, 725, 720, 726, 721, 676, 669, + 14, 716, 704, 717, 705, 718, 707, 719, 709, 720, 711, 721, 713, 669, 715, + 14, 704, 668, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 656, + 14, 1339, 690, 698, 691, 1340, 692, 700, 693, 701, 694, 702, 695, 703, 696, + 14, 690, 683, 691, 684, 692, 685, 693, 686, 694, 687, 695, 688, 696, 689, + 14, 683, 676, 684, 677, 685, 678, 686, 679, 687, 680, 688, 681, 689, 682, + 14, 676, 669, 677, 670, 678, 671, 679, 672, 680, 673, 681, 674, 682, 675, + 14, 669, 655, 670, 657, 671, 659, 672, 661, 673, 663, 674, 665, 675, 667, + 14, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, + 14, 624, 618, 650, 645, 651, 646, 652, 647, 653, 648, 654, 649, 266, 612, + 14, 266, 612, 619, 613, 620, 614, 621, 615, 622, 616, 623, 617, 624, 618, + 26, 612, 605, 613, 606, 614, 607, 615, 608, 616, 609, 617, 610, 618, 611, 645, 640, 646, 641, 647, 642, 648, 643, 649, 644, 612, 605, + 26, 605, 598, 606, 599, 607, 600, 608, 601, 609, 602, 610, 603, 611, 604, 640, 635, 641, 636, 642, 637, 643, 638, 644, 639, 605, 598, + 14, 604, 597, 635, 630, 636, 631, 637, 632, 638, 633, 639, 634, 598, 591, + 14, 597, 590, 630, 625, 631, 626, 632, 627, 633, 628, 634, 629, 591, 584, + 26, 590, 541, 625, 579, 626, 580, 627, 581, 628, 582, 629, 583, 584, 535, 585, 536, 586, 537, 587, 538, 588, 539, 589, 540, 590, 541, + 14, 590, 597, 589, 596, 588, 595, 587, 594, 586, 593, 585, 592, 584, 591, + 14, 597, 604, 596, 603, 595, 602, 594, 601, 593, 600, 592, 599, 591, 598, + 14, 541, 572, 579, 573, 580, 574, 581, 575, 582, 576, 583, 577, 535, 578, + 14, 572, 565, 573, 566, 574, 567, 575, 568, 576, 569, 577, 570, 578, 571, + 14, 565, 520, 566, 560, 567, 561, 568, 562, 569, 563, 570, 564, 571, 514, + 14, 520, 553, 560, 554, 561, 555, 562, 556, 563, 557, 564, 558, 514, 559, + 14, 553, 505, 554, 542, 555, 544, 556, 546, 557, 548, 558, 550, 559, 552, + 14, 505, 506, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 494, + 14, 535, 528, 536, 529, 537, 530, 538, 531, 539, 532, 540, 533, 541, 534, + 14, 528, 521, 529, 522, 530, 523, 531, 524, 532, 525, 533, 526, 534, 527, + 14, 521, 514, 522, 515, 523, 516, 524, 517, 525, 518, 526, 519, 527, 520, + 14, 514, 507, 515, 508, 516, 509, 517, 510, 518, 511, 519, 512, 520, 513, + 14, 507, 493, 508, 495, 509, 497, 510, 499, 511, 501, 512, 503, 513, 1341, + 14, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 1341, 506, + 26, 216, 349, 348, 467, 347, 466, 346, 465, 345, 464, 344, 463, 310, 432, 309, 431, 308, 430, 307, 429, 306, 428, 305, 427, 1342, 396, + 26, 349, 356, 467, 472, 466, 471, 465, 470, 464, 469, 463, 468, 432, 438, 431, 437, 430, 436, 429, 435, 428, 434, 427, 433, 396, 402, + 26, 356, 363, 472, 477, 471, 476, 470, 475, 469, 474, 468, 473, 438, 444, 437, 443, 436, 442, 435, 441, 434, 440, 433, 439, 402, 408, + 26, 363, 370, 477, 482, 476, 481, 475, 480, 474, 479, 473, 478, 444, 450, 443, 449, 442, 448, 441, 447, 440, 446, 439, 445, 408, 414, + 26, 370, 377, 482, 487, 481, 486, 480, 485, 479, 484, 478, 483, 450, 456, 449, 455, 448, 454, 447, 453, 446, 452, 445, 451, 414, 420, + 26, 377, 384, 487, 492, 486, 491, 485, 490, 484, 489, 483, 488, 456, 462, 455, 461, 454, 460, 453, 459, 452, 458, 451, 457, 420, 426, + 26, 1342, 396, 265, 395, 264, 394, 263, 393, 262, 392, 261, 391, 222, 355, 221, 354, 220, 353, 219, 352, 218, 351, 217, 350, 216, 349, + 26, 396, 1343, 395, 401, 394, 400, 393, 399, 392, 398, 391, 397, 355, 362, 354, 361, 353, 360, 352, 359, 351, 358, 350, 357, 349, 1344, + 26, 1343, 1345, 401, 407, 400, 406, 399, 405, 398, 404, 397, 403, 362, 369, 361, 368, 360, 367, 359, 366, 358, 365, 357, 364, 1344, 1346, + 26, 1345, 1347, 407, 413, 406, 412, 405, 411, 404, 410, 403, 409, 369, 376, 368, 375, 367, 374, 366, 373, 365, 372, 364, 371, 1346, 1348, + 26, 1347, 1349, 413, 419, 412, 418, 411, 417, 410, 416, 409, 415, 376, 383, 375, 382, 374, 381, 373, 380, 372, 379, 371, 378, 1348, 1350, + 26, 1349, 426, 419, 425, 418, 424, 417, 423, 416, 422, 415, 421, 383, 390, 382, 389, 381, 388, 380, 387, 379, 386, 378, 385, 1350, 384, + 26, 42, 320, 319, 318, 317, 316, 174, 315, 314, 313, 312, 311, 137, 277, 276, 275, 274, 273, 134, 272, 271, 270, 269, 268, 92, 267, + 26, 320, 326, 318, 325, 316, 324, 315, 323, 313, 322, 311, 321, 277, 284, 275, 283, 273, 282, 272, 281, 270, 280, 268, 279, 267, 278, + 26, 326, 195, 325, 331, 324, 330, 323, 329, 322, 328, 321, 327, 284, 290, 283, 289, 282, 288, 281, 287, 280, 286, 279, 285, 278, 246, + 26, 195, 337, 331, 336, 330, 335, 329, 334, 328, 333, 327, 332, 290, 297, 289, 296, 288, 295, 287, 294, 286, 293, 285, 292, 246, 291, + 26, 337, 343, 336, 342, 335, 341, 334, 340, 333, 339, 332, 338, 297, 304, 296, 303, 295, 302, 294, 301, 293, 300, 292, 299, 291, 298, + 26, 343, 216, 342, 348, 341, 347, 340, 346, 339, 345, 338, 344, 304, 310, 303, 309, 302, 308, 301, 307, 300, 306, 299, 305, 298, 1342, + 14, 222, 254, 261, 255, 262, 256, 263, 257, 264, 258, 265, 259, 1342, 260, + 14, 254, 247, 255, 248, 256, 249, 257, 250, 258, 251, 259, 252, 260, 253, + 14, 247, 201, 248, 241, 249, 242, 250, 243, 251, 244, 252, 245, 253, 246, + 14, 201, 234, 241, 235, 242, 236, 243, 237, 244, 238, 245, 239, 246, 240, + 14, 234, 223, 235, 224, 236, 226, 237, 228, 238, 229, 239, 231, 240, 233, + 14, 223, 48, 224, 225, 226, 227, 228, 89, 229, 230, 231, 232, 233, 92, + 14, 216, 209, 1351, 210, 218, 211, 219, 212, 220, 213, 221, 214, 222, 215, + 14, 209, 202, 210, 203, 211, 204, 212, 205, 213, 206, 214, 207, 215, 208, + 14, 202, 195, 203, 196, 204, 197, 205, 198, 206, 199, 207, 200, 208, 201, + 14, 195, 188, 196, 189, 197, 190, 198, 191, 199, 192, 200, 193, 201, 194, + 14, 188, 177, 189, 178, 190, 180, 191, 182, 192, 183, 193, 185, 194, 187, + 14, 177, 42, 178, 179, 180, 181, 182, 45, 183, 184, 185, 186, 187, 48, + 26, 1, 148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 60, 93, + 26, 148, 154, 146, 153, 144, 152, 142, 151, 140, 150, 138, 149, 104, 112, 102, 111, 100, 110, 98, 109, 96, 108, 94, 107, 93, 106, + 26, 154, 21, 153, 159, 152, 158, 151, 157, 150, 156, 149, 155, 112, 118, 111, 117, 110, 116, 109, 115, 108, 114, 107, 113, 106, 72, + 26, 21, 165, 159, 164, 158, 163, 157, 162, 156, 161, 155, 160, 118, 124, 117, 123, 116, 122, 115, 121, 114, 120, 113, 119, 72, 79, + 26, 165, 171, 164, 170, 163, 169, 162, 168, 161, 167, 160, 166, 124, 131, 123, 130, 122, 129, 121, 128, 120, 127, 119, 126, 79, 125, + 26, 171, 1352, 170, 176, 169, 175, 168, 1353, 167, 173, 166, 172, 131, 1354, 130, 136, 129, 135, 128, 1355, 127, 133, 126, 132, 125, 1356, + 14, 1357, 80, 87, 81, 88, 82, 1358, 83, 90, 84, 91, 85, 1356, 86, + 14, 80, 73, 81, 74, 82, 75, 83, 76, 84, 77, 85, 78, 86, 1359, + 14, 73, 27, 74, 67, 75, 68, 76, 69, 77, 70, 78, 71, 1359, 72, + 14, 27, 20, 67, 61, 68, 62, 69, 63, 70, 64, 71, 65, 72, 66, + 14, 20, 12, 61, 49, 62, 51, 63, 53, 64, 55, 65, 57, 66, 59, + 14, 12, 13, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 14, 1352, 35, 43, 36, 44, 37, 1360, 38, 46, 39, 47, 40, 1357, 41, + 14, 35, 28, 36, 29, 37, 30, 38, 31, 39, 32, 40, 33, 41, 34, + 14, 28, 21, 29, 22, 30, 23, 31, 24, 32, 25, 33, 26, 34, 27, + 14, 21, 14, 22, 15, 23, 16, 24, 17, 25, 18, 26, 19, 27, 20, + 14, 14, 0, 15, 2, 16, 4, 17, 6, 18, 8, 19, 10, 20, 1361, + 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1361, 13, + 12, 1024, 1055, 1061, 1062, 1068, 1069, 1075, 1076, 1082, 1083, 1089, 1090, + 12, 1089, 1088, 1082, 1081, 1075, 1074, 1068, 1067, 1061, 1030, 1024, 1023, + 9, 1030, 1067, 1036, 1073, 1042, 1079, 1048, 1085, 1054, + 7, 1085, 1079, 1086, 1080, 1087, 1081, 1088, + 5, 1081, 1080, 1074, 1073, 1067, + 3, 1080, 1079, 1073, + 12, 1055, 1056, 1062, 1063, 1069, 1070, 1076, 1077, 1083, 1084, 1090, 1116, + 12, 1056, 1057, 1063, 1064, 1070, 1071, 1077, 1078, 1084, 1111, 1116, 1117, + 12, 1057, 1058, 1064, 1065, 1071, 1072, 1078, 1106, 1111, 1112, 1117, 1118, + 12, 1058, 1059, 1065, 1066, 1072, 1101, 1106, 1107, 1112, 1113, 1118, 1119, + 12, 1059, 1060, 1066, 1096, 1101, 1102, 1107, 1108, 1113, 1114, 1119, 1120, + 12, 1060, 1091, 1096, 1097, 1102, 1103, 1108, 1109, 1114, 1115, 1120, 1012, + 12, 1091, 1092, 1097, 1098, 1103, 1104, 1109, 1110, 1115, 1005, 1012, 1013, + 12, 1092, 1093, 1098, 1099, 1104, 1105, 1110, 998, 1005, 1006, 1013, 1014, + 7, 998, 1105, 991, 1100, 984, 1095, 977, + 5, 1095, 1100, 1094, 1099, 1093, + 3, 1100, 1105, 1099, + 25, 984, 977, 985, 978, 986, 979, 987, 980, 988, 981, 989, 982, 990, 983, 1025, 1019, 1026, 1020, 1027, 1021, 1028, 1022, 1029, 1023, 1030, + 26, 1030, 1362, 1029, 1035, 1028, 1034, 1027, 1033, 1026, 1032, 1025, 1031, 990, 997, 989, 996, 988, 995, 987, 994, 986, 993, 985, 992, 984, 1363, + 26, 1362, 1042, 1035, 1041, 1034, 1040, 1033, 1039, 1032, 1038, 1031, 1037, 997, 1004, 996, 1003, 995, 1002, 994, 1001, 993, 1000, 992, 999, 1363, 998, + 6, 998, 999, 1006, 1007, 1014, 1015, + 6, 999, 1000, 1007, 1008, 1015, 1016, + 6, 1000, 1001, 1008, 1009, 1016, 1017, + 6, 1001, 1002, 1009, 1010, 1017, 1018, + 6, 1002, 1003, 1010, 1011, 1018, 1049, + 6, 1003, 1004, 1011, 1043, 1049, 1050, + 6, 1004, 1037, 1043, 1044, 1050, 1051, + 6, 1037, 1038, 1044, 1045, 1051, 1052, + 6, 1038, 1039, 1045, 1046, 1052, 1053, + 6, 1039, 1040, 1046, 1047, 1053, 1054, + 5, 1054, 1047, 1048, 1041, 1042, + 3, 1041, 1047, 1040, +}; + +#endif // TEAPOT_H diff --git a/GLGravity/Prefix.pch b/GLGravity/Prefix.pch new file mode 100644 index 0000000..4cf6a74 --- /dev/null +++ b/GLGravity/Prefix.pch @@ -0,0 +1,3 @@ +#ifdef __OBJC__ + #import +#endif diff --git a/GLGravity/ReadMe.txt b/GLGravity/ReadMe.txt new file mode 100644 index 0000000..7e4fac3 --- /dev/null +++ b/GLGravity/ReadMe.txt @@ -0,0 +1,66 @@ +### GLGravity ### + +=========================================================================== +DESCRIPTION: + +The GLGravity sample application demonstrates how to use the UIAccelerometer class in combination with OpenGL rendering. It shows how to extract the gravity vector from the accelerometer values using a basic low-pass filter, and how to build an OpenGL transformation matrix from it. Note that the result is not fully defined, as rotation of the device around the gravity vector cannot be detected by the accelerometer. + +This application is designed to run on a device, not in the iPhone Simulator. Rotate the device and observe how the teapot always stays upright, independent of the device orientation. + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +=========================================================================== +PACKAGING LIST: + +Classes/GLGravityAppDelegate.h +Classes/GLGravityAppDelegate.m +The GLGravityAppDelegate class is the app delegate that ties everything together. It updates the acceletometer values used to draw OpenGL content in the GLGravityView class. + +Classes/GLGravityView.h +Classes/GLGravityView.m +The GLGravityView wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view content is basically an EAGL surface you render your OpenGL scene into. + +Models/teapot.h +Contains data necessary for rendering the teapot model. + +main.m +Entry point for this application. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 2.2 +- Upgraded project to build with the iOS 4.0 SDK. + +Version 2.1 +- Updated for iPhone OS 3.1. Use CADisplayLink as the preferred method for controlling animation timing, and fall back to NSTimer when running on a pre 3.1 device where CADisplayLink is not available. +- Made the sample xib-based. + +Version 2.0 +- First Public Release. + +Version 1.4 +- Updated for Beta 5 + +Version 1.3 +- Updated for Beta 4 +- Updated build settings +- Updated ReadMe file and converted it to plain text format for viewing on website + +Version 1.2 +- Updated for Beta 3 +- Added an icon and a Default.png file + +Version 1.1 +- Updated for Beta 2 + +=========================================================================== +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/GLGravity/main.m b/GLGravity/main.m new file mode 100644 index 0000000..ca75728 --- /dev/null +++ b/GLGravity/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Entry point for this application. + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GLImageProcessing.zip b/GLImageProcessing.zip new file mode 100644 index 0000000..8ada1b3 Binary files /dev/null and b/GLImageProcessing.zip differ diff --git a/GLImageProcessing/Classes/EAGLView.h b/GLImageProcessing/Classes/EAGLView.h new file mode 100644 index 0000000..a53aa36 --- /dev/null +++ b/GLImageProcessing/Classes/EAGLView.h @@ -0,0 +1,74 @@ +/* + File: EAGLView.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import +#import + + +@interface EAGLView : UIView { + +@private + // The pixel dimensions of the backbuffer + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + IBOutlet UISlider *slider; + IBOutlet UITabBar *tabBar; + + // OpenGL names for the renderbuffer and framebuffer used to render to this view + GLuint viewRenderbuffer, viewFramebuffer; +} + +@property (nonatomic, retain) UISlider *slider; +@property (nonatomic, retain) UITabBar *tabBar; + +- (void)drawView; + +@end diff --git a/GLImageProcessing/Classes/EAGLView.m b/GLImageProcessing/Classes/EAGLView.m new file mode 100644 index 0000000..f859b2a --- /dev/null +++ b/GLImageProcessing/Classes/EAGLView.m @@ -0,0 +1,157 @@ +/* + File: EAGLView.m + Abstract: n/a + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import "EAGLView.h" +#import "Imaging.h" + + +// A class extension to declare private methods +@interface EAGLView () + +@property (nonatomic, retain) EAGLContext *context; + +@end + + +@implementation EAGLView + +@synthesize context; +@synthesize slider; +@synthesize tabBar; + + +// You must implement this method ++ (Class)layerClass +{ + return [CAEAGLLayer class]; +} + + +// The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder +{ + if ((self = [super initWithCoder:coder])) + { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, + nil]; + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + if (!context || ![EAGLContext setCurrentContext:context]) + { + [self release]; + return nil; + } + + // Create system framebuffer object. The backing will be allocated in -reshapeFramebuffer + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + // Perform additional one-time GL initialization + initGL(); + } + return self; +} + + +- (void)drawView +{ + int mode = self.tabBar.selectedItem.tag; + float value = self.slider.value; + + // This application only creates a single GL context, so it is already current here. + // If there are multiple contexts, ensure the correct one is current before drawing. + drawGL(backingWidth, backingHeight, value, mode); + + // This application only creates a single (color) renderbuffer, so it is already bound here. + // If there are multiple renderbuffers (for example color and depth), ensure the correct one is bound here. + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + + +- (void)reshapeFramebuffer +{ + // Allocate GL color buffer backing, matching the current layer size + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + // This application only needs color. If depth and/or stencil are needed, ensure they are also resized here. + rt_assert(GL_FRAMEBUFFER_COMPLETE_OES == glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + glCheckError(); +} + + +- (void)layoutSubviews +{ + [self reshapeFramebuffer]; + [self drawView]; +} + + +- (void)dealloc +{ + if ([EAGLContext currentContext] == context) + [EAGLContext setCurrentContext:nil]; + + self.context = nil; + self.slider = nil; + self.tabBar = nil; + [super dealloc]; +} + +@end diff --git a/GLImageProcessing/Classes/ViewController.h b/GLImageProcessing/Classes/ViewController.h new file mode 100644 index 0000000..5e90d9f --- /dev/null +++ b/GLImageProcessing/Classes/ViewController.h @@ -0,0 +1,62 @@ +/* + File: ViewController.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface ViewController : UIViewController +{ + IBOutlet UISlider *slider; + IBOutlet UITabBar *tabBar; +} + +@property (nonatomic, retain) UISlider *slider; +@property (nonatomic, retain) UITabBar *tabBar; + +- (IBAction)sliderAction:(id)sender; + +@end diff --git a/GLImageProcessing/Classes/ViewController.m b/GLImageProcessing/Classes/ViewController.m new file mode 100644 index 0000000..8a69258 --- /dev/null +++ b/GLImageProcessing/Classes/ViewController.m @@ -0,0 +1,254 @@ +/* + File: ViewController.m + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ViewController.h" +#import "EAGLView.h" + +#define DEG2RAD (M_PI/180.0f) + + +// These enums match the button tags in the nib +enum { + BUTTON_BRIGHTNESS, + BUTTON_CONTRAST, + BUTTON_SATURATION, + BUTTON_HUE, + BUTTON_SHARPNESS, + NUM_BUTTONS +}; + +@implementation ViewController + +@synthesize slider; +@synthesize tabBar; + + +- (void)viewDidLoad +{ + int b, i; + + // Select first tab by default + tabBar.selectedItem = [tabBar.items objectAtIndex:0]; + + // Create a bitmap context for rendering the tabBar buttons + // Usually, button images are loaded from disk, but these simple shapes can be procedurally generated. + // UITabBar only needs the alpha channel of these images. + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate(nil, 30, 30, 8, 0, colorSpace, kCGImageAlphaPremultipliedFirst); + CGImageRef theCGImage; + + // Draw with white round strokes + CGContextSetLineCap(context, kCGLineCapRound); + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextSetLineWidth(context, 2.0); + + for (b = 0; b < NUM_BUTTONS; b++) + { + CGContextClearRect(context, CGRectMake(0, 0, 30, 30)); + + switch(b) + { + case BUTTON_BRIGHTNESS: + { + const CGFloat line[8*4] = { + 15.0, 6.0, 15.0, 4.0, + 15.0,24.0, 15.0,26.0, + 6.0,15.0, 4.0,15.0, + 24.0,15.0, 26.0,15.0, + 21.5,21.5, 23.0,23.0, + 8.5, 8.5, 7.0, 7.0, + 21.5, 8.5, 23.0, 7.0, + 8.5,21.5, 7.0,23.0, + }; + + // A circle with eight rays around it + CGContextStrokeEllipseInRect(context, CGRectMake(10.5, 10.5, 9.0, 9.0)); + for (i = 0; i < 8; i++) + { + CGContextMoveToPoint(context, line[i*4+0], line[i*4+1]); + CGContextAddLineToPoint(context, line[i*4+2], line[i*4+3]); + CGContextStrokePath(context); + } + break; + } + case BUTTON_CONTRAST: + { + // A circle with the right half filled + CGContextStrokeEllipseInRect(context, CGRectMake(4.0, 4.0, 22.0, 22.0)); + CGContextAddArc(context, 15.0, 15.0, 11.0, -M_PI/2.0, M_PI/2.0, false); + CGContextFillPath(context); + break; + } + case BUTTON_SATURATION: + { + CGGradientRef gradient; + const CGFloat stripe[3][12] = { + { 0.3,0.3,0.3,0.15, 1.0,0.0,0.0,0.70, 5, 5, 7, 25 }, + { 0.5,0.5,0.5,0.25, 0.0,1.0,0.0,0.75, 12, 5, 6, 25 }, + { 0.2,0.2,0.2,0.10, 0.0,0.0,1.0,0.65, 18, 5, 7, 25 }, + }; + + // Red/Green/Blue gradients, inside a rounded rect + for (i = 0; i < 3; i++) + { + gradient = CGGradientCreateWithColorComponents(colorSpace, stripe[i], NULL, 2); + CGContextSaveGState(context); + CGContextClipToRect(context, CGRectMake(stripe[i][8], stripe[i][9], stripe[i][10], stripe[i][11])); + CGContextDrawLinearGradient(context, gradient, CGPointMake(15, 5), CGPointMake(15, 25), 0); + CGContextRestoreGState(context); + CGGradientRelease(gradient); + } + + CGContextMoveToPoint(context, 4, 15); + CGContextAddArcToPoint(context, 4, 4, 15, 4, 4); + CGContextAddArcToPoint(context, 26, 4, 26, 15, 4); + CGContextAddArcToPoint(context, 26, 26, 15, 26, 4); + CGContextAddArcToPoint(context, 4, 26, 4, 15, 4); + CGContextClosePath(context); + CGContextStrokePath(context); + break; + } + case BUTTON_HUE: + { + CGGradientRef gradient; + CGFloat hue[8]; + const int angle = 4; + + // A radial gradient, inside a circle + for (i = 0; i < 360; i+=angle) + { + float x = cosf((i+angle*0.5)*DEG2RAD)*10+15; + float y = sinf((i+angle*0.5)*DEG2RAD)*10+15; + float r = (i )/180.0; if (r > 1.0) r = 2.0-r; + float g = (i+120)/180.0; if (g > 2.0) g = g-2.0; else if (g > 1.0) g = 2.0-g; + float b = (i+240)/180.0; if (b > 3.0) b = 4.0-b; else if (b > 2.0) b = b-2.0; else b = 2.0-b; + float a = (i+ 90)/180.0; if (a > 2.0) a = a-2.0; else if (a > 1.0) a = 2.0-a; + hue[0] = hue[4] = r; + hue[1] = hue[5] = g; + hue[2] = hue[6] = b; + hue[3] = a*0.5; + hue[7] = a*0.75; + + gradient = CGGradientCreateWithColorComponents(colorSpace, hue, NULL, 2); + CGContextSaveGState(context); + CGContextMoveToPoint(context, 15, 15); + CGContextAddArc(context, 15, 15, 10, i*DEG2RAD, (i+angle)*DEG2RAD, false); + CGContextClosePath(context); + CGContextClip(context); + CGContextDrawLinearGradient(context, gradient, CGPointMake(x, y), CGPointMake(15, 15), 0); + CGContextRestoreGState(context); + CGGradientRelease(gradient); + } + + CGContextStrokeEllipseInRect(context, CGRectMake(4.0, 4.0, 22.0, 22.0)); + break; + } + case BUTTON_SHARPNESS: + { + int x, y; + + // A gradient checkerboard, inside a rounded rect + for (x = 5; x < 25; x+=2) + { + float b = (x - 5)/19.0*0.5+0.375; + if (b > 0.75) b = 0.75; + else if (b < 0.5) b = 0.5; + + for (y = 5; y < 25; y+=2) + { + float k = ((x ^ y) & 2) ? b : 1.0-b; + CGContextSetRGBFillColor(context, k, k, k, k); + CGContextFillRect(context, CGRectMake(x, y, 2, 2)); + } + } + + CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextMoveToPoint(context, 4, 15); + CGContextAddArcToPoint(context, 4, 4, 15, 4, 4); + CGContextAddArcToPoint(context, 26, 4, 26, 15, 4); + CGContextAddArcToPoint(context, 26, 26, 15, 26, 4); + CGContextAddArcToPoint(context, 4, 26, 4, 15, 4); + CGContextClosePath(context); + CGContextStrokePath(context); + break; + } + } + theCGImage = CGBitmapContextCreateImage(context); + ((UITabBarItem *)[tabBar.items objectAtIndex:b]).image = [UIImage imageWithCGImage:theCGImage]; + CGImageRelease(theCGImage); + } + + CGContextRelease(context); + CGColorSpaceRelease(colorSpace); +} + + +- (void)dealloc +{ + self.slider = nil; + self.tabBar = nil; + [super dealloc]; +} + + +- (void)sliderAction:(id)sender +{ + // Redraw the view with the new settings + [((EAGLView*)self.view) drawView]; +} + + +- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item +{ + // Recenter the slider (this application does not accumulate multiple filters) + [self.slider setValue:1.0 animated:YES]; + // Redraw the view with the new settings + [((EAGLView*)self.view) drawView]; +} + +@end diff --git a/GLImageProcessing/Debug.c b/GLImageProcessing/Debug.c new file mode 100644 index 0000000..bcedde5 --- /dev/null +++ b/GLImageProcessing/Debug.c @@ -0,0 +1,179 @@ +/* + File: Debug.c + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include +#include +#include "Debug.h" + + +// Debug utility: validate the current texture environment against MBX errata. +// Assert if we use a state combination not supported by the MBX hardware. +void validateTexEnv(void) +{ + #if DEBUG + typedef struct { + GLint combine; + GLint src[3]; + GLint op[3]; + GLint scale; + } Channel; + + typedef struct { + GLint enabled; + GLint binding; + GLint mode; + Channel rgb; + Channel a; + GLfloat color[4]; + } TexEnv; + + // MBX supports two texture units + TexEnv unit[2]; + GLint active; + int i, prev = -1; + + glGetIntegerv(GL_ACTIVE_TEXTURE, &active); + for (i = 0; i < 2; i++) + { + glActiveTexture(GL_TEXTURE0+i); + unit[i].enabled = glIsEnabled(GL_TEXTURE_2D); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &unit[i].binding); + glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &unit[i].mode); + glGetTexEnviv(GL_TEXTURE_ENV, GL_COMBINE_RGB, &unit[i].rgb.combine); + glGetTexEnviv(GL_TEXTURE_ENV, GL_SRC0_RGB, &unit[i].rgb.src[0]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_SRC1_RGB, &unit[i].rgb.src[1]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_SRC2_RGB, &unit[i].rgb.src[2]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_OPERAND0_RGB, &unit[i].rgb.op[0]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_OPERAND1_RGB, &unit[i].rgb.op[1]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_OPERAND2_RGB, &unit[i].rgb.op[2]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_RGB_SCALE, &unit[i].rgb.scale); + glGetTexEnviv(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, &unit[i].a.combine); + glGetTexEnviv(GL_TEXTURE_ENV, GL_SRC0_ALPHA, &unit[i].a.src[0]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_SRC1_ALPHA, &unit[i].a.src[1]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_SRC2_ALPHA, &unit[i].a.src[2]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, &unit[i].a.op[0]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, &unit[i].a.op[1]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, &unit[i].a.op[2]); + glGetTexEnviv(GL_TEXTURE_ENV, GL_ALPHA_SCALE, &unit[i].a.scale); + glGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &unit[i].color[0]); + + if (unit[i].enabled == 0) continue; + if (unit[i].mode != GL_COMBINE) continue; + + // PREVIOUS on unit 0 means PRIMARY_COLOR. + if (i == 0) + { + int j; + + for (j = 0; j < 3; j++) + { + if (unit[i].rgb.src[j] == GL_PREVIOUS) + unit[i].rgb.src[j] = GL_PRIMARY_COLOR; + if (unit[i].a.src[j] == GL_PREVIOUS) + unit[i].a.src[j] = GL_PRIMARY_COLOR; + } + } + + // If the value of COMBINE_RGB is MODULATE, only one of the two multiplicands can use an ALPHA operand. + rt_assert(!(unit[i].rgb.combine == GL_MODULATE && + (unit[i].rgb.op[0] == GL_SRC_ALPHA || unit[i].rgb.op[0] == GL_ONE_MINUS_SRC_ALPHA) && + (unit[i].rgb.op[1] == GL_SRC_ALPHA || unit[i].rgb.op[1] == GL_ONE_MINUS_SRC_ALPHA))); + + // If the value of COMBINE_RGB is INTERPOLATE and either SRC0 or SRC1 uses an ALPHA operand, SRC2 can not be CONSTANT or PRIMARY_COLOR or use an ALPHA operand. + rt_assert(!(unit[i].rgb.combine == GL_INTERPOLATE && + (unit[i].rgb.op[0] == GL_SRC_ALPHA || unit[i].rgb.op[0] == GL_ONE_MINUS_SRC_ALPHA || + unit[i].rgb.op[1] == GL_SRC_ALPHA || unit[i].rgb.op[1] == GL_ONE_MINUS_SRC_ALPHA) && + (unit[i].rgb.op[2] == GL_SRC_ALPHA || unit[i].rgb.op[2] == GL_ONE_MINUS_SRC_ALPHA || + unit[i].rgb.src[2] == GL_CONSTANT || unit[i].rgb.src[2] == GL_PRIMARY_COLOR))); + + // If the value of COMBINE_RGB is INTERPOLATE and SRC0 and SRC1 are CONSTANT or PRIMARY COLOR, SRC2 can not be CONSTANT or PRIMARY_COLOR or use an ALPHA operand. + rt_assert(!(unit[i].rgb.combine == GL_INTERPOLATE && + ((unit[i].rgb.src[0] == GL_CONSTANT && unit[i].rgb.src[1] == GL_CONSTANT) || + (unit[i].rgb.src[0] == GL_PRIMARY_COLOR && unit[i].rgb.src[1] == GL_PRIMARY_COLOR)) && + (unit[i].rgb.op[2] == GL_SRC_ALPHA || unit[i].rgb.op[2] == GL_ONE_MINUS_SRC_ALPHA || + unit[i].rgb.src[2] == GL_CONSTANT || unit[i].rgb.src[2] == GL_PRIMARY_COLOR))); + + // If the value of COMBINE_RGB is DOT3_RGB or DOT3_RGBA, only one of the sources can be PRIMARY_COLOR or use an ALPHA operand. + rt_assert(!((unit[i].rgb.combine == GL_DOT3_RGB || unit[i].rgb.combine == GL_DOT3_RGBA) && + (unit[i].rgb.src[0] == GL_PRIMARY_COLOR || unit[i].rgb.op[0] == GL_SRC_ALPHA || unit[i].rgb.op[0] == GL_ONE_MINUS_SRC_ALPHA) && + (unit[i].rgb.src[1] == GL_PRIMARY_COLOR || unit[i].rgb.op[1] == GL_SRC_ALPHA || unit[i].rgb.op[1] == GL_ONE_MINUS_SRC_ALPHA))); + + // If the value of COMBINE_RGB is SUBTRACT, SCALE_RGB must be 1.0. + rt_assert(!(unit[i].rgb.combine == GL_SUBTRACT && unit[i].rgb.scale != 1)); + + if (unit[i].rgb.combine != GL_DOT3_RGBA) + { + // If the value of COMBINE_ALPHA is MODULATE or INTERPOLATE, only one of the two multiplicands can be CONSTANT. + rt_assert(!(unit[i].a.combine == GL_MODULATE && unit[i].a.src[0] == GL_CONSTANT && unit[i].a.src[1] == GL_CONSTANT)); + rt_assert(!(unit[i].a.combine == GL_INTERPOLATE && (unit[i].a.src[0] == GL_CONSTANT || unit[i].a.src[1] == GL_CONSTANT) && unit[i].a.src[2] == GL_CONSTANT)); + + // If the value of COMBINE_ALPHA is SUBTRACT, SCALE_ALPHA must be 1.0. + rt_assert(!(unit[i].a.combine == GL_SUBTRACT && unit[i].a.scale != 1)); + } + + // The value of TEXTURE_ENV_COLOR must be the same for all texture units that CONSTANT is used on. + if (unit[i].rgb.src[0] == GL_CONSTANT || + (unit[i].rgb.src[1] == GL_CONSTANT && unit[i].rgb.combine != GL_REPLACE) || + (unit[i].rgb.src[2] == GL_CONSTANT && unit[i].rgb.combine == GL_INTERPOLATE) || + (unit[i].rgb.combine != GL_DOT3_RGBA && + (unit[i].a.src[0] == GL_CONSTANT || + (unit[i].a.src[1] == GL_CONSTANT && unit[i].a.combine != GL_REPLACE) || + (unit[i].a.src[2] == GL_CONSTANT && unit[i].a.combine == GL_INTERPOLATE)))) + { + if (prev >= 0) + rt_assert(!(unit[prev].color[0] != unit[i].color[0] || + unit[prev].color[1] != unit[i].color[1] || + unit[prev].color[2] != unit[i].color[2] || + unit[prev].color[3] != unit[i].color[3])); + prev = i; + } + } + + glActiveTexture(active); + glCheckError(); + #endif /* DEBUG */ +} diff --git a/GLImageProcessing/Debug.h b/GLImageProcessing/Debug.h new file mode 100644 index 0000000..5fecaf0 --- /dev/null +++ b/GLImageProcessing/Debug.h @@ -0,0 +1,83 @@ +/* + File: Debug.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef DEBUG_H +#define DEBUG_H + +#include +#include + +// These functions should only be used in Debug builds, because querying GL state affects +// performance. To use them, define ASSERT and DEBUG in your project's Debug configuration +// (i.e. with Xcode's GCC_PREPROCESSOR_DEFINITIONS Build setting.) +// By default, ASSERT and DEBUG are not defined, so these functions compile to no-ops. + +// Run-time assertion +#if ASSERT +#define rt_assert(expression) assert(expression) +#else +#define rt_assert(expression) +#endif + +// Catch run-time GL errors +#if DEBUG +#define glCheckError() { \ + GLenum err = glGetError(); \ + if (err != GL_NO_ERROR) { \ + fprintf(stderr, "glCheckError: %04x caught at %s:%u\n", err, __FILE__, __LINE__); \ + rt_assert(0); \ + } \ +} +#else +#define glCheckError() +#endif + + +// Debug utilities +void validateTexEnv(void); + +#endif /* DEBUG_H */ diff --git a/GLImageProcessing/GLImageProcessing-Info.plist b/GLImageProcessing/GLImageProcessing-Info.plist new file mode 100644 index 0000000..0aac977 --- /dev/null +++ b/GLImageProcessing/GLImageProcessing-Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarStyle + UIStatusBarStyleBlackTranslucent + + diff --git a/GLImageProcessing/GLImageProcessing.xcodeproj/project.pbxproj b/GLImageProcessing/GLImageProcessing.xcodeproj/project.pbxproj new file mode 100755 index 0000000..6f3e45c --- /dev/null +++ b/GLImageProcessing/GLImageProcessing.xcodeproj/project.pbxproj @@ -0,0 +1,330 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1811EF5D11D02C1D0068DA4C /* Image.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF5A11D02C1D0068DA4C /* Image.png */; }; + 182594EF11D11A54000B79F7 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 182594ED11D11A54000B79F7 /* MainWindow.xib */; }; + 18AD6BC611D57040005232E4 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BBF11D57040005232E4 /* Icon-72.png */; }; + 18AD6BC711D57040005232E4 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BC011D57040005232E4 /* Icon-Small-50.png */; }; + 18AD6BC811D57040005232E4 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BC111D57040005232E4 /* Icon-Small.png */; }; + 18AD6BC911D57040005232E4 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BC211D57040005232E4 /* Icon-Small@2x.png */; }; + 18AD6BCA11D57040005232E4 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BC311D57040005232E4 /* Icon.png */; }; + 18AD6BCB11D57040005232E4 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BC411D57040005232E4 /* Icon@2x.png */; }; + 18AD6BCC11D57040005232E4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BC511D57040005232E4 /* iTunesArtwork */; }; + 18AD6BCE11D57068005232E4 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6BCD11D57068005232E4 /* ReadMe.txt */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28FD14FD0DC6FC130079059D /* EAGLView.m */; }; + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; }; + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; }; + 9B72F2440FCC86E3008F116A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B72F2430FCC86E3008F116A /* ViewController.m */; }; + 9B72F2490FCC86EE008F116A /* Imaging.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B72F2460FCC86EE008F116A /* Imaging.c */; }; + 9B72F24A0FCC86EE008F116A /* Texture.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B72F2480FCC86EE008F116A /* Texture.m */; }; + 9B72F2560FCC87C4008F116A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B72F2550FCC87C4008F116A /* CoreGraphics.framework */; }; + 9B81DC9E0FF08151008DF9CA /* Debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B81DC9C0FF08151008DF9CA /* Debug.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1811EF5A11D02C1D0068DA4C /* Image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Image.png; path = images/Image.png; sourceTree = ""; }; + 182594EE11D11A54000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 18AD6BBF11D57040005232E4 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18AD6BC011D57040005232E4 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18AD6BC111D57040005232E4 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18AD6BC211D57040005232E4 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18AD6BC311D57040005232E4 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18AD6BC411D57040005232E4 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18AD6BC511D57040005232E4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 18AD6BCD11D57068005232E4 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* GLImageProcessing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLImageProcessing.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28FD14FC0DC6FC130079059D /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; + 28FD14FD0DC6FC130079059D /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = ""; }; + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 9B72F2420FCC86E3008F116A /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 9B72F2430FCC86E3008F116A /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 9B72F2450FCC86EE008F116A /* Imaging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Imaging.h; sourceTree = ""; }; + 9B72F2460FCC86EE008F116A /* Imaging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Imaging.c; sourceTree = ""; }; + 9B72F2470FCC86EE008F116A /* Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; + 9B72F2480FCC86EE008F116A /* Texture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Texture.m; sourceTree = ""; }; + 9B72F2550FCC87C4008F116A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 9B72F2770FCC87EA008F116A /* GLImageProcessing-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GLImageProcessing-Info.plist"; sourceTree = ""; }; + 9B81DC9C0FF08151008DF9CA /* Debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Debug.c; sourceTree = ""; }; + 9B81DC9D0FF08151008DF9CA /* Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Debug.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */, + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */, + 9B72F2560FCC87C4008F116A /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28FD14FC0DC6FC130079059D /* EAGLView.h */, + 28FD14FD0DC6FC130079059D /* EAGLView.m */, + 9B72F2420FCC86E3008F116A /* ViewController.h */, + 9B72F2430FCC86E3008F116A /* ViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GLImageProcessing.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 18AD6BCD11D57068005232E4 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 29B97316FDCFA39411CA2CEA /* main.m */, + 9B81DC9D0FF08151008DF9CA /* Debug.h */, + 9B81DC9C0FF08151008DF9CA /* Debug.c */, + 9B72F2450FCC86EE008F116A /* Imaging.h */, + 9B72F2460FCC86EE008F116A /* Imaging.c */, + 9B72F2470FCC86EE008F116A /* Texture.h */, + 9B72F2480FCC86EE008F116A /* Texture.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18AD6BBF11D57040005232E4 /* Icon-72.png */, + 18AD6BC011D57040005232E4 /* Icon-Small-50.png */, + 18AD6BC111D57040005232E4 /* Icon-Small.png */, + 18AD6BC211D57040005232E4 /* Icon-Small@2x.png */, + 18AD6BC311D57040005232E4 /* Icon.png */, + 18AD6BC411D57040005232E4 /* Icon@2x.png */, + 18AD6BC511D57040005232E4 /* iTunesArtwork */, + 182594ED11D11A54000B79F7 /* MainWindow.xib */, + 1811EF5A11D02C1D0068DA4C /* Image.png */, + 9B72F2770FCC87EA008F116A /* GLImageProcessing-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9B72F2550FCC87C4008F116A /* CoreGraphics.framework */, + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GLImageProcessing */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLImageProcessing" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GLImageProcessing; + productName = GLImageProcessing; + productReference = 1D6058910D05DD3D006BFB54 /* GLImageProcessing.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLImageProcessing" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GLImageProcessing */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1811EF5D11D02C1D0068DA4C /* Image.png in Resources */, + 182594EF11D11A54000B79F7 /* MainWindow.xib in Resources */, + 18AD6BC611D57040005232E4 /* Icon-72.png in Resources */, + 18AD6BC711D57040005232E4 /* Icon-Small-50.png in Resources */, + 18AD6BC811D57040005232E4 /* Icon-Small.png in Resources */, + 18AD6BC911D57040005232E4 /* Icon-Small@2x.png in Resources */, + 18AD6BCA11D57040005232E4 /* Icon.png in Resources */, + 18AD6BCB11D57040005232E4 /* Icon@2x.png in Resources */, + 18AD6BCC11D57040005232E4 /* iTunesArtwork in Resources */, + 18AD6BCE11D57068005232E4 /* ReadMe.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */, + 9B72F2440FCC86E3008F116A /* ViewController.m in Sources */, + 9B72F2490FCC86EE008F116A /* Imaging.c in Sources */, + 9B72F24A0FCC86EE008F116A /* Texture.m in Sources */, + 9B81DC9E0FF08151008DF9CA /* Debug.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 182594ED11D11A54000B79F7 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 182594EE11D11A54000B79F7 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "GLImageProcessing-Info.plist"; + PRODUCT_NAME = GLImageProcessing; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "GLImageProcessing-Info.plist"; + PRODUCT_NAME = GLImageProcessing; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_PREPROCESSOR_DEFINITIONS = ( + ASSERT, + DEBUG, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_PREPROCESSOR_DEFINITIONS = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLImageProcessing" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLImageProcessing" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GLImageProcessing/Imaging.c b/GLImageProcessing/Imaging.c new file mode 100644 index 0000000..0bfaa4e --- /dev/null +++ b/GLImageProcessing/Imaging.c @@ -0,0 +1,815 @@ +/* + File: Imaging.c + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +// +// Simple 2D image processing using OpenGL ES1.1 +// +// The key concepts here are described at +// http://www.graficaobscura.com/interp/index.html +// http://www.graficaobscura.com/matrix/index.html +// +// The only tricky part is how to process inputs outside of [0..1] in the fixed-function pipeline. +// Simple algebra provides a solution for extrapolation to [0..2]: +// +// lerp = Src*t + Dst*(1-t), where (Src, Dst, t) [0..1] +// if t = 2, then +// lerp = Src*(2t) + Dst*(1-2t) +// = 2(Src*t + Dst*(0.5-t)) +// +// Now, the inputs (Src, Dst, t) are inside [0..1], and the final multiply by 2 can be done with +// TexEnv. Extrapolation by values larger than 2 can be handled by iteration. +// +// With that solved, the rest of the problem is simply mapping math operations to TexEnv state. +// Equations that are too complex to fit in the available texture units have to be broken apart +// into multiple passes. In that case, a scratch FBO is used to store intermediate results. +// +// This sample demonstrates mapping simple filters like Brightness, Contrast, Saturation, +// Hue rotation, and Sharpness to TexEnv. Additional filters such as Convolution, Invert, +// Sepia, etc can be similarly implemented. +// +// For details on the available TexEnv COMBINE operators, see the ES1.1 specification, or +// the equivalent desktop GL extensions: +// http://www.opengl.org/registry/specs/ARB/texture_env_combine.txt +// http://www.opengl.org/registry/specs/ARB/texture_env_dot3.txt +// +// Note: the PowerVR MBX does not support all possible COMBINE state permutations. A debug utility +// is used here to validate the TexEnv state against known hardware errata. +// + + +#include +#include +#include +#include +#include "Texture.h" + + +// Information about the GL renderer +RendererInfo renderer; +// Framebuffer objects +GLuint SystemFBO, DegenFBO, ScratchFBO; +// Images used for filtering +Image Input, Half, Degen, Scratch; +// Geometry for a fullscreen quad +V2fT2f fullquad[4] = { + { 0, 0, 0, 0 }, + { 1, 0, 1, 0 }, + { 0, 1, 0, 1 }, + { 1, 1, 1, 1 }, +}; +// Geometry for a fullscreen quad, flipping texcoords upside down +V2fT2f flipquad[4] = { + { 0, 0, 0, 1 }, + { 1, 0, 1, 1 }, + { 0, 1, 0, 0 }, + { 1, 1, 1, 0 }, +}; + + +// The following filters change the TexEnv state in various ways. +// To reduce state change overhead, the convention adopted here is +// that each filter is responsible for setting up common state, and +// restoring uncommon state to the default. +// +// Common state for this application is defined as: +// GL_TEXTURE_ENV_MODE +// GL_COMBINE_RGB, GL_COMBINE_ALPHA +// GL_SRC[012]_RGB, GL_SRC[012]_ALPHA +// GL_TEXTURE_ENV_COLOR +// +// Uncommon state for this application is defined as: +// GL_OPERAND[012]_RGB, GL_OPERAND[012]_ALPHA +// GL_RGB_SCALE, GL_ALPHA_SCALE +// +// For all filters, the texture's alpha channel is passed through unchanged. +// If you need the alpha channel for compositing purposes, be mindful of +// premultiplication that may have been performed by your image loader. + + +static void brightness(V2fT2f *quad, float t) // t [0..2] +{ + // One pass using one unit: + // brightness < 1.0 biases towards black + // brightness > 1.0 biases towards white + // + // Note: this additive definition of brightness is + // different than what matrix-based adjustment produces, + // where the brightness factor is a scalar multiply. + // + // A +/-1 bias will produce the full range from black to white, + // whereas the scalar multiply can never reach full white. + + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + if (t > 1.0f) + { + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); + glColor4f(t-1, t-1, t-1, t-1); + } + else + { + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT); + glColor4f(1-t, 1-t, 1-t, 1-t); + } + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + + +static void contrast(V2fT2f *quad, float t) // t [0..2] +{ + GLfloat h = t*0.5f; + + // One pass using two units: + // contrast < 1.0 interpolates towards grey + // contrast > 1.0 extrapolates away from grey + // + // Here, the general extrapolation 2*(Src*t + Dst*(0.5-t)) + // can be simplified, because Dst is a constant (grey). + // That results in: 2*(Src*t + 0.25 - 0.5*t) + // + // Unit0 calculates Src*t + // Unit1 adds 0.25 - 0.5*t + // Since 0.5*t will be in [0..0.5], it can be biased up and the addition done in signed space. + + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 2); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + + glColor4f(h, h, h, 0.75 - 0.5 * h); // 2x extrapolation + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Restore state + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1); + glActiveTexture(GL_TEXTURE0); +} + + +static void greyscale(V2fT2f *quad, float t) // t = 1 for standard perceptual weighting +{ + GLfloat lerp[4] = { 1.0, 1.0, 1.0, 0.5 }; + GLfloat avrg[4] = { .667, .667, .667, 0.5 }; // average + GLfloat prcp[4] = { .646, .794, .557, 0.5 }; // perceptual NTSC + GLfloat dot3[4] = { prcp[0]*t+avrg[0]*(1-t), prcp[1]*t+avrg[1]*(1-t), prcp[2]*t+avrg[2]*(1-t), 0.5 }; + + // One pass using two units: + // Unit 0 scales and biases into [0.5..1.0] + // Unit 1 dot products with perceptual weights + + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR, lerp); + + // Note: we prefer to dot product with primary color, because + // the constant color is stored in limited precision on MBX + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + + glColor4f(dot3[0], dot3[1], dot3[2], dot3[3]); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Restore state + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); +} + + +static void extrapolate(V2fT2f *quad, float t) // t [0..2] +{ + int i; + + // t < 1.0 interpolates towards degenerate image + // t > 1.0 extrapolates away from degenerate image + // + // Unlike the simpler filters, extrapolation from an arbitrary image + // requires two passes to implement 2*(Src*t + Dst(0.5-t)). + // + // The extrapolation works in both directions, but when t <= 1.0f, + // the interpolation can be done in a single pass, which is faster. + // + // The degenerate image to extrapolate from is generated + // outside of this function. It can be cached for a static image, + // or regenerated every frame for dynamic content. + + if (t <= 1.0f) + { + // One pass using two units: + // Unit 0 samples the input image + // Unit 1 interpolates towards the degenerate image + + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + + glClientActiveTexture(GL_TEXTURE1); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, Degen.texID); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + glColor4f(0.0, 0.0, 0.0, 1.0f-t); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Restore state + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, Half.texID); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + } + else + { + GLint fbo, tex, viewport[4], blend; + float h = t*0.5f; + V2fT2f flipquad[4]; + + for (i = 0; i < 4; i++) + { + flipquad[i].s = quad[i].s; + flipquad[i].t = quad[3-i].t; + } + + // Push state + glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &fbo); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex); + glGetIntegerv(GL_VIEWPORT, viewport); + glGetIntegerv(GL_BLEND, &blend); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, ScratchFBO); + glViewport(0, 0, Scratch.wide*Scratch.s, Scratch.high*Scratch.t); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, Degen.texID); + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + + // Note: we prefer to sample 0.5 from a texture, because + // the constant color is stored in limited precision on MBX + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, Half.texID); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + if (h < 0.5) + { + float bias = 0.5-h; + + // First pass: 0.5 + degenerate * bias; + glColor4f(bias, bias, bias, 1.0); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); + } + else + { + float bias = h-0.5; + + // First pass: 0.5 - degenerate * bias; + glColor4f(bias, bias, bias, 1.0); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT); + } + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Second pass: 2.0 * (Src * h + first - 0.5) + glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + if (blend) glEnable(GL_BLEND); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glClientActiveTexture(GL_TEXTURE1); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindTexture(GL_TEXTURE_2D, Scratch.texID); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 2); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glColor4f(h, h, h, 1.0); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Restore state + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1); + glBindTexture(GL_TEXTURE_2D, Half.texID); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + } +} + + +// Matrix Utilities for Hue rotation +static void matrixmult(float a[4][4], float b[4][4], float c[4][4]) +{ + int x, y; + float temp[4][4]; + + for(y=0; y<4; y++) + for(x=0; x<4; x++) + temp[y][x] = b[y][0] * a[0][x] + b[y][1] * a[1][x] + b[y][2] * a[2][x] + b[y][3] * a[3][x]; + for(y=0; y<4; y++) + for(x=0; x<4; x++) + c[y][x] = temp[y][x]; +} + + +static void xrotatemat(float mat[4][4], float rs, float rc) +{ + mat[0][0] = 1.0; + mat[0][1] = 0.0; + mat[0][2] = 0.0; + mat[0][3] = 0.0; + + mat[1][0] = 0.0; + mat[1][1] = rc; + mat[1][2] = rs; + mat[1][3] = 0.0; + + mat[2][0] = 0.0; + mat[2][1] = -rs; + mat[2][2] = rc; + mat[2][3] = 0.0; + + mat[3][0] = 0.0; + mat[3][1] = 0.0; + mat[3][2] = 0.0; + mat[3][3] = 1.0; + } + + +static void yrotatemat(float mat[4][4], float rs, float rc) +{ + mat[0][0] = rc; + mat[0][1] = 0.0; + mat[0][2] = -rs; + mat[0][3] = 0.0; + + mat[1][0] = 0.0; + mat[1][1] = 1.0; + mat[1][2] = 0.0; + mat[1][3] = 0.0; + + mat[2][0] = rs; + mat[2][1] = 0.0; + mat[2][2] = rc; + mat[2][3] = 0.0; + + mat[3][0] = 0.0; + mat[3][1] = 0.0; + mat[3][2] = 0.0; + mat[3][3] = 1.0; +} + + +static void zrotatemat(float mat[4][4], float rs, float rc) +{ + mat[0][0] = rc; + mat[0][1] = rs; + mat[0][2] = 0.0; + mat[0][3] = 0.0; + + mat[1][0] = -rs; + mat[1][1] = rc; + mat[1][2] = 0.0; + mat[1][3] = 0.0; + + mat[2][0] = 0.0; + mat[2][1] = 0.0; + mat[2][2] = 1.0; + mat[2][3] = 0.0; + + mat[3][0] = 0.0; + mat[3][1] = 0.0; + mat[3][2] = 0.0; + mat[3][3] = 1.0; +} + + +static void huematrix(GLfloat mat[4][4], float angle) +{ + float mag, rot[4][4]; + float xrs, xrc; + float yrs, yrc; + float zrs, zrc; + + // Rotate the grey vector into positive Z + mag = sqrt(2.0); + xrs = 1.0/mag; + xrc = 1.0/mag; + xrotatemat(mat, xrs, xrc); + mag = sqrt(3.0); + yrs = -1.0/mag; + yrc = sqrt(2.0)/mag; + yrotatemat(rot, yrs, yrc); + matrixmult(rot, mat, mat); + + // Rotate the hue + zrs = sin(angle); + zrc = cos(angle); + zrotatemat(rot, zrs, zrc); + matrixmult(rot, mat, mat); + + // Rotate the grey vector back into place + yrotatemat(rot, -yrs, yrc); + matrixmult(rot, mat, mat); + xrotatemat(rot, -xrs, xrc); + matrixmult(rot, mat, mat); +} + + +static void hue(V2fT2f *quad, float t) // t [0..2] == [-180..180] degrees +{ + GLfloat mat[4][4]; + GLfloat lerp[4] = { 1.0, 1.0, 1.0, 0.5 }; + + // Color matrix rotation can be expressed as three dot products + // Each DOT3 needs inputs prescaled to [0.5..1.0] + + // Construct 3x3 matrix + huematrix(mat, (t-1.0)*M_PI); + + // Prescale matrix weights + mat[0][0] *= 0.5; mat[0][0] += 0.5; + mat[0][1] *= 0.5; mat[0][1] += 0.5; + mat[0][2] *= 0.5; mat[0][2] += 0.5; + mat[0][3] = 1.0; + + mat[1][0] *= 0.5; mat[1][0] += 0.5; + mat[1][1] *= 0.5; mat[1][1] += 0.5; + mat[1][2] *= 0.5; mat[1][2] += 0.5; + mat[1][3] = 1.0; + + mat[2][0] *= 0.5; mat[2][0] += 0.5; + mat[2][1] *= 0.5; mat[2][1] += 0.5; + mat[2][2] *= 0.5; mat[2][2] += 0.5; + mat[2][3] = 1.0; + + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR, lerp); + + // Note: we prefer to dot product with primary color, because + // the constant color is stored in limited precision on MBX + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + + // Red channel + glColorMask(1,0,0,0); + glColor4f(mat[0][0], mat[0][1], mat[0][2], mat[0][3]); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Green channel + glColorMask(0,1,0,0); + glColor4f(mat[1][0], mat[1][1], mat[1][2], mat[1][3]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Blue channel + glColorMask(0,0,1,0); + glColor4f(mat[2][0], mat[2][1], mat[2][2], mat[2][3]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Restore state + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glColorMask(1,1,1,1); +} + + +static void blur(V2fT2f *quad, float t) // t = 1 +{ + GLint tex; + V2fT2f tmpquad[4]; + float offw = t / Input.wide; + float offh = t / Input.high; + int i; + + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex); + + // Three pass small blur, using rotated pattern to sample 17 texels: + // + // .\/.. + // ./\\/ + // \/X/\ rotated samples filter across texel corners + // /\\/. + // ../\. + + // Pass one: center nearest sample + glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Pass two: accumulate two rotated linear samples + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + for (i = 0; i < 4; i++) + { + tmpquad[i].x = quad[i].s + 1.5 * offw; + tmpquad[i].y = quad[i].t + 0.5 * offh; + tmpquad[i].s = quad[i].s - 1.5 * offw; + tmpquad[i].t = quad[i].t - 0.5 * offh; + } + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glClientActiveTexture(GL_TEXTURE1); + glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindTexture(GL_TEXTURE_2D, tex); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR); + + glColor4f(0.5, 0.5, 0.5, 2.0/5); + validateTexEnv(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Pass three: accumulate two rotated linear samples + for (i = 0; i < 4; i++) + { + tmpquad[i].x = quad[i].s - 0.5 * offw; + tmpquad[i].y = quad[i].t + 1.5 * offh; + tmpquad[i].s = quad[i].s + 0.5 * offw; + tmpquad[i].t = quad[i].t - 1.5 * offh; + } + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Restore state + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, Half.texID); + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + glActiveTexture(GL_TEXTURE0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glDisable(GL_BLEND); +} + + +void drawGL(int wide, int high, float val, int mode) +{ + static int prevmode = -1; + typedef void (*procfunc)(V2fT2f *, float); + + typedef struct { + procfunc func; + procfunc degen; + } Filter; + + const Filter filter[] = { + { brightness }, + { contrast }, + { extrapolate, greyscale }, + { hue }, + { extrapolate, blur }, // The blur could be exaggerated by downsampling to half size + }; + #define NUM_FILTERS (sizeof(filter)/sizeof(filter[0])) + rt_assert(mode < NUM_FILTERS); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, wide, 0, high, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glScalef(wide, high, 1); + + glBindTexture(GL_TEXTURE_2D, Input.texID); + + if (prevmode != mode) + { + prevmode = mode; + if (filter[mode].degen) + { + // Cache degenerate image, potentially a different size than the system framebuffer + glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO); + glViewport(0, 0, Degen.wide*Degen.s, Degen.high*Degen.t); + // The entire framebuffer won't be written to if the image was padded to POT. + // In this case, clearing is a performance win on TBDR systems. + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + filter[mode].degen(fullquad, 1.0); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO); + } + } + + // Render filtered image to system framebuffer + glViewport(0, 0, wide, high); + filter[mode].func(flipquad, val); + glCheckError(); +} + + +void initGL(void) +{ + int i; + + // Query renderer capabilities that affect this app's rendering paths + renderer.extension[APPLE_texture_2D_limited_npot] = + (0 != strstr((char *)glGetString(GL_EXTENSIONS), "GL_APPLE_texture_2D_limited_npot")); + renderer.extension[IMG_texture_format_BGRA8888] = + (0 != strstr((char *)glGetString(GL_EXTENSIONS), "GL_IMG_texture_format_BGRA8888")); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer.maxTextureSize); + + // Constant state for the lifetime of the app-- position and unit0 are always used + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnable(GL_TEXTURE_2D); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + // Load image into texture + loadTexture("Image.png", &Input, &renderer); + + // Modify quad texcoords to match (possibly padded) image + for (i = 0; i < 4; i++) + { + fullquad[i].s *= Input.s; + fullquad[i].t *= Input.t; + flipquad[i].s *= Input.s; + flipquad[i].t *= Input.t; + } + + // Create 1x1 for default constant texture + // To enable a texture unit, a valid texture has to be bound even if the combine modes do not access it + GLubyte half[4] = { 0x80, 0x80, 0x80, 0x80 }; + glActiveTexture(GL_TEXTURE1); + glGenTextures(1, &Half.texID); + Half.wide = Half.high = 1; + Half.s = Half.t = 1.0; + glBindTexture(GL_TEXTURE_2D, Half.texID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, half); + glActiveTexture(GL_TEXTURE0); + + // Remember the FBO being used for the display framebuffer + glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO); + + // Create scratch textures and FBOs + glGenTextures(1, &Degen.texID); + Degen.wide = Input.wide; + Degen.high = Input.high; + Degen.s = Input.s; + Degen.t = Input.t; + glBindTexture(GL_TEXTURE_2D, Degen.texID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Degen.wide, Degen.high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glGenFramebuffersOES(1, &DegenFBO); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO); + glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, Degen.texID, 0); + rt_assert(GL_FRAMEBUFFER_COMPLETE_OES == glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + + glGenTextures(1, &Scratch.texID); + Scratch.wide = Input.wide; + Scratch.high = Input.high; + Scratch.s = Input.s; + Scratch.t = Input.t; + glBindTexture(GL_TEXTURE_2D, Scratch.texID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Scratch.wide, Scratch.high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glGenFramebuffersOES(1, &ScratchFBO); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, ScratchFBO); + glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, Scratch.texID, 0); + rt_assert(GL_FRAMEBUFFER_COMPLETE_OES == glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO); + + glCheckError(); +} diff --git a/GLImageProcessing/Imaging.h b/GLImageProcessing/Imaging.h new file mode 100644 index 0000000..98ce9fe --- /dev/null +++ b/GLImageProcessing/Imaging.h @@ -0,0 +1,86 @@ +/* + File: Imaging.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef IMAGING_H +#define IMAGING_H + +#include +#include +#include "Debug.h" + +#define MAX_FILTER_RADIUS 2 + + +enum { + APPLE_texture_2D_limited_npot, + IMG_texture_format_BGRA8888, + NUM_EXTENSIONS +}; + +// Renderer capabilities that affect this application +typedef struct { + GLboolean extension[NUM_EXTENSIONS]; + GLint maxTextureSize; +} RendererInfo; + +// A simple 2D image +typedef struct { + GLuint texID; + GLsizei wide, high; // Texture dimensions + GLfloat s, t; // Texcoords to show full image, taking any POT padding into account +} Image; + +// A simple vertex format +typedef struct { + GLfloat x, y, s, t; +} V2fT2f; + + +void initGL(void); +void drawGL(int wide, int high, float val, int mode); + +#endif /* IMAGING_H */ diff --git a/GLImageProcessing/ReadMe.txt b/GLImageProcessing/ReadMe.txt new file mode 100644 index 0000000..14e8873 --- /dev/null +++ b/GLImageProcessing/ReadMe.txt @@ -0,0 +1,54 @@ +### GLImageProcessing ### + +================================================================================ +DESCRIPTION: + +The GLImageProcessing sample application demonstrates how to implement simple image processing filters (Brightness, Contrast, Saturation, Hue rotation, Sharpness) using OpenGL ES1.1. The sample also shows how to create simple procedural button icons using CoreGraphics. + +By looking at the code you'll see how to set up an OpenGL ES view and use it for applying a filter to a texture. The application creates a texture from an image loaded from disk. It pads the image to a power of two, if required by the GPU. + +The Debug configuration in the Xcode project defines DEBUG and ASSERT preprocessor macros, to enable additional error checking. + +To use this sample, open it in Xcode and click Build and Go. Use the slider to control the current filter. Only a single filter is applied at a time. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +ViewController.h +ViewController.m +Simple controller that redraws the view in response to UI events. + +EAGLView.h +EAGLView.m +Convenience class that wraps the CAEAGLLayer from CoreAnimation into a UIView subclass. + +Debug.h +Debug.c +Debug utilities to catch run-time GL errors and validate TexEnv state. + +Imaging.h +Imaging.c +Simple 2D image processing using OpenGL ES1.1. + +main.m +The main entry point for the GLImageProcessing application. + +Texture.h +Texture.m +Simple image loader to create 2D OpenGL textures using CGImage. + +Image.png +The screen-sized image loaded as a texture. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/GLImageProcessing/Texture.h b/GLImageProcessing/Texture.h new file mode 100644 index 0000000..99bab4e --- /dev/null +++ b/GLImageProcessing/Texture.h @@ -0,0 +1,56 @@ +/* + File: Texture.h + Abstract: + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef TEXTURE_H +#define TEXTURE_H + +#include "Imaging.h" + + +void loadTexture(const char *name, Image *img, RendererInfo *renderer); + +#endif /* TEXTURE_H */ \ No newline at end of file diff --git a/GLImageProcessing/Texture.m b/GLImageProcessing/Texture.m new file mode 100644 index 0000000..af09ce3 --- /dev/null +++ b/GLImageProcessing/Texture.m @@ -0,0 +1,240 @@ +/* + File: Texture.m + Abstract: n/a + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "Texture.h" + + +static unsigned int nextPOT(unsigned int x) +{ + x = x - 1; + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >>16); + return x + 1; +} + + +// This is not a fully generalized image loader. It is an example of how to use +// CGImage to directly access decompressed image data. Only the most commonly +// used image formats are supported. It will be necessary to expand this code +// to account for other uses, for example cubemaps or compressed textures. +// +// If the image format is supported, this loader will Gen a OpenGL 2D texture object +// and upload texels from it, padding to POT if needed. For image processing purposes, +// border pixels are also replicated here to ensure proper filtering during e.g. blur. +// +// The caller of this function is responsible for deleting the GL texture object. +void loadTexture(const char *name, Image *img, RendererInfo *renderer) +{ + GLuint texID = 0, components, x, y; + GLuint imgWide, imgHigh; // Real image size + GLuint rowBytes, rowPixels; // Image size padded by CGImage + GLuint POTWide, POTHigh; // Image size padded to next power of two + CGBitmapInfo info; // CGImage component layout info + CGColorSpaceModel colormodel; // CGImage colormodel (RGB, CMYK, paletted, etc) + GLenum internal, format; + GLubyte *pixels, *temp = NULL; + + CGImageRef CGImage = [UIImage imageNamed:[NSString stringWithUTF8String:name]].CGImage; + rt_assert(CGImage); + if (!CGImage) + return; + + // Parse CGImage info + info = CGImageGetBitmapInfo(CGImage); // CGImage may return pixels in RGBA, BGRA, or ARGB order + colormodel = CGColorSpaceGetModel(CGImageGetColorSpace(CGImage)); + size_t bpp = CGImageGetBitsPerPixel(CGImage); + if (bpp < 8 || bpp > 32 || (colormodel != kCGColorSpaceModelMonochrome && colormodel != kCGColorSpaceModelRGB)) + { + // This loader does not support all possible CGImage types, such as paletted images + CGImageRelease(CGImage); + return; + } + components = bpp>>3; + rowBytes = CGImageGetBytesPerRow(CGImage); // CGImage may pad rows + rowPixels = rowBytes / components; + imgWide = CGImageGetWidth(CGImage); + imgHigh = CGImageGetHeight(CGImage); + img->wide = rowPixels; + img->high = imgHigh; + img->s = (float)imgWide / rowPixels; + img->t = 1.0; + + // Choose OpenGL format + switch(bpp) + { + default: + rt_assert(0 && "Unknown CGImage bpp"); + case 32: + { + internal = GL_RGBA; + switch(info & kCGBitmapAlphaInfoMask) + { + case kCGImageAlphaPremultipliedFirst: + case kCGImageAlphaFirst: + case kCGImageAlphaNoneSkipFirst: + format = GL_BGRA; + break; + default: + format = GL_RGBA; + } + break; + } + case 24: + internal = format = GL_RGB; + break; + case 16: + internal = format = GL_LUMINANCE_ALPHA; + break; + case 8: + internal = format = GL_LUMINANCE; + break; + } + + // Get a pointer to the uncompressed image data. + // + // This allows access to the original (possibly unpremultiplied) data, but any manipulation + // (such as scaling) has to be done manually. Contrast this with drawing the image + // into a CGBitmapContext, which allows scaling, but always forces premultiplication. + CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(CGImage)); + rt_assert(data); + pixels = (GLubyte *)CFDataGetBytePtr(data); + rt_assert(pixels); + + // If the CGImage component layout isn't compatible with OpenGL, fix it. + // On the device, CGImage will generally return BGRA or RGBA. + // On the simulator, CGImage may return ARGB, depending on the file format. + if (format == GL_BGRA) + { + uint32_t *p = (uint32_t *)pixels; + int i, num = img->wide * img->high; + + if ((info & kCGBitmapByteOrderMask) != kCGBitmapByteOrder32Host) + { + // Convert from ARGB to BGRA + for (i = 0; i < num; i++) + p[i] = (p[i] << 24) | ((p[i] & 0xFF00) << 8) | ((p[i] >> 8) & 0xFF00) | (p[i] >> 24); + } + + // All current iPhoneOS devices support BGRA via an extension. + if (!renderer->extension[IMG_texture_format_BGRA8888]) + { + format = GL_RGBA; + + // Convert from BGRA to RGBA + for (i = 0; i < num; i++) + #if __LITTLE_ENDIAN__ + p[i] = ((p[i] >> 16) & 0xFF) | (p[i] & 0xFF00FF00) | ((p[i] & 0xFF) << 16); + #else + p[i] = ((p[i] & 0xFF00) << 16) | (p[i] & 0xFF00FF) | ((p[i] >> 16) & 0xFF00); + #endif + } + } + + // Determine if we need to pad this image to a power of two. + // There are multiple ways to deal with NPOT images on renderers that only support POT: + // 1) scale down the image to POT size. Loses quality. + // 2) pad up the image to POT size. Wastes memory. + // 3) slice the image into multiple POT textures. Requires more rendering logic. + // + // We are only dealing with a single image here, and pick 2) for simplicity. + // + // If you prefer 1), you can use CoreGraphics to scale the image into a CGBitmapContext. + POTWide = nextPOT(img->wide); + POTHigh = nextPOT(img->high); + + if (!renderer->extension[APPLE_texture_2D_limited_npot] && (img->wide != POTWide || img->high != POTHigh)) + { + GLuint dstBytes = POTWide * components; + GLubyte *temp = (GLubyte *)malloc(dstBytes * POTHigh); + + for (y = 0; y < img->high; y++) + memcpy(&temp[y*dstBytes], &pixels[y*rowBytes], rowBytes); + + img->s *= (float)img->wide/POTWide; + img->t *= (float)img->high/POTHigh; + img->wide = POTWide; + img->high = POTHigh; + pixels = temp; + rowBytes = dstBytes; + } + + // For filters that sample texel neighborhoods (like blur), we must replicate + // the edge texels of the original input, to simulate CLAMP_TO_EDGE. + { + GLuint replicatew = MIN(MAX_FILTER_RADIUS, img->wide-imgWide); + GLuint replicateh = MIN(MAX_FILTER_RADIUS, img->high-imgHigh); + GLuint imgRow = imgWide * components; + + for (y = 0; y < imgHigh; y++) + for (x = 0; x < replicatew; x++) + memcpy(&pixels[y*rowBytes+imgRow+x*components], &pixels[y*rowBytes+imgRow-components], components); + for (y = imgHigh; y < imgHigh+replicateh; y++) + memcpy(&pixels[y*rowBytes], &pixels[(imgHigh-1)*rowBytes], imgRow+replicatew*components); + } + + if (img->wide <= renderer->maxTextureSize && img->high <= renderer->maxTextureSize) + { + glGenTextures(1, &texID); + glBindTexture(GL_TEXTURE_2D, texID); + // Set filtering parameters appropriate for this application (image processing on screen-aligned quads.) + // Depending on your needs, you may prefer linear filtering, or mipmap generation. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, internal, img->wide, img->high, 0, format, GL_UNSIGNED_BYTE, pixels); + } + + if (temp) free(temp); + CFRelease(data); + CGImageRelease(CGImage); + img->texID = texID; +} diff --git a/GLImageProcessing/en.lproj/MainWindow.xib b/GLImageProcessing/en.lproj/MainWindow.xib new file mode 100644 index 0000000..f0d09d7 --- /dev/null +++ b/GLImageProcessing/en.lproj/MainWindow.xib @@ -0,0 +1,408 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + 1290 + {{0, 431}, {320, 49}} + + + 3 + MCAwAA + + NO + + YES + + Brightness + + + + 1 + Contrast + + + + 2 + Saturation + + + + 3 + Hue + + + + 4 + Sharpness + + + + + + + 1316 + {{18, 394}, {284, 23}} + + NO + YES + YES + 0 + 0 + 1.000000e+00 + 2.000000e+00 + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + + 1 + + YES + + + + 2 + + + 1 + + + + + + YES + + + sliderAction: + + + 13 + + 19 + + + + delegate + + + + 34 + + + + tabBar + + + + 36 + + + + slider + + + + 37 + + + + tabBar + + + + 38 + + + + view + + + + 39 + + + + slider + + + + 40 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 2 + + + YES + + + + + + + + 17 + + + YES + + + + + 24 + + + YES + + + + + + + + + + 25 + + + + + 28 + + + + + 29 + + + + + 30 + + + + + 26 + + + + + 18 + + + + + 11 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.CustomClassName + 11.IBEditorWindowLastContentRect + 11.IBPluginDependency + 17.CustomClassName + 17.IBPluginDependency + 18.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 24.IBPluginDependency + 25.IBPluginDependency + 26.IBPluginDependency + 28.IBPluginDependency + 29.IBPluginDependency + 30.IBPluginDependency + + + YES + UIApplication + UIResponder + ViewController + {{0, 365}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{469, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 40 + + + + YES + + EAGLView + UIView + + YES + + YES + slider + tabBar + + + YES + UISlider + UITabBar + + + + IBProjectSource + Classes/EAGLView.h + + + + ViewController + UIViewController + + sliderAction: + id + + + YES + + YES + slider + tabBar + + + YES + UISlider + UITabBar + + + + IBProjectSource + ViewController.h + + + + + 0 + ImageProc1.xcodeproj + 3 + 3.0 + + diff --git a/GLImageProcessing/images/Icon-72.png b/GLImageProcessing/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GLImageProcessing/images/Icon-72.png differ diff --git a/GLImageProcessing/images/Icon-Small-50.png b/GLImageProcessing/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GLImageProcessing/images/Icon-Small-50.png differ diff --git a/GLImageProcessing/images/Icon-Small.png b/GLImageProcessing/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GLImageProcessing/images/Icon-Small.png differ diff --git a/GLImageProcessing/images/Icon-Small@2x.png b/GLImageProcessing/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GLImageProcessing/images/Icon-Small@2x.png differ diff --git a/GLImageProcessing/images/Icon.png b/GLImageProcessing/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GLImageProcessing/images/Icon.png differ diff --git a/GLImageProcessing/images/Icon@2x.png b/GLImageProcessing/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GLImageProcessing/images/Icon@2x.png differ diff --git a/GLImageProcessing/images/Image.png b/GLImageProcessing/images/Image.png new file mode 100644 index 0000000..c49a57d Binary files /dev/null and b/GLImageProcessing/images/Image.png differ diff --git a/GLImageProcessing/images/iTunesArtwork b/GLImageProcessing/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GLImageProcessing/images/iTunesArtwork differ diff --git a/GLImageProcessing/main.m b/GLImageProcessing/main.m new file mode 100644 index 0000000..44cc957 --- /dev/null +++ b/GLImageProcessing/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: n/a + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GLPaint.zip b/GLPaint.zip new file mode 100644 index 0000000..29fc5f9 Binary files /dev/null and b/GLPaint.zip differ diff --git a/GLPaint/Classes/AppController.h b/GLPaint/Classes/AppController.h new file mode 100644 index 0000000..212781b --- /dev/null +++ b/GLPaint/Classes/AppController.h @@ -0,0 +1,68 @@ +/* + File: AppController.h + Abstract: The UIApplication delegate class, which is the central controller of + the application. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +//CLASS INTERFACES: + +@class PaintingWindow; +@class PaintingView; +@class SoundEffect; + +@interface AppController : NSObject +{ + PaintingWindow *window; + PaintingView *drawingView; + + SoundEffect *erasingSound; + SoundEffect *selectSound; + CFTimeInterval lastTime; +} + +@property (nonatomic, retain) IBOutlet PaintingWindow *window; +@property (nonatomic, retain) IBOutlet PaintingView *drawingView; + +@end diff --git a/GLPaint/Classes/AppController.m b/GLPaint/Classes/AppController.m new file mode 100644 index 0000000..cb5ac2a --- /dev/null +++ b/GLPaint/Classes/AppController.m @@ -0,0 +1,228 @@ +/* + File: AppController.m + Abstract: The UIApplication delegate class, which is the central controller of + the application. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppController.h" +#import "PaintingView.h" +#import "SoundEffect.h" + +//CONSTANTS: + +#define kPaletteHeight 30 +#define kPaletteSize 5 +#define kMinEraseInterval 0.5 + +// Padding for margins +#define kLeftMargin 10.0 +#define kTopMargin 10.0 +#define kRightMargin 10.0 + +//FUNCTIONS: +/* + HSL2RGB Converts hue, saturation, luminance values to the equivalent red, green and blue values. + For details on this conversion, see Fundamentals of Interactive Computer Graphics by Foley and van Dam (1982, Addison and Wesley) + You can also find HSL to RGB conversion algorithms by searching the Internet. + See also http://en.wikipedia.org/wiki/HSV_color_space for a theoretical explanation + */ +static void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB) +{ + float temp1, + temp2; + float temp[3]; + int i; + + // Check for saturation. If there isn't any just return the luminance value for each, which results in gray. + if(s == 0.0) { + if(outR) + *outR = l; + if(outG) + *outG = l; + if(outB) + *outB = l; + return; + } + + // Test for luminance and compute temporary values based on luminance and saturation + if(l < 0.5) + temp2 = l * (1.0 + s); + else + temp2 = l + s - l * s; + temp1 = 2.0 * l - temp2; + + // Compute intermediate values based on hue + temp[0] = h + 1.0 / 3.0; + temp[1] = h; + temp[2] = h - 1.0 / 3.0; + + for(i = 0; i < 3; ++i) { + + // Adjust the range + if(temp[i] < 0.0) + temp[i] += 1.0; + if(temp[i] > 1.0) + temp[i] -= 1.0; + + + if(6.0 * temp[i] < 1.0) + temp[i] = temp1 + (temp2 - temp1) * 6.0 * temp[i]; + else { + if(2.0 * temp[i] < 1.0) + temp[i] = temp2; + else { + if(3.0 * temp[i] < 2.0) + temp[i] = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp[i]) * 6.0; + else + temp[i] = temp1; + } + } + } + + // Assign temporary values to R, G, B + if(outR) + *outR = temp[0]; + if(outG) + *outG = temp[1]; + if(outB) + *outB = temp[2]; +} + +//CLASS IMPLEMENTATIONS: + +@implementation AppController + +@synthesize window; +@synthesize drawingView; + +- (void) applicationDidFinishLaunching:(UIApplication*)application +{ + CGRect rect = [[UIScreen mainScreen] applicationFrame]; + CGFloat components[3]; + + // Create a segmented control so that the user can choose the brush color. + UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems: + [NSArray arrayWithObjects: + [UIImage imageNamed:@"Red.png"], + [UIImage imageNamed:@"Yellow.png"], + [UIImage imageNamed:@"Green.png"], + [UIImage imageNamed:@"Blue.png"], + [UIImage imageNamed:@"Purple.png"], + nil]]; + + // Compute a rectangle that is positioned correctly for the segmented control you'll use as a brush color palette + CGRect frame = CGRectMake(rect.origin.x + kLeftMargin, rect.size.height - kPaletteHeight - kTopMargin, rect.size.width - (kLeftMargin + kRightMargin), kPaletteHeight); + segmentedControl.frame = frame; + // When the user chooses a color, the method changeBrushColor: is called. + [segmentedControl addTarget:self action:@selector(changeBrushColor:) forControlEvents:UIControlEventValueChanged]; + segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; + // Make sure the color of the color complements the black background + segmentedControl.tintColor = [UIColor darkGrayColor]; + // Set the third color (index values start at 0) + segmentedControl.selectedSegmentIndex = 2; + + // Add the control to the window + [window addSubview:segmentedControl]; + // Now that the control is added, you can release it + [segmentedControl release]; + + // Define a starting color + HSL2RGB((CGFloat) 2.0 / (CGFloat)kPaletteSize, kSaturation, kLuminosity, &components[0], &components[1], &components[2]); + // Defer to the OpenGL view to set the brush color + [drawingView setBrushColorWithRed:components[0] green:components[1] blue:components[2]]; + + // Look in the Info.plist file and you'll see the status bar is hidden + // Set the style to black so it matches the background of the application + [application setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO]; + // Now show the status bar, but animate to the style. + [application setStatusBarHidden:NO withAnimation:YES]; + + // Load the sounds + NSBundle *mainBundle = [NSBundle mainBundle]; + erasingSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@"Erase" ofType:@"caf"]]; + selectSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@"Select" ofType:@"caf"]]; + + // Erase the view when recieving a notification named "shake" from the NSNotificationCenter object + // The "shake" nofification is posted by the PaintingWindow object when user shakes the device + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eraseView) name:@"shake" object:nil]; +} + +// Release resources when they are no longer needed, +- (void) dealloc +{ + [selectSound release]; + [erasingSound release]; + [drawingView release]; + [window release]; + + [super dealloc]; +} + +// Change the brush color +- (void)changeBrushColor:(id)sender +{ + CGFloat components[3]; + + // Play sound + [selectSound play]; + + // Define a new brush color + HSL2RGB((CGFloat)[sender selectedSegmentIndex] / (CGFloat)kPaletteSize, kSaturation, kLuminosity, &components[0], &components[1], &components[2]); + // Defer to the OpenGL view to set the brush color + [drawingView setBrushColorWithRed:components[0] green:components[1] blue:components[2]]; + +} + +// Called when receiving the "shake" notification; plays the erase sound and redraws the view +-(void) eraseView +{ + if(CFAbsoluteTimeGetCurrent() > lastTime + kMinEraseInterval) { + [erasingSound play]; + [drawingView erase]; + lastTime = CFAbsoluteTimeGetCurrent(); + } +} + +@end diff --git a/GLPaint/Classes/PaintingView.h b/GLPaint/Classes/PaintingView.h new file mode 100644 index 0000000..38244c4 --- /dev/null +++ b/GLPaint/Classes/PaintingView.h @@ -0,0 +1,93 @@ +/* + File: PaintingView.h + Abstract: The class responsible for the finger painting. The class wraps the + CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view + content is basically an EAGL surface you render your OpenGL scene into. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import +#import +#import + +//CONSTANTS: + +#define kBrushOpacity (1.0 / 3.0) +#define kBrushPixelStep 3 +#define kBrushScale 2 +#define kLuminosity 0.75 +#define kSaturation 1.0 + +//CLASS INTERFACES: + +@interface PaintingView : UIView +{ +@private + // The pixel dimensions of the backbuffer + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + + // OpenGL names for the renderbuffer and framebuffers used to render to this view + GLuint viewRenderbuffer, viewFramebuffer; + + // OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) + GLuint depthRenderbuffer; + + GLuint brushTexture; + CGPoint location; + CGPoint previousLocation; + Boolean firstTouch; + Boolean needsErase; +} + +@property(nonatomic, readwrite) CGPoint location; +@property(nonatomic, readwrite) CGPoint previousLocation; + +- (void)erase; +- (void)setBrushColorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue; + +@end diff --git a/GLPaint/Classes/PaintingView.m b/GLPaint/Classes/PaintingView.m new file mode 100644 index 0000000..dc2427f --- /dev/null +++ b/GLPaint/Classes/PaintingView.m @@ -0,0 +1,392 @@ +/* + File: PaintingView.m + Abstract: The class responsible for the finger painting. The class wraps the + CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view + content is basically an EAGL surface you render your OpenGL scene into. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "PaintingView.h" + +//CLASS IMPLEMENTATIONS: + +// A class extension to declare private methods +@interface PaintingView (private) + +- (BOOL)createFramebuffer; +- (void)destroyFramebuffer; + +@end + +@implementation PaintingView + +@synthesize location; +@synthesize previousLocation; + +// Implement this to override the default layer class (which is [CALayer class]). +// We do this so that our view will be backed by a layer that is capable of OpenGL ES rendering. ++ (Class) layerClass +{ + return [CAEAGLLayer class]; +} + +// The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder { + + NSMutableArray* recordedPaths; + CGImageRef brushImage; + CGContextRef brushContext; + GLubyte *brushData; + size_t width, height; + + if ((self = [super initWithCoder:coder])) { + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = YES; + // In this application, we want to retain the EAGLDrawable contents after a call to presentRenderbuffer. + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if (!context || ![EAGLContext setCurrentContext:context]) { + [self release]; + return nil; + } + + // Create a texture from an image + // First create a UIImage object from the data in a image file, and then extract the Core Graphics image + brushImage = [UIImage imageNamed:@"Particle.png"].CGImage; + + // Get the width and height of the image + width = CGImageGetWidth(brushImage); + height = CGImageGetHeight(brushImage); + + // Texture dimensions must be a power of 2. If you write an application that allows users to supply an image, + // you'll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2. + + // Make sure the image exists + if(brushImage) { + // Allocate memory needed for the bitmap context + brushData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte)); + // Use the bitmatp creation function provided by the Core Graphics framework. + brushContext = CGBitmapContextCreate(brushData, width, height, 8, width * 4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast); + // After you create the context, you can draw the image to the context. + CGContextDrawImage(brushContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), brushImage); + // You don't need the context at this point, so you need to release it to avoid memory leaks. + CGContextRelease(brushContext); + // Use OpenGL ES to generate a name for the texture. + glGenTextures(1, &brushTexture); + // Bind the texture name. + glBindTexture(GL_TEXTURE_2D, brushTexture); + // Set the texture parameters to use a minifying filter and a linear filer (weighted average) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // Specify a 2D texture image, providing the a pointer to the image data in memory + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData); + // Release the image data; it's no longer needed + free(brushData); + } + + // Set the view's scale factor + self.contentScaleFactor = 1.0; + + // Setup OpenGL states + glMatrixMode(GL_PROJECTION); + CGRect frame = self.bounds; + CGFloat scale = self.contentScaleFactor; + // Setup the view port in Pixels + glOrthof(0, frame.size.width * scale, 0, frame.size.height * scale, -1, 1); + glViewport(0, 0, frame.size.width * scale, frame.size.height * scale); + glMatrixMode(GL_MODELVIEW); + + glDisable(GL_DITHER); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + + glEnable(GL_BLEND); + // Set a blending function appropriate for premultiplied alpha pixel data + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_POINT_SPRITE_OES); + glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE); + glPointSize(width / kBrushScale); + + // Make sure to start with a cleared buffer + needsErase = YES; + + // Playback recorded path, which is "Shake Me" + recordedPaths = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Recording" ofType:@"data"]]; + if([recordedPaths count]) + [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.2]; + } + + return self; +} + +// If our view is resized, we'll be asked to layout subviews. +// This is the perfect opportunity to also update the framebuffer so that it is +// the same size as our display area. +-(void)layoutSubviews +{ + [EAGLContext setCurrentContext:context]; + [self destroyFramebuffer]; + [self createFramebuffer]; + + // Clear the framebuffer the first time it is allocated + if (needsErase) { + [self erase]; + needsErase = NO; + } +} + +- (BOOL)createFramebuffer +{ + // Generate IDs for a framebuffer object and a color renderbuffer + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer) + // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view). + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + // For this sample, we also need a depth buffer, so we'll create and attach one via another renderbuffer. + glGenRenderbuffersOES(1, &depthRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + + if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) + { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + +// Clean up any buffers we have allocated. +- (void)destroyFramebuffer +{ + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if(depthRenderbuffer) + { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + +// Releases resources when they are not longer needed. +- (void) dealloc +{ + if (brushTexture) + { + glDeleteTextures(1, &brushTexture); + brushTexture = 0; + } + + if([EAGLContext currentContext] == context) + { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + [super dealloc]; +} + +// Erases the screen +- (void) erase +{ + [EAGLContext setCurrentContext:context]; + + // Clear the buffer + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + // Display the buffer + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +// Drawings a line onscreen based on where the user touches +- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end +{ + static GLfloat* vertexBuffer = NULL; + static NSUInteger vertexMax = 64; + NSUInteger vertexCount = 0, + count, + i; + + [EAGLContext setCurrentContext:context]; + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + + // Convert locations from Points to Pixels + CGFloat scale = self.contentScaleFactor; + start.x *= scale; + start.y *= scale; + end.x *= scale; + end.y *= scale; + + // Allocate vertex array buffer + if(vertexBuffer == NULL) + vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat)); + + // Add points to the buffer so there are drawing points every X pixels + count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1); + for(i = 0; i < count; ++i) { + if(vertexCount == vertexMax) { + vertexMax = 2 * vertexMax; + vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat)); + } + + vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count); + vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count); + vertexCount += 1; + } + + // Render the vertex array + glVertexPointer(2, GL_FLOAT, 0, vertexBuffer); + glDrawArrays(GL_POINTS, 0, vertexCount); + + // Display the buffer + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +// Reads previously recorded points and draws them onscreen. This is the Shake Me message that appears when the application launches. +- (void) playback:(NSMutableArray*)recordedPaths +{ + NSData* data = [recordedPaths objectAtIndex:0]; + CGPoint* point = (CGPoint*)[data bytes]; + NSUInteger count = [data length] / sizeof(CGPoint), + i; + + // Render the current path + for(i = 0; i < count - 1; ++i, ++point) + [self renderLineFromPoint:*point toPoint:*(point + 1)]; + + // Render the next path after a short delay + [recordedPaths removeObjectAtIndex:0]; + if([recordedPaths count]) + [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.01]; +} + + +// Handles the start of a touch +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + CGRect bounds = [self bounds]; + UITouch* touch = [[event touchesForView:self] anyObject]; + firstTouch = YES; + // Convert touch point from UIView referential to OpenGL one (upside-down flip) + location = [touch locationInView:self]; + location.y = bounds.size.height - location.y; +} + +// Handles the continuation of a touch. +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + + CGRect bounds = [self bounds]; + UITouch* touch = [[event touchesForView:self] anyObject]; + + // Convert touch point from UIView referential to OpenGL one (upside-down flip) + if (firstTouch) { + firstTouch = NO; + previousLocation = [touch previousLocationInView:self]; + previousLocation.y = bounds.size.height - previousLocation.y; + } else { + location = [touch locationInView:self]; + location.y = bounds.size.height - location.y; + previousLocation = [touch previousLocationInView:self]; + previousLocation.y = bounds.size.height - previousLocation.y; + } + + // Render the stroke + [self renderLineFromPoint:previousLocation toPoint:location]; +} + +// Handles the end of a touch event when the touch is a tap. +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + CGRect bounds = [self bounds]; + UITouch* touch = [[event touchesForView:self] anyObject]; + if (firstTouch) { + firstTouch = NO; + previousLocation = [touch previousLocationInView:self]; + previousLocation.y = bounds.size.height - previousLocation.y; + [self renderLineFromPoint:previousLocation toPoint:location]; + } +} + +// Handles the end of a touch event. +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + // If appropriate, add code necessary to save the state of the application. + // This application is not saving state. +} + +- (void)setBrushColorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue +{ + // Set the brush color using premultiplied alpha values + glColor4f(red * kBrushOpacity, + green * kBrushOpacity, + blue * kBrushOpacity, + kBrushOpacity); +} + +@end diff --git a/GLPaint/Classes/PaintingWindow.h b/GLPaint/Classes/PaintingWindow.h new file mode 100644 index 0000000..85bba68 --- /dev/null +++ b/GLPaint/Classes/PaintingWindow.h @@ -0,0 +1,54 @@ +/* + File: PaintingWindow.h + Abstract: A subclass of UIWindow to handle shake and other motion events. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface PaintingWindow : UIWindow { + +} + +@end diff --git a/GLPaint/Classes/PaintingWindow.m b/GLPaint/Classes/PaintingWindow.m new file mode 100644 index 0000000..d76460d --- /dev/null +++ b/GLPaint/Classes/PaintingWindow.m @@ -0,0 +1,69 @@ +/* + File: PaintingWindow.m + Abstract: A subclass of UIWindow to handle shake and other motion events. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "PaintingWindow.h" + +@implementation PaintingWindow + +- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ +} + +- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + if (motion == UIEventSubtypeMotionShake ) + { + // User was shaking the device. Post a notification named "shake". + [[NSNotificationCenter defaultCenter] postNotificationName:@"shake" object:self]; + } +} + +- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ +} + +@end diff --git a/GLPaint/Classes/SoundEffect.h b/GLPaint/Classes/SoundEffect.h new file mode 100644 index 0000000..823ae33 --- /dev/null +++ b/GLPaint/Classes/SoundEffect.h @@ -0,0 +1,59 @@ +/* + File: SoundEffect.h + Abstract: SoundEffect is a class that loads and plays sound files. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +@interface SoundEffect : NSObject { + SystemSoundID _soundID; +} + ++ (id)soundEffectWithContentsOfFile:(NSString *)aPath; +- (id)initWithContentsOfFile:(NSString *)path; +- (void)play; + +@end diff --git a/GLPaint/Classes/SoundEffect.m b/GLPaint/Classes/SoundEffect.m new file mode 100644 index 0000000..458199f --- /dev/null +++ b/GLPaint/Classes/SoundEffect.m @@ -0,0 +1,99 @@ +/* + File: SoundEffect.m + Abstract: SoundEffect is a class that loads and plays sound files. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "SoundEffect.h" + +@implementation SoundEffect + +// Creates a sound effect object from the specified sound file ++ (id)soundEffectWithContentsOfFile:(NSString *)aPath { + if (aPath) { + return [[[SoundEffect alloc] initWithContentsOfFile:aPath] autorelease]; + } + return nil; +} + +// Initializes a sound effect object with the contents of the specified sound file +- (id)initWithContentsOfFile:(NSString *)path { + self = [super init]; + + // Gets the file located at the specified path. + if (self != nil) { + NSURL *aFileURL = [NSURL fileURLWithPath:path isDirectory:NO]; + + // If the file exists, calls Core Audio to create a system sound ID. + if (aFileURL != nil) { + SystemSoundID aSoundID; + OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)aFileURL, &aSoundID); + + if (error == kAudioServicesNoError) { // success + _soundID = aSoundID; + } else { + NSLog(@"Error %d loading sound at path: %@", error, path); + [self release], self = nil; + } + } else { + NSLog(@"NSURL is nil for path: %@", path); + [self release], self = nil; + } + } + return self; +} + +// Releases resouces when no longer needed. +-(void)dealloc { + AudioServicesDisposeSystemSoundID(_soundID); + [super dealloc]; +} + +// Plays the sound associated with a sound effect object. +-(void)play { + // Calls Core Audio to play the sound for the specified sound ID. + AudioServicesPlaySystemSound(_soundID); +} + +@end diff --git a/GLPaint/Default.png b/GLPaint/Default.png new file mode 100644 index 0000000..8a47f39 Binary files /dev/null and b/GLPaint/Default.png differ diff --git a/GLPaint/Erase.caf b/GLPaint/Erase.caf new file mode 100644 index 0000000..bf5ccb9 Binary files /dev/null and b/GLPaint/Erase.caf differ diff --git a/GLPaint/GLPaint-Info.plist b/GLPaint/GLPaint-Info.plist new file mode 100644 index 0000000..e7be526 --- /dev/null +++ b/GLPaint/GLPaint-Info.plist @@ -0,0 +1,41 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.11 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarHidden + + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + + diff --git a/GLPaint/GLPaint.xcodeproj/project.pbxproj b/GLPaint/GLPaint.xcodeproj/project.pbxproj new file mode 100755 index 0000000..bf4c52e --- /dev/null +++ b/GLPaint/GLPaint.xcodeproj/project.pbxproj @@ -0,0 +1,354 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1B612B1F0DDCF277003A5CC7 /* Particle.png in Resources */ = {isa = PBXBuildFile; fileRef = 1B612B1E0DDCF277003A5CC7 /* Particle.png */; }; + 1B8CA3120DC8E3A4002C657A /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B8CA30B0DC8E3A4002C657A /* AppController.m */; }; + 1B8CA3130DC8E3A4002C657A /* PaintingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B8CA30D0DC8E3A4002C657A /* PaintingView.m */; }; + 1B8CA3140DC8E3A4002C657A /* SoundEffect.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B8CA30F0DC8E3A4002C657A /* SoundEffect.m */; }; + 1BBE306C0DD273B90012773B /* Blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 1BBE30670DD273B90012773B /* Blue.png */; }; + 1BBE306D0DD273B90012773B /* Green.png in Resources */ = {isa = PBXBuildFile; fileRef = 1BBE30680DD273B90012773B /* Green.png */; }; + 1BBE306E0DD273B90012773B /* Purple.png in Resources */ = {isa = PBXBuildFile; fileRef = 1BBE30690DD273B90012773B /* Purple.png */; }; + 1BBE306F0DD273B90012773B /* Red.png in Resources */ = {isa = PBXBuildFile; fileRef = 1BBE306A0DD273B90012773B /* Red.png */; }; + 1BBE30700DD273B90012773B /* Yellow.png in Resources */ = {isa = PBXBuildFile; fileRef = 1BBE306B0DD273B90012773B /* Yellow.png */; }; + 1BD0B6AB0DDCA9B800E538F8 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1BD0B6AA0DDCA9B800E538F8 /* Default.png */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28F25BC20D64BF0B00158CCD /* Recording.data in Resources */ = {isa = PBXBuildFile; fileRef = 28F25BBF0D64BF0B00158CCD /* Recording.data */; }; + 28F25BC30D64BF0B00158CCD /* Select.caf in Resources */ = {isa = PBXBuildFile; fileRef = 28F25BC00D64BF0B00158CCD /* Select.caf */; }; + 28F25BC40D64BF0B00158CCD /* Erase.caf in Resources */ = {isa = PBXBuildFile; fileRef = 28F25BC10D64BF0B00158CCD /* Erase.caf */; }; + 2D500B940D5A79C200DBA0E3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D500B920D5A79C200DBA0E3 /* OpenGLES.framework */; }; + 2D500B9A0D5A79CF00DBA0E3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D500B990D5A79CF00DBA0E3 /* QuartzCore.framework */; }; + 2D500C820D5A7DAE00DBA0E3 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D500C810D5A7DAE00DBA0E3 /* AudioToolbox.framework */; }; + AF85865410694D4D0004D36B /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF85865310694D4D0004D36B /* MainWindow.xib */; }; + AF858950106977F20004D36B /* PaintingWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = AF85894F106977F20004D36B /* PaintingWindow.m */; }; + AFCEBA2111D96215001AA22A /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA1A11D96215001AA22A /* Icon-72.png */; }; + AFCEBA2211D96215001AA22A /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA1B11D96215001AA22A /* Icon-Small-50.png */; }; + AFCEBA2311D96215001AA22A /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA1C11D96215001AA22A /* Icon-Small.png */; }; + AFCEBA2411D96215001AA22A /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA1D11D96215001AA22A /* Icon-Small@2x.png */; }; + AFCEBA2511D96215001AA22A /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA1E11D96215001AA22A /* Icon.png */; }; + AFCEBA2611D96215001AA22A /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA1F11D96215001AA22A /* Icon@2x.png */; }; + AFCEBA2711D96215001AA22A /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = AFCEBA2011D96215001AA22A /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1B612B1E0DDCF277003A5CC7 /* Particle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Particle.png; sourceTree = ""; }; + 1B8CA30A0DC8E3A4002C657A /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppController.h; path = Classes/AppController.h; sourceTree = ""; }; + 1B8CA30B0DC8E3A4002C657A /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppController.m; path = Classes/AppController.m; sourceTree = ""; }; + 1B8CA30C0DC8E3A4002C657A /* PaintingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PaintingView.h; path = Classes/PaintingView.h; sourceTree = ""; }; + 1B8CA30D0DC8E3A4002C657A /* PaintingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PaintingView.m; path = Classes/PaintingView.m; sourceTree = ""; }; + 1B8CA30E0DC8E3A4002C657A /* SoundEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SoundEffect.h; path = Classes/SoundEffect.h; sourceTree = ""; }; + 1B8CA30F0DC8E3A4002C657A /* SoundEffect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SoundEffect.m; path = Classes/SoundEffect.m; sourceTree = ""; }; + 1BBE30670DD273B90012773B /* Blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Blue.png; path = Images/Blue.png; sourceTree = ""; }; + 1BBE30680DD273B90012773B /* Green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Green.png; path = Images/Green.png; sourceTree = ""; }; + 1BBE30690DD273B90012773B /* Purple.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Purple.png; path = Images/Purple.png; sourceTree = ""; }; + 1BBE306A0DD273B90012773B /* Red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Red.png; path = Images/Red.png; sourceTree = ""; }; + 1BBE306B0DD273B90012773B /* Yellow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Yellow.png; path = Images/Yellow.png; sourceTree = ""; }; + 1BD0B6AA0DDCA9B800E538F8 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 1BEB7DB40DA5967E00271C96 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* GLPaint.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLPaint.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28F25BBF0D64BF0B00158CCD /* Recording.data */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Recording.data; sourceTree = ""; }; + 28F25BC00D64BF0B00158CCD /* Select.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Select.caf; sourceTree = ""; }; + 28F25BC10D64BF0B00158CCD /* Erase.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Erase.caf; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2D500B920D5A79C200DBA0E3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 2D500B990D5A79CF00DBA0E3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 2D500C810D5A7DAE00DBA0E3 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* GLPaint-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GLPaint-Info.plist"; sourceTree = ""; }; + AF85865310694D4D0004D36B /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + AF85894E106977F20004D36B /* PaintingWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PaintingWindow.h; path = Classes/PaintingWindow.h; sourceTree = ""; }; + AF85894F106977F20004D36B /* PaintingWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PaintingWindow.m; path = Classes/PaintingWindow.m; sourceTree = ""; }; + AFCEBA1A11D96215001AA22A /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + AFCEBA1B11D96215001AA22A /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + AFCEBA1C11D96215001AA22A /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + AFCEBA1D11D96215001AA22A /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + AFCEBA1E11D96215001AA22A /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + AFCEBA1F11D96215001AA22A /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + AFCEBA2011D96215001AA22A /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 2D500B940D5A79C200DBA0E3 /* OpenGLES.framework in Frameworks */, + 2D500B9A0D5A79CF00DBA0E3 /* QuartzCore.framework in Frameworks */, + 2D500C820D5A7DAE00DBA0E3 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GLPaint.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 1BEB7DB40DA5967E00271C96 /* ReadMe.txt */, + 2D500B1D0D5A766B00DBA0E3 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + AFCEBA1A11D96215001AA22A /* Icon-72.png */, + AFCEBA1B11D96215001AA22A /* Icon-Small-50.png */, + AFCEBA1C11D96215001AA22A /* Icon-Small.png */, + AFCEBA1D11D96215001AA22A /* Icon-Small@2x.png */, + AFCEBA1E11D96215001AA22A /* Icon.png */, + AFCEBA1F11D96215001AA22A /* Icon@2x.png */, + AFCEBA2011D96215001AA22A /* iTunesArtwork */, + AF85865310694D4D0004D36B /* MainWindow.xib */, + 1B612B1E0DDCF277003A5CC7 /* Particle.png */, + 1BD0B6AA0DDCA9B800E538F8 /* Default.png */, + 28F25BBF0D64BF0B00158CCD /* Recording.data */, + 28F25BC00D64BF0B00158CCD /* Select.caf */, + 28F25BC10D64BF0B00158CCD /* Erase.caf */, + 8D1107310486CEB800E47090 /* GLPaint-Info.plist */, + 1BBE30670DD273B90012773B /* Blue.png */, + 1BBE30680DD273B90012773B /* Green.png */, + 1BBE30690DD273B90012773B /* Purple.png */, + 1BBE306A0DD273B90012773B /* Red.png */, + 1BBE306B0DD273B90012773B /* Yellow.png */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2D500C810D5A7DAE00DBA0E3 /* AudioToolbox.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 2D500B990D5A79CF00DBA0E3 /* QuartzCore.framework */, + 2D500B920D5A79C200DBA0E3 /* OpenGLES.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2D500B1D0D5A766B00DBA0E3 /* Classes */ = { + isa = PBXGroup; + children = ( + 1B8CA30A0DC8E3A4002C657A /* AppController.h */, + 1B8CA30B0DC8E3A4002C657A /* AppController.m */, + AF85894E106977F20004D36B /* PaintingWindow.h */, + AF85894F106977F20004D36B /* PaintingWindow.m */, + 1B8CA30C0DC8E3A4002C657A /* PaintingView.h */, + 1B8CA30D0DC8E3A4002C657A /* PaintingView.m */, + 1B8CA30E0DC8E3A4002C657A /* SoundEffect.h */, + 1B8CA30F0DC8E3A4002C657A /* SoundEffect.m */, + ); + name = Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GLPaint */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLPaint" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GLPaint; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* GLPaint.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLPaint" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GLPaint */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28F25BC20D64BF0B00158CCD /* Recording.data in Resources */, + 28F25BC30D64BF0B00158CCD /* Select.caf in Resources */, + 28F25BC40D64BF0B00158CCD /* Erase.caf in Resources */, + 1BBE306C0DD273B90012773B /* Blue.png in Resources */, + 1BBE306D0DD273B90012773B /* Green.png in Resources */, + 1BBE306E0DD273B90012773B /* Purple.png in Resources */, + 1BBE306F0DD273B90012773B /* Red.png in Resources */, + 1BBE30700DD273B90012773B /* Yellow.png in Resources */, + 1BD0B6AB0DDCA9B800E538F8 /* Default.png in Resources */, + 1B612B1F0DDCF277003A5CC7 /* Particle.png in Resources */, + AF85865410694D4D0004D36B /* MainWindow.xib in Resources */, + AFCEBA2111D96215001AA22A /* Icon-72.png in Resources */, + AFCEBA2211D96215001AA22A /* Icon-Small-50.png in Resources */, + AFCEBA2311D96215001AA22A /* Icon-Small.png in Resources */, + AFCEBA2411D96215001AA22A /* Icon-Small@2x.png in Resources */, + AFCEBA2511D96215001AA22A /* Icon.png in Resources */, + AFCEBA2611D96215001AA22A /* Icon@2x.png in Resources */, + AFCEBA2711D96215001AA22A /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1B8CA3120DC8E3A4002C657A /* AppController.m in Sources */, + 1B8CA3130DC8E3A4002C657A /* PaintingView.m in Sources */, + 1B8CA3140DC8E3A4002C657A /* SoundEffect.m in Sources */, + AF858950106977F20004D36B /* PaintingWindow.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = "GLPaint-Info.plist"; + PREBINDING = NO; + PRODUCT_NAME = GLPaint; + WARNING_CFLAGS = "-Wall"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = "GLPaint-Info.plist"; + PREBINDING = NO; + PRODUCT_NAME = GLPaint; + WARNING_CFLAGS = "-Wall"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLPaint" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLPaint" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GLPaint/Images/Blue.png b/GLPaint/Images/Blue.png new file mode 100755 index 0000000..3b726a6 Binary files /dev/null and b/GLPaint/Images/Blue.png differ diff --git a/GLPaint/Images/Green.png b/GLPaint/Images/Green.png new file mode 100755 index 0000000..35e03a4 Binary files /dev/null and b/GLPaint/Images/Green.png differ diff --git a/GLPaint/Images/Icon-72.png b/GLPaint/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GLPaint/Images/Icon-72.png differ diff --git a/GLPaint/Images/Icon-Small-50.png b/GLPaint/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GLPaint/Images/Icon-Small-50.png differ diff --git a/GLPaint/Images/Icon-Small.png b/GLPaint/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GLPaint/Images/Icon-Small.png differ diff --git a/GLPaint/Images/Icon-Small@2x.png b/GLPaint/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GLPaint/Images/Icon-Small@2x.png differ diff --git a/GLPaint/Images/Icon.png b/GLPaint/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GLPaint/Images/Icon.png differ diff --git a/GLPaint/Images/Icon@2x.png b/GLPaint/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GLPaint/Images/Icon@2x.png differ diff --git a/GLPaint/Images/Purple.png b/GLPaint/Images/Purple.png new file mode 100755 index 0000000..1b2779d Binary files /dev/null and b/GLPaint/Images/Purple.png differ diff --git a/GLPaint/Images/Red.png b/GLPaint/Images/Red.png new file mode 100755 index 0000000..659cac5 Binary files /dev/null and b/GLPaint/Images/Red.png differ diff --git a/GLPaint/Images/Yellow.png b/GLPaint/Images/Yellow.png new file mode 100755 index 0000000..0f4ea43 Binary files /dev/null and b/GLPaint/Images/Yellow.png differ diff --git a/GLPaint/Images/iTunesArtwork b/GLPaint/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GLPaint/Images/iTunesArtwork differ diff --git a/GLPaint/MainWindow.xib b/GLPaint/MainWindow.xib new file mode 100644 index 0000000..0a0c7e7 --- /dev/null +++ b/GLPaint/MainWindow.xib @@ -0,0 +1,420 @@ + + + + 768 + 10B504 + 732 + 1038.2 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + drawingView + + + + 10 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + + -1 + + + File's Owner + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + PaintingWindow + + YES + + + YES + + + {{309, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + PaintingView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 10 + + + + YES + + AppController + NSObject + + YES + + YES + drawingView + window + + + YES + PaintingView + PaintingWindow + + + + IBProjectSource + Classes/AppController.h + + + + PaintingView + UIView + + IBProjectSource + Classes/PaintingView.h + + + + PaintingWindow + UIWindow + + IBProjectSource + PaintingWindow.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIResponder + NSObject + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + GLPaint.xcodeproj + 3 + 3.1 + + diff --git a/GLPaint/Particle.png b/GLPaint/Particle.png new file mode 100644 index 0000000..90d44a2 Binary files /dev/null and b/GLPaint/Particle.png differ diff --git a/GLPaint/Prefix.pch b/GLPaint/Prefix.pch new file mode 100644 index 0000000..bb57e5f --- /dev/null +++ b/GLPaint/Prefix.pch @@ -0,0 +1,6 @@ +#import + + +#ifdef __OBJC__ + #import +#endif diff --git a/GLPaint/ReadMe.txt b/GLPaint/ReadMe.txt new file mode 100644 index 0000000..483ae5f --- /dev/null +++ b/GLPaint/ReadMe.txt @@ -0,0 +1,99 @@ +### GLPaint ### + +================================================================================ +DESCRIPTION: + +The GLPaint sample application demonstrates how to support single finger painting using OpenGL ES. This sample also shows how to detect a "shake" motion of the device. + +By looking at the code you'll see how to set up an OpenGL ES view and use it for rendering painting strokes. The application creates a brush texture from an image by first drawing the image into a Core Graphics bitmap context. It then uses the bitmap data for the texture. The image used for a texture must have dimensions that are a power of 2. + +To use this sample, open it in Xcode and click Build and Go. After the application paints "Shake Me", shake the device to erase the words. Touch a color to choose it. Paint by dragging a finger. + +NOTE: When you run the application in the simulator, you can use the Shake Gesture key under Hardware to simulate the shake motion. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +AppController.h +AppController.m +UIApplication's delegate class i.e. the central controller of the application. + +PaintingWindow.h +PaintingWindow.m +A subclass of UIWindow to handle shake and other motion events. + +PaintingView.h +PaintingView.m +The class responsible for the finger painting. The class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view content is basically an EAGL surface you render your OpenGL scene into. + +SoundEffect.h +SoundEffect.m +A simple Objective-C wrapper around Audio Services functions that allow the loading and playing of sound files. + +main.m +The main entry point for the GLPaint application. + +Recording.data +Contains the path used to display "Shake Me" after the application launches. + +Particle.png +The texture used for the paint brush. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.11 +Updated to take into account the view's contentScaleFactor. +Updated to draw strictly with premultiplied alpha pixel data. + +Version 1.9 +Upgraded project to build with the iOS 4.0 SDK. +Fixed minor bugs. + +Version 1.8 +Removed duplicate lines in setting up OpenGL blending. + +Version 1.7 +Updated for iPhone OS 3.1. Set texture parameters before creating the texture. This will save texture memory and texture loading time. +Use the shake API available in iPhone OS 3.0 and later. +Made the sample xib-based. + +Version 1.6 +Updated for and tested with iPhone OS 2.0. First public release. + +Version 1.5 +Minor changes to the comments. +There are no code changes in this version. + +Version 1.4 +Updated for Beta 6. +Updated code to use revised EAGL API. +Removed TouchView and Texture2D classes. +Replaced the views used to choose brush color with a segmented control. +Replace the Texture2D class with code that creates a texture using a Core Graphic bitmap graphics context. +Speeded up the "Shake Me" instructions that appear at the start of the application. +Revised touch handling to use the begin, moved, end, and cancelled methods instead of touchesChanged:withEvent; + +Version 1.3 +Updated for Beta 4. +Changed project setting related to code signing. +Replaced pixel buffer objects with framebuffer objects. + +Version 1.2 +Added an icon and a default.png file. + +Version 1.1 +Updated for Beta 2. + +================================================================================ +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/GLPaint/Recording.data b/GLPaint/Recording.data new file mode 100644 index 0000000..814bee9 --- /dev/null +++ b/GLPaint/Recording.data @@ -0,0 +1,90 @@ + + + + + + AAB4QgAAt0MAAFBCAIC1QwAAMEIAgLRDAAAUQgAAskMAAOhBAACvQwAAwEEAgKxDAAC4 + QQCAqkMAALhBAICnQwAAPEIAAKRDAABsQgCAokMAAIxCAIChQwAAlEIAgJ9DAACWQgCA + nkMAAI5CAICbQwAAbEIAAJhDAAAkQgAAlEMAAKBBAACOQwAAgEEAgIxDAABwQQAAjEMA + AGBBAICLQwAAYEEAgItD + + + AAC8QgAAsEMAAMJCAICoQwAAwkIAAKRDAADCQgCAnUMAAMJCAACYQwAAwEIAgJRDAADA + QgCAkkMAAMBCAACRQwAAwEIAgJBDAADAQgCAkEM= + + + AACoQgAAnEMAALpCAACdQwAAxEIAAJ1DAADQQgAAnUMAANpCAICdQwAA4kIAgJ5DAADs + QgCAn0MAAOxCAICfQw== + + + AAACQwAAsEMAAANDAACpQwAAA0MAAKVDAAADQwAAn0MAAANDAICZQwAAA0MAAJVDAAAD + QwAAkkMAAANDAACSQw== + + + AAAVQwCAiUMAABdDAICMQwAAF0MAAJBDAAAYQwCAlUMAABtDAACcQwAAI0MAAKRDAAAr + QwAArEMAADFDAICxQwAANkMAgLRDAAA6QwAAtkMAAD1DAIC2QwAAP0MAgLVDAABAQwAA + skMAAEFDAACuQwAAQkMAgKhDAABCQwAApEMAAEJDAACeQwAAQkMAgJhDAABCQwCAlkMA + AD5DAICTQwAAPkMAgJND + + + AAAhQwCAoEMAADRDAIChQwAAO0MAAKJDAABAQwCAokMAAEZDAICiQwAARkMAgKJD + + + AABbQwAAs0MAAFtDAICsQwAAW0MAAKhDAABbQwAAokMAAFpDAICaQwAAWEMAgJVDAABX + QwAAkkMAAFdDAACQQwAAV0MAAI9DAABXQwAAjkMAAFdDAACQQwAAWUMAAJRDAABfQwAA + mUMAAGVDAACfQwAAa0MAAKNDAABxQwCApkMAAHZDAACpQwAAeUMAAKtDAAB9QwCArEMA + AH9DAICtQwCAgEMAgK5DAACBQwAAr0MAgIFDAACvQwCAgUMAAK9D + + + AABlQwAAn0MAAG5DAICbQwAAckMAgJtDAAB3QwAAm0MAAHtDAACaQwAAf0MAAJlDAICA + QwCAmEMAgIFDAACYQwCAgkMAAJdDAACEQwCAlUMAAIRDAICVQw== + + + AACOQwAAsUMAAI1DAACtQwAAjUMAgKlDAACMQwAApkMAgIpDAAChQwAAiUMAAJxDAICI + QwAAmUMAgIhDAICWQwCAiEMAgJRDAICIQwAAk0MAAIlDAACSQwAAi0MAgJFDAICNQwCA + kUMAgJJDAICRQwCAlEMAgJJDAICWQwCAk0MAAJlDAICUQwAAmkMAAJVDAICaQwAAlUMA + gJpDAACVQw== + + + AICJQwCAoUMAgI1DAACiQwCAj0MAAKJDAACSQwAAokMAgJNDAICiQwAAlUMAgKJDAACV + QwCAokM= + + + AICNQwCAr0MAgJNDAACyQwAAl0MAgLJDAACaQwAAtEMAAJxDAIC0QwAAnEMAgLRD + + + AABcQgAAJUMAAFRCAAAeQwAAVEIAABNDAABUQgAACEMAAFRCAAD+QgAAVEIAAPBCAABU + QgAA5EIAAFRCAADcQgAAVEIAANpCAABUQgAA2EIAAFRCAADaQgAAVEIAAOZCAABYQgAA + A0MAAGRCAAAfQwAAaEIAADFDAABsQgAAPUMAAGxCAABEQwAAdEIAAElDAACAQgAASEMA + AI5CAABCQwAAoEIAAD1DAAC0QgAAOUMAAMZCAAA4QwAA3EIAADhDAADsQgAAPUMAAPRC + AABBQwAA/kIAAEZDAAAAQwAARkMAAABDAAA/QwAAAEMAADNDAAAAQwAAIUMAAP5CAAAP + QwAA/kIAAP5CAAD+QgAA5EIAAP5CAADUQgAA/kIAAMhCAAAAQwAAxkIAAABDAADGQg== + + + AAAvQwAATEMAACxDAABDQwAALEMAADpDAAArQwAALUMAACpDAAAgQwAAKUMAABFDAAAo + QwAABkMAACZDAAD8QgAAJUMAAOpCAAAlQwAA3kIAACVDAADWQgAAKkMAANJCAAAzQwAA + 0kIAADxDAADcQgAARkMAAOZCAABQQwAA7kIAAFhDAAD0QgAAXUMAAPZCAABjQwAA+kIA + AGNDAAD6Qg== + + + AAA0QwAAFUMAAEFDAAAYQwAATUMAABpDAABaQwAAHkMAAGZDAAAkQwAAcEMAACpDAAB0 + QwAAL0MAAHRDAAAvQw== + + + AAAxQwAAPUMAAD9DAABAQwAATUMAAEFDAABbQwAARUMAAGhDAABKQwAAcUMAAE1DAAB5 + QwAAUEMAAHlDAABQQw== + + + AICEQwAAb0MAAIZDAABjQwCAhkMAAFdDAACHQwAARkMAgIdDAAAyQwCAiEMAACBDAACJ + QwAAFkMAgIlDAAAOQwCAikMAAAVDAICKQwAABUM= + + + AICNQwAAukIAgI1DAAC6Qg== + + + AACTQwAArkIAgI5DAACiQgAAjkMAAKJCAACOQwAAoEIAAI5DAACeQgCAjkMAAKBCAICO + QwAApEIAgI5DAACmQgCAjkMAAKhCAACOQwAAqEIAAI1DAACoQgAAjUMAAKZCAACNQwAA + pEIAAI1DAACkQg== + + + diff --git a/GLPaint/Select.caf b/GLPaint/Select.caf new file mode 100644 index 0000000..20b01db Binary files /dev/null and b/GLPaint/Select.caf differ diff --git a/GLPaint/main.m b/GLPaint/main.m new file mode 100644 index 0000000..a4095fa --- /dev/null +++ b/GLPaint/main.m @@ -0,0 +1,59 @@ +/* + File: main.m + Abstract: The main entry point for GLPaint. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool* pool = [NSAutoreleasePool new]; + + UIApplicationMain(argc, argv, nil, nil); + + [pool release]; + + return 0; +} diff --git a/GLSprite.zip b/GLSprite.zip new file mode 100644 index 0000000..97bf82c Binary files /dev/null and b/GLSprite.zip differ diff --git a/GLSprite/Classes/EAGLView.h b/GLSprite/Classes/EAGLView.h new file mode 100644 index 0000000..89073b6 --- /dev/null +++ b/GLSprite/Classes/EAGLView.h @@ -0,0 +1,94 @@ +/* + File: EAGLView.h + Abstract: This class wraps the CAEAGLLayer from CoreAnimation into a convenient + UIView subclass. The view content is basically an EAGL surface you render your + OpenGL scene into. Note that setting the view non-opaque will only work if the + EAGL surface has an alpha channel. + + Version: 1.9 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import +#import +#import + +@interface EAGLView : UIView +{ +@private + + /* The pixel dimensions of the backbuffer */ + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + + /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ + GLuint viewRenderbuffer, viewFramebuffer; + + /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ + GLuint depthRenderbuffer; + + /* OpenGL name for the sprite texture */ + GLuint spriteTexture; + + BOOL animating; + BOOL displayLinkSupported; + NSInteger animationFrameInterval; + // Use of the CADisplayLink class is the preferred method for controlling your animation timing. + // CADisplayLink will link to the main display and fire every vsync when added to a given run-loop. + // The NSTimer class is used only as fallback when running on a pre 3.1 device where CADisplayLink + // isn't available. + id displayLink; + NSTimer *animationTimer; +} + +@property (readonly, nonatomic, getter=isAnimating) BOOL animating; +@property (nonatomic) NSInteger animationFrameInterval; + +- (void)startAnimation; +- (void)stopAnimation; +- (void)drawView; + +@end diff --git a/GLSprite/Classes/EAGLView.m b/GLSprite/Classes/EAGLView.m new file mode 100644 index 0000000..6cd79c3 --- /dev/null +++ b/GLSprite/Classes/EAGLView.m @@ -0,0 +1,338 @@ +/* + File: EAGLView.m + Abstract: This class wraps the CAEAGLLayer from CoreAnimation into a convenient + UIView subclass. The view content is basically an EAGL surface you render your + OpenGL scene into. Note that setting the view non-opaque will only work if the + EAGL surface has an alpha channel. + + Version: 1.9 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "EAGLView.h" + +@interface EAGLView (EAGLViewPrivate) + +- (BOOL)createFramebuffer; +- (void)destroyFramebuffer; + +@end + +@interface EAGLView (EAGLViewSprite) + +- (void)setupView; + +@end + +@implementation EAGLView + +@synthesize animating; +@dynamic animationFrameInterval; + +// You must implement this ++ (Class) layerClass +{ + return [CAEAGLLayer class]; +} + + +//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder +{ + if((self = [super initWithCoder:coder])) { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer; + + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) { + [self release]; + return nil; + } + + animating = FALSE; + displayLinkSupported = FALSE; + animationFrameInterval = 1; + displayLink = nil; + animationTimer = nil; + + // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer + // class is used as fallback when it isn't available. + NSString *reqSysVer = @"3.1"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) + displayLinkSupported = TRUE; + + [self setupView]; + [self drawView]; + } + + return self; +} + + +- (void)layoutSubviews +{ + [EAGLContext setCurrentContext:context]; + [self destroyFramebuffer]; + [self createFramebuffer]; + [self drawView]; +} + + +- (BOOL)createFramebuffer +{ + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + + +- (void)destroyFramebuffer +{ + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if(depthRenderbuffer) { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + + +- (NSInteger) animationFrameInterval +{ + return animationFrameInterval; +} + +- (void) setAnimationFrameInterval:(NSInteger)frameInterval +{ + // Frame interval defines how many display frames must pass between each time the + // display link fires. The display link will only fire 30 times a second when the + // frame internal is two on a display that refreshes 60 times a second. The default + // frame interval setting of one will fire 60 times a second when the display refreshes + // at 60 times a second. A frame interval setting of less than one results in undefined + // behavior. + if (frameInterval >= 1) + { + animationFrameInterval = frameInterval; + + if (animating) + { + [self stopAnimation]; + [self startAnimation]; + } + } +} + +- (void) startAnimation +{ + if (!animating) + { + if (displayLinkSupported) + { + // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed + // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will + // not be called in system versions earlier than 3.1. + + displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView)]; + [displayLink setFrameInterval:animationFrameInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } + else + animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView) userInfo:nil repeats:TRUE]; + + animating = TRUE; + } +} + +- (void)stopAnimation +{ + if (animating) + { + if (displayLinkSupported) + { + [displayLink invalidate]; + displayLink = nil; + } + else + { + [animationTimer invalidate]; + animationTimer = nil; + } + + animating = FALSE; + } +} + + +// Sets up an array of values to use as the sprite vertices. +const GLfloat spriteVertices[] = { +-0.5f, -0.5f, +0.5f, -0.5f, +-0.5f, 0.5f, +0.5f, 0.5f, +}; + +// Sets up an array of values for the texture coordinates. +const GLshort spriteTexcoords[] = { +0, 0, +1, 0, +0, 1, +1, 1, +}; + +- (void)setupView +{ + CGImageRef spriteImage; + CGContextRef spriteContext; + GLubyte *spriteData; + size_t width, height; + + // Sets up matrices and transforms for OpenGL ES + glViewport(0, 0, backingWidth, backingHeight); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); + + // Clears the view with black + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + // Sets up pointers and enables states needed for using vertex arrays and textures + glVertexPointer(2, GL_FLOAT, 0, spriteVertices); + glEnableClientState(GL_VERTEX_ARRAY); + glTexCoordPointer(2, GL_SHORT, 0, spriteTexcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // Creates a Core Graphics image from an image file + spriteImage = [UIImage imageNamed:@"Sprite.png"].CGImage; + // Get the width and height of the image + width = CGImageGetWidth(spriteImage); + height = CGImageGetHeight(spriteImage); + // Texture dimensions must be a power of 2. If you write an application that allows users to supply an image, + // you'll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2. + + if(spriteImage) { + // Allocated memory needed for the bitmap context + spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte)); + // Uses the bitmap creation function provided by the Core Graphics framework. + spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast); + // After you create the context, you can draw the sprite image to the context. + CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage); + // You don't need the context at this point, so you need to release it to avoid memory leaks. + CGContextRelease(spriteContext); + + // Use OpenGL ES to generate a name for the texture. + glGenTextures(1, &spriteTexture); + // Bind the texture name. + glBindTexture(GL_TEXTURE_2D, spriteTexture); + // Set the texture parameters to use a minifying filter and a linear filer (weighted average) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // Specify a 2D texture image, providing the a pointer to the image data in memory + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); + // Release the image data + free(spriteData); + + // Enable use of the texture + glEnable(GL_TEXTURE_2D); + // Set a blending function to use + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + // Enable blending + glEnable(GL_BLEND); + } +} + +// Updates the OpenGL view when the timer fires +- (void)drawView +{ + // Make sure that you are drawing to the current context + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glRotatef(3.0f, 0.0f, 0.0f, 1.0f); + + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +// Release resources when they are no longer needed. +- (void)dealloc +{ + if([EAGLContext currentContext] == context) { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + context = nil; + + [super dealloc]; +} + +@end diff --git a/GLSprite/Classes/GLSpriteAppDelegate.h b/GLSprite/Classes/GLSpriteAppDelegate.h new file mode 100644 index 0000000..93caa1c --- /dev/null +++ b/GLSprite/Classes/GLSpriteAppDelegate.h @@ -0,0 +1,62 @@ +/* + File: GLSpriteAppDelegate.h + Abstract: The UIApplication delegate class which is the central controller of + the application. + + Version: 1.9 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class EAGLView; + +@interface GLSpriteAppDelegate : NSObject { + IBOutlet UIWindow *window; + IBOutlet EAGLView *glView; +} + +@property (nonatomic, retain) UIWindow *window; + +@end + diff --git a/GLSprite/Classes/GLSpriteAppDelegate.m b/GLSprite/Classes/GLSpriteAppDelegate.m new file mode 100644 index 0000000..d157c14 --- /dev/null +++ b/GLSprite/Classes/GLSpriteAppDelegate.m @@ -0,0 +1,85 @@ +/* + File: GLSpriteAppDelegate.m + Abstract: The UIApplication delegate class which is the central controller of + the application. + + Version: 1.9 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "GLSpriteAppDelegate.h" +#import "EAGLView.h" + +@implementation GLSpriteAppDelegate + +@synthesize window; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void) applicationWillResignActive:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) applicationDidBecomeActive:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) dealloc +{ + [window release]; + [glView release]; + + [super dealloc]; +} + +@end diff --git a/GLSprite/Default.png b/GLSprite/Default.png new file mode 100644 index 0000000..8a47f39 Binary files /dev/null and b/GLSprite/Default.png differ diff --git a/GLSprite/GLSprite.xcodeproj/project.pbxproj b/GLSprite/GLSprite.xcodeproj/project.pbxproj new file mode 100755 index 0000000..9b1c92e --- /dev/null +++ b/GLSprite/GLSprite.xcodeproj/project.pbxproj @@ -0,0 +1,327 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1B62193E0DDBC27200C070EC /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1B62193D0DDBC27200C070EC /* Default.png */; }; + 1B7FD2380DCBBCF100E48ED5 /* Sprite.png in Resources */ = {isa = PBXBuildFile; fileRef = 1B7FD2370DCBBCF100E48ED5 /* Sprite.png */; }; + 1BF0DBA40DDCF72400C6466A /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1BF0DBA20DDCF72400C6466A /* MainWindow.xib */; }; + 1D3623260D0F684500981E51 /* GLSpriteAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* GLSpriteAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28FD14FD0DC6FC130079059D /* EAGLView.m */; }; + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; }; + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; }; + AF5A94F01210DFC3003EF434 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94E91210DFC3003EF434 /* Icon-72.png */; }; + AF5A94F11210DFC3003EF434 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94EA1210DFC3003EF434 /* Icon-Small-50.png */; }; + AF5A94F21210DFC3003EF434 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94EB1210DFC3003EF434 /* Icon-Small.png */; }; + AF5A94F31210DFC3003EF434 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94EC1210DFC3003EF434 /* Icon-Small@2x.png */; }; + AF5A94F41210DFC3003EF434 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94ED1210DFC3003EF434 /* Icon.png */; }; + AF5A94F51210DFC3003EF434 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94EE1210DFC3003EF434 /* Icon@2x.png */; }; + AF5A94F61210DFC3003EF434 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = AF5A94EF1210DFC3003EF434 /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1B62193D0DDBC27200C070EC /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 1B76A63F0DCBB4F3003B05F2 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 1B7FD2370DCBBCF100E48ED5 /* Sprite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Sprite.png; sourceTree = ""; }; + 1BF0DBA30DDCF72400C6466A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = MainWindow.xib; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* GLSpriteAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSpriteAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* GLSpriteAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLSpriteAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* GLSprite.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLSprite.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28FD14FC0DC6FC130079059D /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; + 28FD14FD0DC6FC130079059D /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = ""; }; + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* GLSprite_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSprite_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + AF5A94E91210DFC3003EF434 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + AF5A94EA1210DFC3003EF434 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + AF5A94EB1210DFC3003EF434 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + AF5A94EC1210DFC3003EF434 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + AF5A94ED1210DFC3003EF434 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + AF5A94EE1210DFC3003EF434 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + AF5A94EF1210DFC3003EF434 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */, + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28FD14FC0DC6FC130079059D /* EAGLView.h */, + 28FD14FD0DC6FC130079059D /* EAGLView.m */, + 1D3623240D0F684500981E51 /* GLSpriteAppDelegate.h */, + 1D3623250D0F684500981E51 /* GLSpriteAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GLSprite.app */, + ); + name = Products; + sourceTree = ""; + }; + 1BF0DBA10DDCF72400C6466A /* en.lproj */ = { + isa = PBXGroup; + children = ( + 1BF0DBA20DDCF72400C6466A /* MainWindow.xib */, + ); + path = en.lproj; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 1B76A63F0DCBB4F3003B05F2 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* GLSprite_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + AF5A94E81210DFC3003EF434 /* Images */, + 1BF0DBA10DDCF72400C6466A /* en.lproj */, + 1B62193D0DDBC27200C070EC /* Default.png */, + 1B7FD2370DCBBCF100E48ED5 /* Sprite.png */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + AF5A94E81210DFC3003EF434 /* Images */ = { + isa = PBXGroup; + children = ( + AF5A94E91210DFC3003EF434 /* Icon-72.png */, + AF5A94EA1210DFC3003EF434 /* Icon-Small-50.png */, + AF5A94EB1210DFC3003EF434 /* Icon-Small.png */, + AF5A94EC1210DFC3003EF434 /* Icon-Small@2x.png */, + AF5A94ED1210DFC3003EF434 /* Icon.png */, + AF5A94EE1210DFC3003EF434 /* Icon@2x.png */, + AF5A94EF1210DFC3003EF434 /* iTunesArtwork */, + ); + path = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GLSprite */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLSprite" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GLSprite; + productName = GLSprite; + productReference = 1D6058910D05DD3D006BFB54 /* GLSprite.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLSprite" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GLSprite */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1B7FD2380DCBBCF100E48ED5 /* Sprite.png in Resources */, + 1B62193E0DDBC27200C070EC /* Default.png in Resources */, + 1BF0DBA40DDCF72400C6466A /* MainWindow.xib in Resources */, + AF5A94F01210DFC3003EF434 /* Icon-72.png in Resources */, + AF5A94F11210DFC3003EF434 /* Icon-Small-50.png in Resources */, + AF5A94F21210DFC3003EF434 /* Icon-Small.png in Resources */, + AF5A94F31210DFC3003EF434 /* Icon-Small@2x.png in Resources */, + AF5A94F41210DFC3003EF434 /* Icon.png in Resources */, + AF5A94F51210DFC3003EF434 /* Icon@2x.png in Resources */, + AF5A94F61210DFC3003EF434 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* GLSpriteAppDelegate.m in Sources */, + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 1BF0DBA20DDCF72400C6466A /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 1BF0DBA30DDCF72400C6466A /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GLSprite_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = GLSprite; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GLSprite_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = GLSprite; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos3.1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLSprite" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLSprite" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GLSprite/GLSprite_Prefix.pch b/GLSprite/GLSprite_Prefix.pch new file mode 100644 index 0000000..27a13aa --- /dev/null +++ b/GLSprite/GLSprite_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'GLSprite' target in the 'GLSprite' project +// + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/GLSprite/Images/Icon-72.png b/GLSprite/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GLSprite/Images/Icon-72.png differ diff --git a/GLSprite/Images/Icon-Small-50.png b/GLSprite/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GLSprite/Images/Icon-Small-50.png differ diff --git a/GLSprite/Images/Icon-Small.png b/GLSprite/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GLSprite/Images/Icon-Small.png differ diff --git a/GLSprite/Images/Icon-Small@2x.png b/GLSprite/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GLSprite/Images/Icon-Small@2x.png differ diff --git a/GLSprite/Images/Icon.png b/GLSprite/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GLSprite/Images/Icon.png differ diff --git a/GLSprite/Images/Icon@2x.png b/GLSprite/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GLSprite/Images/Icon@2x.png differ diff --git a/GLSprite/Images/iTunesArtwork b/GLSprite/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GLSprite/Images/iTunesArtwork differ diff --git a/GLSprite/Info.plist b/GLSprite/Info.plist new file mode 100644 index 0000000..264824f --- /dev/null +++ b/GLSprite/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Icon.png + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.9 + LSRequiresIPhoneOS + + UIStatusBarHidden + + NSMainNibFile + MainWindow + CFBundleShortVersionString + + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + + diff --git a/GLSprite/ReadMe.txt b/GLSprite/ReadMe.txt new file mode 100644 index 0000000..4b8445e --- /dev/null +++ b/GLSprite/ReadMe.txt @@ -0,0 +1,73 @@ +### GLSprite ### + +================================================================================ +DESCRIPTION: + +The GLSprite sample application shows how to create a texture from an image. By looking at the code, you'll learn how to use Core Graphics to create a bitmap context and draw an image into the context. You'll then see how to use OpenGL ES to create a texture from the image data. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +GLSpriteAppDelegate.h +GLSpriteAppDelegate.m +The UIApplication delegate class, which is the central controller of the application. + +EAGLView.h +EAGLView.m +This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view content is basically an EAGL surface you render your OpenGL scene into. Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. + +main.m +The main entry point for the GLSprite application. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.9 +Upgraded project to build with the iOS 4.0 SDK + +Version 1.8 +Updated for iPhone OS 3.1: +Set texture parameters before creating the texture. This will save texture memory and texture loading time. +Use CADisplayLink as the preferred method for controlling animation timing, and fall back to NSTimer when running on a pre 3.1 device where CADisplayLink is not available. + +Version 1.7 +-Updated for and tested with iPhone OS 2.0. First public release. + +Version 1.6 +-Fixed typographical error. + +Version 1.5 +-Updated for Beta 6. There were changes to the EAGL API. +-Changed the status bar to black. +-Modified the Default.png file. + +Version 1.4 +-Updated for Beta 5. +-Restructured the application to use a xib file. +-Removed the Texture2D class. The texture is now created using data from a bitmap context. +-Changed the dimensions and case of the png file. + +Version 1.3 +-Updated for Beta 4. +-Changed the project setting for Code Signing. +-Removed the error that prevented the application from running in the simulator. + +Version 1.2 +-Updated for Beta 3. +-Updated art files + +Version 1.1 +Updated for Beta 2 + +================================================================================ +Copyright (C) 2009 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/GLSprite/Sprite.png b/GLSprite/Sprite.png new file mode 100755 index 0000000..66fe413 Binary files /dev/null and b/GLSprite/Sprite.png differ diff --git a/GLSprite/en.lproj/MainWindow.xib b/GLSprite/en.lproj/MainWindow.xib new file mode 100644 index 0000000..747f612 --- /dev/null +++ b/GLSprite/en.lproj/MainWindow.xib @@ -0,0 +1,213 @@ + + + + 512 + 9C7010 + 655 + 949.26 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + + + 1292 + + YES + + + 1292 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + 8 + + + + + + + YES + + YES + -1.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + + YES + + YES + + + YES + + + {{726, 594}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLSpriteAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + EAGLView + UIView + + IBProjectSource + Classes/EAGLView.h + + + + GLSpriteAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + EAGLView + UIWindow + + + + IBProjectSource + Classes/GLSpriteAppDelegate.h + + + + + 0 + GLSprite.xcodeproj + 3 + + diff --git a/GLSprite/main.m b/GLSprite/main.m new file mode 100644 index 0000000..09bb43a --- /dev/null +++ b/GLSprite/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: The main entry point for the GLSprite application. + + Version: 1.9 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GLTextureAtlas.zip b/GLTextureAtlas.zip new file mode 100644 index 0000000..73c1d6f Binary files /dev/null and b/GLTextureAtlas.zip differ diff --git a/GLTextureAtlas/Classes/EAGLView.h b/GLTextureAtlas/Classes/EAGLView.h new file mode 100644 index 0000000..3af1a11 --- /dev/null +++ b/GLTextureAtlas/Classes/EAGLView.h @@ -0,0 +1,100 @@ +/* + File: EAGLView.h + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import +#import + +#import "PVRTexture.h" + +/* +This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. +The view content is basically an EAGL surface you render your OpenGL scene into. +Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. +*/ +@interface EAGLView : UIView { + +@private + /* The pixel dimensions of the backbuffer */ + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + + /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ + GLuint viewRenderbuffer, viewFramebuffer; + + /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ + GLuint depthRenderbuffer; + + GLint widthScaleIndex, frameCount; //to simulate the fly effect + + GLuint textureAtlas; + PVRTexture *pvrTextureAtlas; + + Boolean init; + + BOOL animating; + BOOL displayLinkSupported; + NSInteger animationFrameInterval; + // Use of the CADisplayLink class is the preferred method for controlling your animation timing. + // CADisplayLink will link to the main display and fire every vsync when added to a given run-loop. + // The NSTimer class is used only as fallback when running on a pre 3.1 device where CADisplayLink + // isn't available. + id displayLink; + NSTimer *animationTimer; +} + +@property (readonly, nonatomic, getter=isAnimating) BOOL animating; +@property (nonatomic) NSInteger animationFrameInterval; + +- (void)startAnimation; +- (void)stopAnimation; +- (void)drawView; + +@end diff --git a/GLTextureAtlas/Classes/EAGLView.m b/GLTextureAtlas/Classes/EAGLView.m new file mode 100644 index 0000000..6db432d --- /dev/null +++ b/GLTextureAtlas/Classes/EAGLView.m @@ -0,0 +1,510 @@ +/* + File: EAGLView.m + Abstract: n/a + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +#import "EAGLView.h" +#import "Matrix4x4.h" + +#define USE_DEPTH_BUFFER 0 +#define USE_4_BIT_PVR 0 //if 0 use 2-bit pvr + +#define kAnimationSpeed 0.2 // (0, 1], the bigger the faster + +#define NUM_COLS 4 +#define NUM_ROWS 4 + +#define NUM_IMPOSTERS 40 + +#define CLAMP(min,x,max) (x < min ? min : (x > max ? max : x)) +#define DegreeToRadian(x) ((x) * M_PI / 180.0f) + +// get random float in [-1,1] +static inline float randf() { return (rand() % RAND_MAX) / (float)(RAND_MAX) * 2. - 1.; } + +typedef struct particle { + float x, y, z, t, v, tx, ty, tz; + int c; +} particle; + +particle butterflies[NUM_IMPOSTERS]; + + +// A class extension to declare private methods +@interface EAGLView () + +- (BOOL) createFramebuffer; +- (void) destroyFramebuffer; + +- (void) loadPVRTexture:(NSString *)name; + +@end + + +@implementation EAGLView + +@synthesize animating; +@dynamic animationFrameInterval; + +// You must implement this method ++ (Class)layerClass { + return [CAEAGLLayer class]; +} + + +//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder { + + if ((self = [super initWithCoder:coder])) { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if (!context || ![EAGLContext setCurrentContext:context]) { + [self release]; + return nil; + } + + animating = FALSE; + displayLinkSupported = FALSE; + animationFrameInterval = 1; + displayLink = nil; + animationTimer = nil; + + // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer + // class is used as fallback when it isn't available. + NSString *reqSysVer = @"3.1"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) + displayLinkSupported = TRUE; + + // load the texture atlas in the PVRTC format + if (USE_4_BIT_PVR) + [self loadPVRTexture:@"butterfly_4"]; + else //use 2-bit pvr + [self loadPVRTexture:@"butterfly_2"]; + + // precalc some random normals and velocities + int i; + for (i = 0; i < NUM_IMPOSTERS; i++) { + float x = randf(); + float y = randf(); + float z = randf(); + if (fabs(x<0.1) && fabs(y<0.1)) { + x += (x>0) ? 0.1 : -0.1; + y += (y>0) ? 0.1 : -0.1; + } + float m = 1.0/sqrtf( (x*x) + (y*y) + (z*z) ); + butterflies[i].x = x*m; + butterflies[i].y = y*m; + butterflies[i].z = z*m; + butterflies[i].t = 0; + butterflies[i].v = randf()/2.; butterflies[i].v += (butterflies[i].v > 0) ? 0.1 : -0.1; + butterflies[i].c = i % (NUM_ROWS*NUM_COLS); + } + } + + return self; +} + +- (void)loadPVRTexture:(NSString *)name +{ + glGenTextures(1, &textureAtlas); + glBindTexture(GL_TEXTURE_2D, textureAtlas); + + // setup texture parameters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + pvrTextureAtlas = [PVRTexture pvrTextureWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:@"pvr"]]; + [pvrTextureAtlas retain]; + + if (pvrTextureAtlas == nil) + NSLog(@"Failed to load %@.pvr", name); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +- (void)setupView +{ + glViewport(0, 0, backingWidth, backingHeight); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + GLfloat fov = 60.0f, zNear = 0.1f, zFar = 1000.0f, aspect = 1.5f; + GLfloat ymax = zNear * tanf(fov * M_PI / 360.0f); + GLfloat ymin = -ymax; + glFrustumf(ymin * aspect, ymax * aspect, ymin, ymax, zNear, zFar); + + glMatrixMode(GL_MODELVIEW); + + // enable GL states + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +int comp(const void *p1, const void *p2) +{ + float d = ((particle *)p1)->tz - ((particle *)p2)->tz; + if (d < 0) return -1; + if (d > 0) return 1; + return (int)p1 - (int)p2; +} + +- (void)drawView { + + GLint i = 0, j; + static GLfloat s = 1, sz = 1; + static GLfloat sanim = 0.001, szanim = 0.002; + static GLfloat widthScale[8] = { 1, 0.8, 0.6, 0.4, 0.2, 0.1, 0.6, 0.8 }; + + static GLfloat tex[NUM_COLS*NUM_ROWS][8]; + static GLushort indices_all[NUM_IMPOSTERS*6]; + + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glClearColor(0.7f, 0.9f, 0.6f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + if (!init) + { + // compute texture coordinates of each cell + for (i = 0; i < NUM_COLS*NUM_ROWS; i++) + { + GLint row = i / NUM_COLS; //y + GLint col = i % NUM_COLS; //x + + GLfloat left, right, top, bottom; + left = col * (1./NUM_COLS); + right = (col+1) * (1./NUM_COLS); + top = row * (1./NUM_ROWS); + bottom = (row+1) * (1./NUM_ROWS); + + // the order of the texture coordinates is: + //{left, bottom, right, bottom, left, top, right, top} + tex[i][0] = tex[i][4] = left; + tex[i][2] = tex[i][6] = right; + tex[i][5] = tex[i][7] = top; + tex[i][1] = tex[i][3] = bottom; + } + + // build the index array + for (i = 0; i < NUM_IMPOSTERS; i++) + { + // the first and last additional indices are added to create degenerated triangles + // between consistent quads. for example, we use the compact index array 0123*34*4567 + // to draw quad 0123 and 4567 using one draw call + indices_all[i*6] = i*4; + for (j=0; j<4; j++) + indices_all[i*6+j+1] = i*4+j; + indices_all[i*6+5] = i*4+3; + } + + init = YES; + } + + // SW transform point to find z order + for (i = 0; i < NUM_IMPOSTERS; i++) + { + float ax = DegreeToRadian(butterflies[i].x*butterflies[i].t); + float ay = DegreeToRadian(butterflies[i].y*butterflies[i].t); + float az = DegreeToRadian(butterflies[i].z*butterflies[i].t); + float cosx = cosf(ax), sinx = sinf(ax); + float cosy = cosf(ay), siny = sinf(ay); + float cosz = cosf(az), sinz = sinf(az); + float p1 = (sinz * butterflies[i].y + cosz * butterflies[i].x); + float p2 = (cosy * butterflies[i].z + siny * p1); + float p3 = (cosz * butterflies[i].y - sinz * butterflies[i].x); + butterflies[i].tx = cosy * p1 - siny * butterflies[i].z; + butterflies[i].ty = sinx * p2 + cosx * p3; + butterflies[i].tz = cosx * p2 - sinx * p3; + } + qsort(butterflies, NUM_IMPOSTERS, sizeof(particle), comp); + + // the interleaved array including position and texture coordinate data of all vertices + // first position (3 floats) then tex coord (2 floats) + // NOTE: we want every attribute to be 4-byte left aligned for best performance, + // so if you use shorts (2 bytes), padding may be needed to achieve that. + static GLfloat pos_tex_all[NUM_IMPOSTERS*4*(3+2)]; + + // now update the interleaved data array + for (i = 0; i < NUM_IMPOSTERS; i++) + { + // in order to batch the drawcalls into a single one, + // we have to drop usage of glMatrix/glTranslate/glRotate/glScale, + // and do the transformations ourselves. + + // rotation around z + GLfloat rotzDegree = butterflies[i].z * butterflies[i].t; + if (rotzDegree >= 60.0 || rotzDegree <= -60.0) + { + butterflies[i].v *= -1.0; + rotzDegree = CLAMP(-60.0, rotzDegree, 60.0); + } + GLfloat rotz = DegreeToRadian(rotzDegree); + + // scale along x + GLint ind = (i%2 == 0) ? widthScaleIndex : 7-widthScaleIndex; //add some noise + + // compute the transformation matrix + + GLfloat Tz[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -2, 1 }; + GLfloat S[16] = { widthScale[ind]*0.2, 0, 0, 0, 0, 0.2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; + GLfloat T[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, butterflies[i].tx*s, butterflies[i].ty*s, butterflies[i].tz*sz, 1 }; + GLfloat Rz[16] = { cosf(rotz), -sinf(rotz), 0, 0, sinf(rotz), cosf(rotz), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; + + GLfloat M[16]; + MatrixMultMatrix(S, Tz, M); + MatrixMultMatrix(T, M, M); + MatrixMultMatrix(Rz, M, M); + + // simple quad data + // 4D homogeneous coordinates (x,y,z,1) + GLfloat pos[] = { + -1,-1,0,1, 1,-1,0,1, -1,1,0,1, 1, 1,0,1, + }; + + // first position + GLint v; + for (v=0; v<4; v++) { + // apply the result transformation matrix on each vertex + MatrixMultVector(M, pos+v*4, pos_tex_all+i*20+v*5, 0); + } + + // then tex coord + for (j=0; j<8; j++) + { + GLint n = i*20 + (j/2)*5 + 3+j%2; + GLint c = butterflies[i].c; + pos_tex_all[n] = tex[c][j]; + } + + butterflies[i].t += butterflies[i].v; + } + + // bind the texture atlas ONCE + glBindTexture(GL_TEXTURE_2D, textureAtlas); + + glVertexPointer(3, GL_FLOAT, 5*sizeof(GLfloat), pos_tex_all); + glTexCoordPointer(2, GL_FLOAT, 5*sizeof(GLfloat), pos_tex_all+3); + + // draw all butterflies using ONE single call + glDrawElements(GL_TRIANGLE_STRIP, NUM_IMPOSTERS*6, GL_UNSIGNED_SHORT, indices_all); + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; + + glBindTexture(GL_TEXTURE_2D, 0); + + // update parameters + + s += sanim; + if ((s >= 1.5) || (s <= 1.0)) sanim *= -1.0; + + sz += szanim; + if ((sz >= 1.4) || (sz <= -1.2)) szanim *= -1.0; + + GLfloat speed = CLAMP(0, kAnimationSpeed, 1); + if (speed) { + GLint speedInv = 1./speed; + if (frameCount % speedInv == 0) { + // update width scale to simulate the fly effect + widthScaleIndex = widthScaleIndex < 7 ? widthScaleIndex+1 : 0; + } + frameCount ++; + } +} + + +- (void)layoutSubviews { + [EAGLContext setCurrentContext:context]; + [self destroyFramebuffer]; + [self createFramebuffer]; + [self setupView]; + [self drawView]; +} + + +- (BOOL)createFramebuffer { + + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + if (USE_DEPTH_BUFFER) { + glGenRenderbuffersOES(1, &depthRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + } + + if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + + +- (void)destroyFramebuffer { + + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if(depthRenderbuffer) { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + + +- (NSInteger) animationFrameInterval +{ + return animationFrameInterval; +} + +- (void) setAnimationFrameInterval:(NSInteger)frameInterval +{ + // Frame interval defines how many display frames must pass between each time the + // display link fires. The display link will only fire 30 times a second when the + // frame internal is two on a display that refreshes 60 times a second. The default + // frame interval setting of one will fire 60 times a second when the display refreshes + // at 60 times a second. A frame interval setting of less than one results in undefined + // behavior. + if (frameInterval >= 1) + { + animationFrameInterval = frameInterval; + + if (animating) + { + [self stopAnimation]; + [self startAnimation]; + } + } +} + +- (void) startAnimation +{ + if (!animating) + { + if (displayLinkSupported) + { + // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed + // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will + // not be called in system versions earlier than 3.1. + + displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView)]; + [displayLink setFrameInterval:animationFrameInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } + else + animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView) userInfo:nil repeats:TRUE]; + + animating = TRUE; + } +} + +- (void)stopAnimation +{ + if (animating) + { + if (displayLinkSupported) + { + [displayLink invalidate]; + displayLink = nil; + } + else + { + [animationTimer invalidate]; + animationTimer = nil; + } + + animating = FALSE; + } +} + +- (void)dealloc { + + // release the texture atlas + if (textureAtlas) { + glDeleteTextures(1, &textureAtlas); + textureAtlas = 0; + } + [pvrTextureAtlas release]; + pvrTextureAtlas = nil; + + if ([EAGLContext currentContext] == context) { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + [super dealloc]; +} + +@end diff --git a/GLTextureAtlas/Classes/GLTextureAtlasAppDelegate.h b/GLTextureAtlas/Classes/GLTextureAtlasAppDelegate.h new file mode 100644 index 0000000..910eab4 --- /dev/null +++ b/GLTextureAtlas/Classes/GLTextureAtlasAppDelegate.h @@ -0,0 +1,62 @@ +/* + File: GLTextureAtlasAppDelegate.h + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +#import + +@class EAGLView; + +@interface GLTextureAtlasAppDelegate : NSObject { + UIWindow *window; + EAGLView *glView; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet EAGLView *glView; + +@end + diff --git a/GLTextureAtlas/Classes/GLTextureAtlasAppDelegate.m b/GLTextureAtlas/Classes/GLTextureAtlasAppDelegate.m new file mode 100644 index 0000000..504d5cd --- /dev/null +++ b/GLTextureAtlas/Classes/GLTextureAtlasAppDelegate.m @@ -0,0 +1,84 @@ +/* + File: GLTextureAtlasAppDelegate.m + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "GLTextureAtlasAppDelegate.h" +#import "EAGLView.h" + +@implementation GLTextureAtlasAppDelegate + +@synthesize window; +@synthesize glView; + +- (void) applicationDidFinishLaunching:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void) applicationWillResignActive:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) applicationDidBecomeActive:(UIApplication *)application +{ + [glView startAnimation]; +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + [glView stopAnimation]; +} + +- (void) dealloc +{ + [window release]; + [glView release]; + + [super dealloc]; +} + +@end diff --git a/GLTextureAtlas/Classes/Matrix4x4.c b/GLTextureAtlas/Classes/Matrix4x4.c new file mode 100644 index 0000000..b590364 --- /dev/null +++ b/GLTextureAtlas/Classes/Matrix4x4.c @@ -0,0 +1,107 @@ +/* + File: Matrix4x4.c + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include "Matrix4x4.h" + +/* + NOTE: These functions are created for your convenience but the matrix algorithms + are not optimized. You are encouraged to do additional research on your own to + implement a more robust numerical algorithm. +*/ + +// GL matrix is column-major + +void MatrixMultMatrix(const float* M1, const float* M2, float* Mout) +{ + float res[16]; + res[0] = M1[0]*M2[0] + M1[4]*M2[1] + M1[8]*M2[2] + M1[12]*M2[3]; + res[4] = M1[0]*M2[4] + M1[4]*M2[5] + M1[8]*M2[6] + M1[12]*M2[7]; + res[8] = M1[0]*M2[8] + M1[4]*M2[9] + M1[8]*M2[10] + M1[12]*M2[11]; + res[12] = M1[0]*M2[12] + M1[4]*M2[13] + M1[8]*M2[14] + M1[12]*M2[15]; + + res[1] = M1[1]*M2[0] + M1[5]*M2[1] + M1[9]*M2[2] + M1[13]*M2[3]; + res[5] = M1[1]*M2[4] + M1[5]*M2[5] + M1[9]*M2[6] + M1[13]*M2[7]; + res[9] = M1[1]*M2[8] + M1[5]*M2[9] + M1[9]*M2[10] + M1[13]*M2[11]; + res[13] = M1[1]*M2[12] + M1[5]*M2[13] + M1[9]*M2[14] + M1[13]*M2[15]; + + res[2] = M1[2]*M2[0] + M1[6]*M2[1] + M1[10]*M2[2] + M1[14]*M2[3]; + res[6] = M1[2]*M2[4] + M1[6]*M2[5] + M1[10]*M2[6] + M1[14]*M2[7]; + res[10] = M1[2]*M2[8] + M1[6]*M2[9] + M1[10]*M2[10] + M1[14]*M2[11]; + res[14] = M1[2]*M2[12] + M1[6]*M2[13] + M1[10]*M2[14] + M1[14]*M2[15]; + + res[3] = M1[3]*M2[0] + M1[7]*M2[1] + M1[11]*M2[2] + M1[15]*M2[3]; + res[7] = M1[3]*M2[4] + M1[7]*M2[5] + M1[11]*M2[6] + M1[15]*M2[7]; + res[11] = M1[3]*M2[8] + M1[7]*M2[9] + M1[11]*M2[10] + M1[15]*M2[11]; + res[15] = M1[3]*M2[12] + M1[7]*M2[13] + M1[11]*M2[14] + M1[15]*M2[15]; + + int i; + for (i=0; i<16; i++) + Mout[i] = res[i]; +} + +void MatrixMultVector(const float* M, const float* v, float* vout, int voutIs4D) +{ + float res[4]; + res[0] = M[0]*v[0] + M[4]*v[1] + M[ 8]*v[2] + M[12]*v[3]; + res[1] = M[1]*v[0] + M[5]*v[1] + M[ 9]*v[2] + M[13]*v[3]; + res[2] = M[2]*v[0] + M[6]*v[1] + M[10]*v[2] + M[14]*v[3]; + res[3] = M[3]*v[0] + M[7]*v[1] + M[11]*v[2] + M[15]*v[3]; + + if (voutIs4D) { + vout[0] = res[0]; + vout[1] = res[1]; + vout[2] = res[2]; + vout[3] = res[3]; + } + else { + vout[0] = res[0] / res[3]; + vout[1] = res[1] / res[3]; + vout[2] = res[2] / res[3]; + } +} + + diff --git a/GLTextureAtlas/Classes/Matrix4x4.h b/GLTextureAtlas/Classes/Matrix4x4.h new file mode 100644 index 0000000..9848791 --- /dev/null +++ b/GLTextureAtlas/Classes/Matrix4x4.h @@ -0,0 +1,49 @@ +/* + File: Matrix4x4.h + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +void MatrixMultMatrix(const float* M1, const float* M2, float* Mout); +void MatrixMultVector(const float* M, const float* v, float* vout, int voutIs4D); \ No newline at end of file diff --git a/GLTextureAtlas/Classes/PVRTexture.h b/GLTextureAtlas/Classes/PVRTexture.h new file mode 100644 index 0000000..586476b --- /dev/null +++ b/GLTextureAtlas/Classes/PVRTexture.h @@ -0,0 +1,73 @@ +/* + File: PVRTexture.h + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import + +@interface PVRTexture : NSObject +{ + NSMutableArray *_imageData; + + //GLuint _name; + uint32_t _width, _height; + GLenum _internalFormat; + BOOL _hasAlpha; +} + +- (id)initWithContentsOfFile:(NSString *)path; +- (id)initWithContentsOfURL:(NSURL *)url; ++ (id)pvrTextureWithContentsOfFile:(NSString *)path; ++ (id)pvrTextureWithContentsOfURL:(NSURL *)url; + +//@property (readonly) GLuint name; +@property (readonly) uint32_t width; +@property (readonly) uint32_t height; +@property (readonly) GLenum internalFormat; +@property (readonly) BOOL hasAlpha; + +@end diff --git a/GLTextureAtlas/Classes/PVRTexture.m b/GLTextureAtlas/Classes/PVRTexture.m new file mode 100644 index 0000000..e6be248 --- /dev/null +++ b/GLTextureAtlas/Classes/PVRTexture.m @@ -0,0 +1,274 @@ +/* + File: PVRTexture.m + Abstract: + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PVRTexture.h" + +#define PVR_TEXTURE_FLAG_TYPE_MASK 0xff + +static char gPVRTexIdentifier[4] = "PVR!"; + +enum +{ + kPVRTextureFlagTypePVRTC_2 = 24, + kPVRTextureFlagTypePVRTC_4 +}; + +typedef struct _PVRTexHeader +{ + uint32_t headerLength; + uint32_t height; + uint32_t width; + uint32_t numMipmaps; + uint32_t flags; + uint32_t dataLength; + uint32_t bpp; + uint32_t bitmaskRed; + uint32_t bitmaskGreen; + uint32_t bitmaskBlue; + uint32_t bitmaskAlpha; + uint32_t pvrTag; + uint32_t numSurfs; +} PVRTexHeader; + + +@implementation PVRTexture + +//@synthesize name = _name; +@synthesize width = _width; +@synthesize height = _height; +@synthesize internalFormat = _internalFormat; +@synthesize hasAlpha = _hasAlpha; + + +- (BOOL)unpackPVRData:(NSData *)data +{ + BOOL success = FALSE; + PVRTexHeader *header = NULL; + uint32_t flags, pvrTag; + uint32_t dataLength = 0, dataOffset = 0, dataSize = 0; + uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; + uint32_t width = 0, height = 0, bpp = 4; + uint8_t *bytes = NULL; + uint32_t formatFlags; + + header = (PVRTexHeader *)[data bytes]; + + pvrTag = CFSwapInt32LittleToHost(header->pvrTag); + + if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) || + gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) || + gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) || + gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff)) + { + return FALSE; + } + + flags = CFSwapInt32LittleToHost(header->flags); + formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK; + + if (formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2) + { + [_imageData removeAllObjects]; + + if (formatFlags == kPVRTextureFlagTypePVRTC_4) + _internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + else if (formatFlags == kPVRTextureFlagTypePVRTC_2) + _internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + + _width = width = CFSwapInt32LittleToHost(header->width); + _height = height = CFSwapInt32LittleToHost(header->height); + + if (CFSwapInt32LittleToHost(header->bitmaskAlpha)) + _hasAlpha = TRUE; + else + _hasAlpha = FALSE; + + dataLength = CFSwapInt32LittleToHost(header->dataLength); + + bytes = ((uint8_t *)[data bytes]) + sizeof(PVRTexHeader); + + // Calculate the data size for each texture level and respect the minimum number of blocks + while (dataOffset < dataLength) + { + if (formatFlags == kPVRTextureFlagTypePVRTC_4) + { + blockSize = 4 * 4; // Pixel by pixel block size for 4bpp + widthBlocks = width / 4; + heightBlocks = height / 4; + bpp = 4; + } + else + { + blockSize = 8 * 4; // Pixel by pixel block size for 2bpp + widthBlocks = width / 8; + heightBlocks = height / 4; + bpp = 2; + } + + // Clamp to minimum number of blocks + if (widthBlocks < 2) + widthBlocks = 2; + if (heightBlocks < 2) + heightBlocks = 2; + + dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8); + + [_imageData addObject:[NSData dataWithBytes:bytes+dataOffset length:dataSize]]; + + dataOffset += dataSize; + + width = MAX(width >> 1, 1); + height = MAX(height >> 1, 1); + } + + success = TRUE; + } + + return success; +} + + +- (BOOL)createGLTexture +{ + int width = _width; + int height = _height; + NSData *data; + GLenum err; + + /*if ([_imageData count] > 0) + { + if (_name != 0) + glDeleteTextures(1, &_name); + + glGenTextures(1, &_name); + glBindTexture(GL_TEXTURE_2D, _name); + }*/ + + for (int i=0; i < [_imageData count]; i++) + { + data = [_imageData objectAtIndex:i]; + glCompressedTexImage2D(GL_TEXTURE_2D, i, _internalFormat, width, height, 0, [data length], [data bytes]); + + err = glGetError(); + if (err != GL_NO_ERROR) + { + NSLog(@"Error uploading compressed texture level: %d. glError: 0x%04X", i, err); + return FALSE; + } + + width = MAX(width >> 1, 1); + height = MAX(height >> 1, 1); + } + + [_imageData removeAllObjects]; + + return TRUE; +} + + +- (id)initWithContentsOfFile:(NSString *)path +{ + if (self = [super init]) + { + NSData *data = [NSData dataWithContentsOfFile:path]; + + _imageData = [[NSMutableArray alloc] initWithCapacity:10]; + + //_name = 0; + _width = _height = 0; + _internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + _hasAlpha = FALSE; + + if (!data || ![self unpackPVRData:data] || ![self createGLTexture]) + { + [self release]; + self = nil; + } + } + + return self; +} + + +- (id)initWithContentsOfURL:(NSURL *)url +{ + if (![url isFileURL]) + { + [self release]; + return nil; + } + + return [self initWithContentsOfFile:[url path]]; +} + + ++ (id)pvrTextureWithContentsOfFile:(NSString *)path +{ + return [[[self alloc] initWithContentsOfFile:path] autorelease]; +} + + ++ (id)pvrTextureWithContentsOfURL:(NSURL *)url +{ + if (![url isFileURL]) + return nil; + + return [PVRTexture pvrTextureWithContentsOfFile:[url path]]; +} + + +- (void)dealloc +{ + [_imageData release]; + + /*if (_name != 0) + glDeleteTextures(1, &_name);*/ + + [super dealloc]; +} + +@end diff --git a/GLTextureAtlas/GLTextureAtlas-Info.plist b/GLTextureAtlas/GLTextureAtlas-Info.plist new file mode 100644 index 0000000..062da18 --- /dev/null +++ b/GLTextureAtlas/GLTextureAtlas-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.5 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/GLTextureAtlas/GLTextureAtlas.xcodeproj/lsang.mode1v3 b/GLTextureAtlas/GLTextureAtlas.xcodeproj/lsang.mode1v3 new file mode 100644 index 0000000..c01c155 --- /dev/null +++ b/GLTextureAtlas/GLTextureAtlas.xcodeproj/lsang.mode1v3 @@ -0,0 +1,1405 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + AF325C700F97EB66003E4A3A + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + buildOrClean + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 270 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + 29B97315FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + 29B97323FDCFA39411CA2CEA + 19C28FACFE9D520D11CA2CBB + 1C37FBAC04509CD000000102 + AFFFAAAD1188F65000375290 + AFFFAAC11188F87400375290 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {270, 1265}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {287, 1283}} + GroupTreeTableConfiguration + + MainColumn + 270 + + RubberWindowFrame + 397 241 1576 1324 0 0 2560 1578 + + Module + PBXSmartGroupTreeModule + Proportion + 287pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + ReadMe.txt + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + ReadMe.txt + _historyCapacity + 0 + bookmark + AFFFAAD41188F8B500375290 + history + + AF3319160FF196B900D04241 + AFFC670C1072C39C008E3145 + AFFC670D1072C39C008E3145 + AFFC670E1072C39C008E3145 + AFFC670F1072C39C008E3145 + AFFC67101072C39C008E3145 + AFFC67111072C39C008E3145 + AFFC67121072C39C008E3145 + AFFC67131072C39C008E3145 + AFFC67141072C39C008E3145 + AFFC67151072C39C008E3145 + AF9BDC9611498AE100664AB2 + AFFFAAC21188F87400375290 + AFCCCB15115194D400430FE2 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1284, 1151}} + RubberWindowFrame + 397 241 1576 1324 0 0 2560 1578 + + Module + PBXNavigatorGroup + Proportion + 1151pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 1156}, {1284, 127}} + RubberWindowFrame + 397 241 1576 1324 0 0 2560 1578 + + Module + XCDetailModule + Proportion + 127pt + + + Proportion + 1284pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + AFFFAAC41188F87400375290 + 1CE0B1FE06471DED0097A5F4 + AFFFAAC51188F87400375290 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 1C530D57069F1CE1000CFCEE + AFFFAACE1188F87400375290 + AFFFAACF1188F87400375290 + 1C78EAAD065D492600B07095 + 1CD10A99069EF8BA00B06720 + AF325C710F97EB66003E4A3A + /Users/lsang/DTS/SampleCodeEdit/samplecode/G/GLTextureAtlas/GLTextureAtlas.xcodeproj + + WindowString + 397 241 1576 1324 0 0 2560 1578 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 46 1005 500 500 0 0 2560 1578 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 46 1005 500 500 0 0 2560 1578 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + AF325C710F97EB66003E4A3A + AFFFAAC61188F87400375290 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowString + 46 1005 500 500 0 0 2560 1578 + WindowToolGUID + AF325C710F97EB66003E4A3A + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 53 1093 694 422 0 0 2560 1578 + + RubberWindowFrame + 53 1093 694 422 0 0 2560 1578 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + AFFFAAC71188F87400375290 + 1C162984064C10D400B95A72 + AFFFAAC81188F87400375290 + AFFFAAC91188F87400375290 + AFFFAACA1188F87400375290 + AFFFAACB1188F87400375290 + AFFFAACC1188F87400375290 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 53 1093 694 422 0 0 2560 1578 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {929, 174}} + RubberWindowFrame + 67 738 929 717 0 0 2560 1578 + + Module + PBXNavigatorGroup + Proportion + 929pt + + + Proportion + 174pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 179}, {929, 497}} + RubberWindowFrame + 67 738 929 717 0 0 2560 1578 + + Module + PBXProjectFindModule + Proportion + 497pt + + + Proportion + 676pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + AFFFAAD21188F8B200375290 + AFFFAAD31188F8B200375290 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 67 738 929 717 0 0 2560 1578 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {754, 423}} + RubberWindowFrame + 366 866 754 464 0 0 2560 1578 + + Module + PBXDebugCLIModule + Proportion + 423pt + + + Proportion + 423pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + AFFFAACD1188F87400375290 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 366 866 754 464 0 0 2560 1578 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/GLTextureAtlas/GLTextureAtlas.xcodeproj/project.pbxproj b/GLTextureAtlas/GLTextureAtlas.xcodeproj/project.pbxproj new file mode 100755 index 0000000..e667814 --- /dev/null +++ b/GLTextureAtlas/GLTextureAtlas.xcodeproj/project.pbxproj @@ -0,0 +1,357 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 186FBE8C11CADF55000061EC /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 186FBE8A11CADF55000061EC /* MainWindow.xib */; }; + 18A6140211D3D62F0078F8B4 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18A613FF11D3D62F0078F8B4 /* Icon-72.png */; }; + 18A6140311D3D62F0078F8B4 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18A6140011D3D62F0078F8B4 /* Icon-Small-50.png */; }; + 18A6140411D3D62F0078F8B4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18A6140111D3D62F0078F8B4 /* iTunesArtwork */; }; + 18A6144211D3FC580078F8B4 /* butterfly.png in Resources */ = {isa = PBXBuildFile; fileRef = 18A6144111D3FC580078F8B4 /* butterfly.png */; }; + 18F7177511CAC9B100EF110D /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18F7177011CAC9B100EF110D /* Icon-Small.png */; }; + 18F7177611CAC9B100EF110D /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18F7177111CAC9B100EF110D /* Icon-Small@2x.png */; }; + 18F7177711CAC9B100EF110D /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18F7177211CAC9B100EF110D /* Icon.png */; }; + 18F7177811CAC9B100EF110D /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18F7177311CAC9B100EF110D /* Icon@2x.png */; }; + 1D3623260D0F684500981E51 /* GLTextureAtlasAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* GLTextureAtlasAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28FD14FD0DC6FC130079059D /* EAGLView.m */; }; + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; }; + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; }; + AF325C0E0F97E8B1003E4A3A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF325C0D0F97E8B1003E4A3A /* CoreGraphics.framework */; }; + AFC141C40FB0B196001B158B /* PVRTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = AFC141C30FB0B196001B158B /* PVRTexture.m */; }; + AFC143E40FB0EACD001B158B /* Matrix4x4.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC143E20FB0EACD001B158B /* Matrix4x4.c */; }; + AFFD85CC11D54E1F00181FB0 /* butterfly_2.pvr in Resources */ = {isa = PBXBuildFile; fileRef = AFFD85CA11D54E1F00181FB0 /* butterfly_2.pvr */; }; + AFFD85CD11D54E1F00181FB0 /* butterfly_4.pvr in Resources */ = {isa = PBXBuildFile; fileRef = AFFD85CB11D54E1F00181FB0 /* butterfly_4.pvr */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 186FBE8B11CADF55000061EC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 18A613FF11D3D62F0078F8B4 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18A6140011D3D62F0078F8B4 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18A6140111D3D62F0078F8B4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 18A6144111D3FC580078F8B4 /* butterfly.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = butterfly.png; path = images/butterfly.png; sourceTree = ""; }; + 18F7177011CAC9B100EF110D /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18F7177111CAC9B100EF110D /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18F7177211CAC9B100EF110D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18F7177311CAC9B100EF110D /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* GLTextureAtlasAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLTextureAtlasAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* GLTextureAtlasAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLTextureAtlasAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* GLTextureAtlas.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLTextureAtlas.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 28FD14FC0DC6FC130079059D /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; + 28FD14FD0DC6FC130079059D /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = ""; }; + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* GLTextureAtlas_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLTextureAtlas_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* GLTextureAtlas-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GLTextureAtlas-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + AF28F90E1061A29900B93E5C /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + AF325C0D0F97E8B1003E4A3A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + AFC141C20FB0B196001B158B /* PVRTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTexture.h; sourceTree = ""; }; + AFC141C30FB0B196001B158B /* PVRTexture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PVRTexture.m; sourceTree = ""; }; + AFC143E20FB0EACD001B158B /* Matrix4x4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Matrix4x4.c; sourceTree = ""; }; + AFC143E30FB0EACD001B158B /* Matrix4x4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Matrix4x4.h; sourceTree = ""; }; + AFFD85CA11D54E1F00181FB0 /* butterfly_2.pvr */ = {isa = PBXFileReference; lastKnownFileType = file; name = butterfly_2.pvr; path = images/butterfly_2.pvr; sourceTree = ""; }; + AFFD85CB11D54E1F00181FB0 /* butterfly_4.pvr */ = {isa = PBXFileReference; lastKnownFileType = file; name = butterfly_4.pvr; path = images/butterfly_4.pvr; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */, + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */, + AF325C0E0F97E8B1003E4A3A /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + AFC143E30FB0EACD001B158B /* Matrix4x4.h */, + AFC143E20FB0EACD001B158B /* Matrix4x4.c */, + AFC141C20FB0B196001B158B /* PVRTexture.h */, + AFC141C30FB0B196001B158B /* PVRTexture.m */, + 28FD14FC0DC6FC130079059D /* EAGLView.h */, + 28FD14FD0DC6FC130079059D /* EAGLView.m */, + 1D3623240D0F684500981E51 /* GLTextureAtlasAppDelegate.h */, + 1D3623250D0F684500981E51 /* GLTextureAtlasAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GLTextureAtlas.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + AF28F90E1061A29900B93E5C /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* GLTextureAtlas_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + AFFD85CA11D54E1F00181FB0 /* butterfly_2.pvr */, + AFFD85CB11D54E1F00181FB0 /* butterfly_4.pvr */, + 18A6144111D3FC580078F8B4 /* butterfly.png */, + 18A613FF11D3D62F0078F8B4 /* Icon-72.png */, + 18A6140011D3D62F0078F8B4 /* Icon-Small-50.png */, + 18A6140111D3D62F0078F8B4 /* iTunesArtwork */, + 186FBE8A11CADF55000061EC /* MainWindow.xib */, + 18F7177011CAC9B100EF110D /* Icon-Small.png */, + 18F7177111CAC9B100EF110D /* Icon-Small@2x.png */, + 18F7177211CAC9B100EF110D /* Icon.png */, + 18F7177311CAC9B100EF110D /* Icon@2x.png */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* GLTextureAtlas-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + AF325C0D0F97E8B1003E4A3A /* CoreGraphics.framework */, + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GLTextureAtlas */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLTextureAtlas" */; + buildPhases = ( + AFC141D20FB0B1F3001B158B /* ShellScript */, + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GLTextureAtlas; + productName = GLTextureAtlas; + productReference = 1D6058910D05DD3D006BFB54 /* GLTextureAtlas.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLTextureAtlas" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GLTextureAtlas */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + 18F7177511CAC9B100EF110D /* Icon-Small.png in Resources */, + 18F7177611CAC9B100EF110D /* Icon-Small@2x.png in Resources */, + 18F7177711CAC9B100EF110D /* Icon.png in Resources */, + 18F7177811CAC9B100EF110D /* Icon@2x.png in Resources */, + 186FBE8C11CADF55000061EC /* MainWindow.xib in Resources */, + 18A6140211D3D62F0078F8B4 /* Icon-72.png in Resources */, + 18A6140311D3D62F0078F8B4 /* Icon-Small-50.png in Resources */, + 18A6140411D3D62F0078F8B4 /* iTunesArtwork in Resources */, + 18A6144211D3FC580078F8B4 /* butterfly.png in Resources */, + AFFD85CC11D54E1F00181FB0 /* butterfly_2.pvr in Resources */, + AFFD85CD11D54E1F00181FB0 /* butterfly_4.pvr in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + AFC141D20FB0B1F3001B158B /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + $SRCROOT/images/butterfly.png, + ); + outputPaths = ( + $SRCROOT/images/butterfly_2.pvr, + $SRCROOT/images/butterfly_4.pvr, + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "xcrun -sdk iphoneos texturetool -e PVRTC --bits-per-pixel-2 -o \"$SRCROOT/images/butterfly_2.pvr\" -f PVR \"$SRCROOT/images/butterfly.png\"\nxcrun -sdk iphoneos texturetool -e PVRTC --bits-per-pixel-4 -o \"$SRCROOT/images/butterfly_4.pvr\" -f PVR \"$SRCROOT/images/butterfly.png\""; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* GLTextureAtlasAppDelegate.m in Sources */, + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */, + AFC141C40FB0B196001B158B /* PVRTexture.m in Sources */, + AFC143E40FB0EACD001B158B /* Matrix4x4.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 186FBE8A11CADF55000061EC /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 186FBE8B11CADF55000061EC /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GLTextureAtlas_Prefix.pch; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "GLTextureAtlas-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PRODUCT_NAME = GLTextureAtlas; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GLTextureAtlas_Prefix.pch; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "GLTextureAtlas-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PRODUCT_NAME = GLTextureAtlas; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GLTextureAtlas" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GLTextureAtlas" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GLTextureAtlas/GLTextureAtlas_Prefix.pch b/GLTextureAtlas/GLTextureAtlas_Prefix.pch new file mode 100644 index 0000000..b9c3075 --- /dev/null +++ b/GLTextureAtlas/GLTextureAtlas_Prefix.pch @@ -0,0 +1,52 @@ +/* + + File: GLTextureAtlas_Prefix.pch + + Abstract: The prefix file. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009-2010 Apple Inc. All Rights Reserved. + +*/ + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/GLTextureAtlas/MainWindow.xib b/GLTextureAtlas/MainWindow.xib new file mode 100644 index 0000000..db0c422 --- /dev/null +++ b/GLTextureAtlas/MainWindow.xib @@ -0,0 +1,233 @@ + + + + 768 + 10A288 + 715 + 1010 + 411.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 46 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + + -1 + + + File's Owner + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLTextureAtlasAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 9 + + + + YES + + EAGLView + UIView + + IBProjectSource + Classes/EAGLView.h + + + + GLTextureAtlasAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + EAGLView + UIWindow + + + + IBProjectSource + Classes/GLTextureAtlasAppDelegate.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + GLTextureAtlas.xcodeproj + 3 + + diff --git a/GLTextureAtlas/ReadMe.txt b/GLTextureAtlas/ReadMe.txt new file mode 100644 index 0000000..209baff --- /dev/null +++ b/GLTextureAtlas/ReadMe.txt @@ -0,0 +1,69 @@ +GLTextureAtlas + +================================================================================ +DESCRIPTION: + +This sample demonstrates how to use a texture atlas to draw multiple objects with different textures simultaneously using OpenGL ES. + +It shows how to: + * create PVR textures in an Xcode project build phase using texturetool; + * load a PVR texture and display it using OpenGL ES; + * create interleaved (tightly packed) vertex array; + * join triangle strips together by adding in degenerated triangles; + * compute 3D transformations using matrices and homogeneous coordinates (x,y,z,1). + +This sample also uses some unrelated techniques, including random number generators, and depth-sorted blended particle system. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +Matrix4x4.h +Matrix4x4.c +Functions to do simple 4x4 matrix calculations, including matrix*matrix and matrix*vector. + +PVRTexture.h +PVRTexture.m +The PVRTexture class is responsible for loading .pvr files generated by texturetool. + +EAGLView.h +EAGLView.m +The EAGLView class is a UIView subclass that renders OpenGL scene. It demonstrates how to bind a texture atlas once, and draw multiple objects with different textures using one draw call. + +GLTextureAtlasAppDelegate.h +GLTextureAtlasAppDelegate.m +The GLTextureAtlasAppDelegate class is the app delegate that ties everything together. + +butterfly_2.pvr +butterfly_4.pvr +These are the pvr files generated from the butterfly.png image by the "Run Script" build phase. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.5 +Changed deployment target back to iPhone OS 3.2 and added CFBundleIconFiles in Info.plist. + +Version 1.4 +Upgraded project to build with the iOS 4 SDK. + +Version 1.3 +Fixed a bug when running in the simulator. + +Version 1.2 +Modified the script so that it works regardless where texturetool is installed. + +Version 1.1 +Updated for iPhone OS 3.1. Use CADisplayLink as the preferred method for controlling animation timing, and fall back to NSTimer when running on a pre 3.1 device where CADisplayLink is not available. + +================================================================================ +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/GLTextureAtlas/en.lproj/MainWindow.xib b/GLTextureAtlas/en.lproj/MainWindow.xib new file mode 100644 index 0000000..db0c422 --- /dev/null +++ b/GLTextureAtlas/en.lproj/MainWindow.xib @@ -0,0 +1,233 @@ + + + + 768 + 10A288 + 715 + 1010 + 411.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 46 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + + -1 + + + File's Owner + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GLTextureAtlasAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 9 + + + + YES + + EAGLView + UIView + + IBProjectSource + Classes/EAGLView.h + + + + GLTextureAtlasAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + EAGLView + UIWindow + + + + IBProjectSource + Classes/GLTextureAtlasAppDelegate.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + GLTextureAtlas.xcodeproj + 3 + + diff --git a/GLTextureAtlas/images/Icon-72.png b/GLTextureAtlas/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GLTextureAtlas/images/Icon-72.png differ diff --git a/GLTextureAtlas/images/Icon-Small-50.png b/GLTextureAtlas/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GLTextureAtlas/images/Icon-Small-50.png differ diff --git a/GLTextureAtlas/images/Icon-Small.png b/GLTextureAtlas/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GLTextureAtlas/images/Icon-Small.png differ diff --git a/GLTextureAtlas/images/Icon-Small@2x.png b/GLTextureAtlas/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GLTextureAtlas/images/Icon-Small@2x.png differ diff --git a/GLTextureAtlas/images/Icon.png b/GLTextureAtlas/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GLTextureAtlas/images/Icon.png differ diff --git a/GLTextureAtlas/images/Icon@2x.png b/GLTextureAtlas/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GLTextureAtlas/images/Icon@2x.png differ diff --git a/GLTextureAtlas/images/butterfly.png b/GLTextureAtlas/images/butterfly.png new file mode 100755 index 0000000..1326280 Binary files /dev/null and b/GLTextureAtlas/images/butterfly.png differ diff --git a/GLTextureAtlas/images/iTunesArtwork b/GLTextureAtlas/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GLTextureAtlas/images/iTunesArtwork differ diff --git a/GLTextureAtlas/main.m b/GLTextureAtlas/main.m new file mode 100644 index 0000000..8b3bfb6 --- /dev/null +++ b/GLTextureAtlas/main.m @@ -0,0 +1,57 @@ +/* + + File: main.m + + Abstract: The main file. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009-2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/GenericKeychain.zip b/GenericKeychain.zip new file mode 100644 index 0000000..8b141ca Binary files /dev/null and b/GenericKeychain.zip differ diff --git a/GenericKeychain/Classes/AppDelegate.h b/GenericKeychain/Classes/AppDelegate.h new file mode 100755 index 0000000..3fc2964 --- /dev/null +++ b/GenericKeychain/Classes/AppDelegate.h @@ -0,0 +1,70 @@ +/* + File: AppDelegate.h + Abstract: + Application delegate, loaded with MainWindow nib and does basic UI + setup. Also creates the keychain item wrapper objects. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class KeychainItemWrapper, DetailViewController; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navigationController; + DetailViewController *detailViewController; + KeychainItemWrapper *passwordItem; + KeychainItemWrapper *accountNumberItem; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController; +@property (nonatomic, retain) KeychainItemWrapper *passwordItem; +@property (nonatomic, retain) KeychainItemWrapper *accountNumberItem; + +@end diff --git a/GenericKeychain/Classes/AppDelegate.m b/GenericKeychain/Classes/AppDelegate.m new file mode 100755 index 0000000..aa84b2e --- /dev/null +++ b/GenericKeychain/Classes/AppDelegate.m @@ -0,0 +1,86 @@ +/* + File: AppDelegate.m + Abstract: + Application delegate, loaded with MainWindow nib and does basic UI + setup. Also creates the keychain item wrapper objects. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "DetailViewController.h" +#import "KeychainItemWrapper.h" + +@implementation AppDelegate + +@synthesize window, navigationController, detailViewController, passwordItem, accountNumberItem; + +- (void)dealloc +{ + [detailViewController release]; + [navigationController release]; + [window release]; + [passwordItem release]; + [accountNumberItem release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Password" accessGroup:nil]; + self.passwordItem = wrapper; + detailViewController.passwordItem = wrapper; + [wrapper release]; + + wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Account Number" accessGroup:@"YOUR_APP_ID_HERE.com.yourcompany.GenericKeychainSuite"]; + self.accountNumberItem = wrapper; + detailViewController.accountNumberItem = wrapper; + [wrapper release]; + + [window addSubview:navigationController.view]; + [window makeKeyAndVisible]; +} + +@end diff --git a/GenericKeychain/Classes/DetailViewController.h b/GenericKeychain/Classes/DetailViewController.h new file mode 100755 index 0000000..090ba64 --- /dev/null +++ b/GenericKeychain/Classes/DetailViewController.h @@ -0,0 +1,73 @@ +/* + File: DetailViewController.h + Abstract: + Controller for editing text view data. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class EditorController; +@class KeychainItemWrapper; + +@interface DetailViewController : UIViewController +{ + UITableView *tableView; + EditorController *textFieldController; + KeychainItemWrapper *passwordItem; + KeychainItemWrapper *accountNumberItem; +} + +@property (nonatomic, retain) IBOutlet UITableView *tableView; +@property (nonatomic, retain) IBOutlet EditorController *textFieldController; +@property (nonatomic, retain) KeychainItemWrapper *passwordItem; +@property (nonatomic, retain) KeychainItemWrapper *accountNumberItem; + ++ (NSString *)titleForSection:(NSInteger)section; ++ (id)secAttrForSection:(NSInteger)section; + +- (IBAction)resetKeychain:(id)sender; + +@end diff --git a/GenericKeychain/Classes/DetailViewController.m b/GenericKeychain/Classes/DetailViewController.m new file mode 100755 index 0000000..6f1b5a4 --- /dev/null +++ b/GenericKeychain/Classes/DetailViewController.m @@ -0,0 +1,306 @@ +/* + File: DetailViewController.m + Abstract: + Controller for editing text view data. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +#import "DetailViewController.h" +#import "KeychainItemWrapper.h" +#import "EditorController.h" + +enum { + kUsernameSection = 0, + kPasswordSection, + kAccountNumberSection, + kShowCleartextSection +}; + +// Defined UI constants. +static NSInteger kPasswordTag = 2; // Tag table view cells that contain a text field to support secure text entry. + +@implementation DetailViewController + +@synthesize tableView, textFieldController, passwordItem, accountNumberItem; + ++ (NSString *)titleForSection:(NSInteger)section +{ + switch (section) + { + case kUsernameSection: return NSLocalizedString(@"Username", @""); + case kPasswordSection: return NSLocalizedString(@"Password", @""); + case kAccountNumberSection: return NSLocalizedString(@"Account Number", @""); + } + return nil; +} + ++ (id)secAttrForSection:(NSInteger)section +{ + switch (section) + { + case kUsernameSection: return (id)kSecAttrAccount; + case kPasswordSection: return (id)kSecValueData; + case kAccountNumberSection: return (id)kSecValueData; + } + return nil; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) + { + // Title displayed by the navigation controller. + self.title = @"Keychain"; + } + return self; +} + +- (void)dealloc +{ + // Release allocated resources. + [tableView release]; + [textFieldController release]; + [passwordItem release]; + [accountNumberItem release]; + [super dealloc]; +} + +- (void)awakeFromNib { + self.navigationItem.rightBarButtonItem = self.editButtonItem; + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; +} + +- (void)switchAction:(id)sender +{ + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: + [NSIndexPath indexPathForRow:0 inSection:kPasswordSection]]; + UITextField *textField = (UITextField *) [cell.contentView viewWithTag:kPasswordTag]; + textField.secureTextEntry = ![sender isOn]; + + cell = [self.tableView cellForRowAtIndexPath: + [NSIndexPath indexPathForRow:0 inSection:kAccountNumberSection]]; + textField = (UITextField *) [cell.contentView viewWithTag:kPasswordTag]; + textField.secureTextEntry = ![sender isOn]; +} + +// Action sheet delegate method. +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + // the user clicked one of the OK/Cancel buttons + if (buttonIndex == 0) + { + [passwordItem resetKeychainItem]; + [accountNumberItem resetKeychainItem]; + [self.tableView reloadData]; + } +} + +- (IBAction)resetKeychain:(id)sender +{ + // open a dialog with an OK and cancel button + UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Reset Generic Keychain Item?" + delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"OK" otherButtonTitles:nil]; + actionSheet.actionSheetStyle = UIActionSheetStyleDefault; + [actionSheet showInView:self.view]; + [actionSheet release]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [tableView reloadData]; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated +{ + [super setEditing:editing animated:animated]; + [tableView reloadData]; +} + +#pragma mark - +#pragma mark Methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv +{ + // 4 sections, one for each property and one for the switch + return 4; +} + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + // Only one row for each section + return 1; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section +{ + return (section == kAccountNumberSection) ? 48.0 : 0.0; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [DetailViewController titleForSection:section]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + NSString *title = nil; + + if (section == kAccountNumberSection) + { + title = NSLocalizedString(@"AccountNumberShared", @""); + } + + return title; +} + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kUsernameCellIdentifier = @"UsernameCell"; + static NSString *kPasswordCellIdentifier = @"PasswordCell"; + static NSString *kSwitchCellIdentifier = @"SwitchCell"; + + UITableViewCell *cell = nil; + + switch (indexPath.section) + { + case kUsernameSection: + { + cell = [aTableView dequeueReusableCellWithIdentifier:kUsernameCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kUsernameCellIdentifier] autorelease]; + } + + cell.textLabel.text = [passwordItem objectForKey:[DetailViewController secAttrForSection:indexPath.section]]; + cell.accessoryType = (self.editing) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + break; + } + + case kPasswordSection: + case kAccountNumberSection: + { + UITextField *textField = nil; + + cell = [aTableView dequeueReusableCellWithIdentifier:kPasswordCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kPasswordCellIdentifier] autorelease]; + + textField = [[UITextField alloc] initWithFrame:CGRectInset(cell.contentView.bounds, 10, 10)]; + textField.tag = kPasswordTag; + textField.font = [UIFont systemFontOfSize:17.0]; + + // prevent editing + textField.enabled = NO; + + // display contents as bullets rather than text + textField.secureTextEntry = YES; + + [cell.contentView addSubview:textField]; + [textField release]; + } + else { + textField = (UITextField *) [cell.contentView viewWithTag:kPasswordTag]; + } + + KeychainItemWrapper *wrapper = (indexPath.section == kPasswordSection) ? passwordItem : accountNumberItem; + textField.text = [wrapper objectForKey:[DetailViewController secAttrForSection:indexPath.section]]; + cell.accessoryType = (self.editing) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + break; + } + + case kShowCleartextSection: + { + cell = [aTableView dequeueReusableCellWithIdentifier:kSwitchCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kSwitchCellIdentifier] autorelease]; + + cell.textLabel.text = NSLocalizedString(@"Show Cleartext", @""); + cell.selectionStyle = UITableViewCellSelectionStyleNone; + + UISwitch *switchCtl = [[[UISwitch alloc] initWithFrame:CGRectMake(194, 8, 94, 27)] autorelease]; + [switchCtl addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged]; + [cell.contentView addSubview:switchCtl]; + } + + break; + } + } + + return cell; +} + + +- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section != kShowCleartextSection) + { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + id secAttr = [DetailViewController secAttrForSection:indexPath.section]; + [textFieldController.textControl setPlaceholder:[DetailViewController titleForSection:indexPath.section]]; + [textFieldController.textControl setSecureTextEntry:(indexPath.section == kPasswordSection || indexPath.section == kAccountNumberSection)]; + if (indexPath.section == kUsernameSection || indexPath.section == kPasswordSection) + { + textFieldController.keychainItemWrapper = passwordItem; + } + else { + textFieldController.keychainItemWrapper = accountNumberItem; + } + textFieldController.textValue = [textFieldController.keychainItemWrapper objectForKey:secAttr]; + textFieldController.editedFieldKey = secAttr; + textFieldController.title = [DetailViewController titleForSection:indexPath.section]; + + [self.navigationController pushViewController:textFieldController animated:YES]; + } +} + +@end \ No newline at end of file diff --git a/GenericKeychain/Classes/EditorController.h b/GenericKeychain/Classes/EditorController.h new file mode 100644 index 0000000..bba3a24 --- /dev/null +++ b/GenericKeychain/Classes/EditorController.h @@ -0,0 +1,71 @@ +/* + File: EditorController.h + Abstract: + Controller class for the two editing views. Abstracts the interaction with + text field and text view for the main controller. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class KeychainItemWrapper; + +@interface EditorController : UIViewController +{ + NSString *textValue; + NSString *editedFieldKey; + id textControl; + KeychainItemWrapper *keychainItemWrapper; +} + +@property (nonatomic, retain) NSString *textValue; +@property (nonatomic, retain) NSString *editedFieldKey; +@property (nonatomic, retain) IBOutlet id textControl; +@property (nonatomic, retain) KeychainItemWrapper *keychainItemWrapper; + +- (IBAction)cancel:(id)sender; +- (IBAction)save:(id)sender; + +@end diff --git a/GenericKeychain/Classes/EditorController.m b/GenericKeychain/Classes/EditorController.m new file mode 100644 index 0000000..e49c8e5 --- /dev/null +++ b/GenericKeychain/Classes/EditorController.m @@ -0,0 +1,98 @@ +/* + File: EditorController.m + Abstract: + Controller class for the two editing views. Abstracts the interaction with + text field and text view for the main controller. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "EditorController.h" +#import "KeychainItemWrapper.h" + +@implementation EditorController + +@synthesize textValue, editedFieldKey, textControl, keychainItemWrapper; + +- (void)dealloc +{ + [textValue release]; + [editedFieldKey release]; + [textControl release]; + [keychainItemWrapper release]; + [super dealloc]; +} + +- (void)awakeFromNib +{ + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; + [textControl setFont:[UIFont boldSystemFontOfSize:16]]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + +- (IBAction)cancel:(id)sender +{ + // cancel edits + [self.navigationController popViewControllerAnimated:YES]; +} + +- (IBAction)save:(id)sender +{ + // save edits + [keychainItemWrapper setObject:[textControl text] forKey:editedFieldKey]; + [self.navigationController popViewControllerAnimated:YES]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [textControl becomeFirstResponder]; + [textControl setText:textValue]; +} + +@end diff --git a/GenericKeychain/Classes/KeychainItemWrapper.h b/GenericKeychain/Classes/KeychainItemWrapper.h new file mode 100755 index 0000000..2ec18cb --- /dev/null +++ b/GenericKeychain/Classes/KeychainItemWrapper.h @@ -0,0 +1,74 @@ +/* + File: KeychainItemWrapper.h + Abstract: + Objective-C wrapper for accessing a single keychain item. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +/* + The KeychainItemWrapper class is an abstraction layer for the iPhone Keychain communication. It is merely a + simple wrapper to provide a distinct barrier between all the idiosyncracies involved with the Keychain + CF/NS container objects. +*/ +@interface KeychainItemWrapper : NSObject +{ + NSMutableDictionary *keychainItemData; // The actual keychain item data backing store. + NSMutableDictionary *genericPasswordQuery; // A placeholder for the generic keychain item query used to locate the item. +} + +@property (nonatomic, retain) NSMutableDictionary *keychainItemData; +@property (nonatomic, retain) NSMutableDictionary *genericPasswordQuery; + +// Designated initializer. +- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup; +- (void)setObject:(id)inObject forKey:(id)key; +- (id)objectForKey:(id)key; + +// Initializes and resets the default generic keychain item data. +- (void)resetKeychainItem; + +@end \ No newline at end of file diff --git a/GenericKeychain/Classes/KeychainItemWrapper.m b/GenericKeychain/Classes/KeychainItemWrapper.m new file mode 100755 index 0000000..cef5d56 --- /dev/null +++ b/GenericKeychain/Classes/KeychainItemWrapper.m @@ -0,0 +1,313 @@ +/* + File: KeychainItemWrapper.m + Abstract: + Objective-C wrapper for accessing a single keychain item. + + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "KeychainItemWrapper.h" +#import + +/* + +These are the default constants and their respective types, +available for the kSecClassGenericPassword Keychain Item class: + +kSecAttrAccessGroup - CFStringRef +kSecAttrCreationDate - CFDateRef +kSecAttrModificationDate - CFDateRef +kSecAttrDescription - CFStringRef +kSecAttrComment - CFStringRef +kSecAttrCreator - CFNumberRef +kSecAttrType - CFNumberRef +kSecAttrLabel - CFStringRef +kSecAttrIsInvisible - CFBooleanRef +kSecAttrIsNegative - CFBooleanRef +kSecAttrAccount - CFStringRef +kSecAttrService - CFStringRef +kSecAttrGeneric - CFDataRef + +See the header file Security/SecItem.h for more details. + +*/ + +@interface KeychainItemWrapper (PrivateMethods) +/* +The decision behind the following two methods (secItemFormatToDictionary and dictionaryToSecItemFormat) was +to encapsulate the transition between what the detail view controller was expecting (NSString *) and what the +Keychain API expects as a validly constructed container class. +*/ +- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert; +- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert; + +// Updates the item in the keychain, or adds it if it doesn't exist. +- (void)writeToKeychain; + +@end + +@implementation KeychainItemWrapper + +@synthesize keychainItemData, genericPasswordQuery; + +- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup; +{ + if (self = [super init]) + { + // Begin Keychain search setup. The genericPasswordQuery leverages the special user + // defined attribute kSecAttrGeneric to distinguish itself between other generic Keychain + // items which may be included by the same application. + genericPasswordQuery = [[NSMutableDictionary alloc] init]; + + [genericPasswordQuery setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; + [genericPasswordQuery setObject:identifier forKey:(id)kSecAttrGeneric]; + + // The keychain access group attribute determines if this item can be shared + // amongst multiple apps whose code signing entitlements contain the same keychain access group. + if (accessGroup != nil) + { +#if TARGET_IPHONE_SIMULATOR + // Ignore the access group if running on the iPhone simulator. + // + // Apps that are built for the simulator aren't signed, so there's no keychain access group + // for the simulator to check. This means that all apps can see all keychain items when run + // on the simulator. + // + // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the + // simulator will return -25243 (errSecNoAccessForItem). +#else + [genericPasswordQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup]; +#endif + } + + // Use the proper search constants, return only the attributes of the first match. + [genericPasswordQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; + [genericPasswordQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; + + NSDictionary *tempQuery = [NSDictionary dictionaryWithDictionary:genericPasswordQuery]; + + NSMutableDictionary *outDictionary = nil; + + if (! SecItemCopyMatching((CFDictionaryRef)tempQuery, (CFTypeRef *)&outDictionary) == noErr) + { + // Stick these default values into keychain item if nothing found. + [self resetKeychainItem]; + + // Add the generic attribute and the keychain access group. + [keychainItemData setObject:identifier forKey:(id)kSecAttrGeneric]; + if (accessGroup != nil) + { +#if TARGET_IPHONE_SIMULATOR + // Ignore the access group if running on the iPhone simulator. + // + // Apps that are built for the simulator aren't signed, so there's no keychain access group + // for the simulator to check. This means that all apps can see all keychain items when run + // on the simulator. + // + // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the + // simulator will return -25243 (errSecNoAccessForItem). +#else + [keychainItemData setObject:accessGroup forKey:(id)kSecAttrAccessGroup]; +#endif + } + } + else + { + // load the saved data from Keychain. + self.keychainItemData = [self secItemFormatToDictionary:outDictionary]; + } + + [outDictionary release]; + } + + return self; +} + +- (void)dealloc +{ + [keychainItemData release]; + [genericPasswordQuery release]; + + [super dealloc]; +} + +- (void)setObject:(id)inObject forKey:(id)key +{ + if (inObject == nil) return; + id currentObject = [keychainItemData objectForKey:key]; + if (![currentObject isEqual:inObject]) + { + [keychainItemData setObject:inObject forKey:key]; + [self writeToKeychain]; + } +} + +- (id)objectForKey:(id)key +{ + return [keychainItemData objectForKey:key]; +} + +- (void)resetKeychainItem +{ + OSStatus junk = noErr; + if (!keychainItemData) + { + self.keychainItemData = [[NSMutableDictionary alloc] init]; + } + else if (keychainItemData) + { + NSMutableDictionary *tempDictionary = [self dictionaryToSecItemFormat:keychainItemData]; + junk = SecItemDelete((CFDictionaryRef)tempDictionary); + NSAssert( junk == noErr || junk == errSecItemNotFound, @"Problem deleting current dictionary." ); + } + + // Default attributes for keychain item. + [keychainItemData setObject:@"" forKey:(id)kSecAttrAccount]; + [keychainItemData setObject:@"" forKey:(id)kSecAttrLabel]; + [keychainItemData setObject:@"" forKey:(id)kSecAttrDescription]; + + // Default data for keychain item. + [keychainItemData setObject:@"" forKey:(id)kSecValueData]; +} + +- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert +{ + // The assumption is that this method will be called with a properly populated dictionary + // containing all the right key/value pairs for a SecItem. + + // Create a dictionary to return populated with the attributes and data. + NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert]; + + // Add the Generic Password keychain item class attribute. + [returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; + + // Convert the NSString to NSData to meet the requirements for the value type kSecValueData. + // This is where to store sensitive data that should be encrypted. + NSString *passwordString = [dictionaryToConvert objectForKey:(id)kSecValueData]; + [returnDictionary setObject:[passwordString dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData]; + + return returnDictionary; +} + +- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert +{ + // The assumption is that this method will be called with a properly populated dictionary + // containing all the right key/value pairs for the UI element. + + // Create a dictionary to return populated with the attributes and data. + NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert]; + + // Add the proper search key and class attribute. + [returnDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; + [returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; + + // Acquire the password data from the attributes. + NSData *passwordData = NULL; + if (SecItemCopyMatching((CFDictionaryRef)returnDictionary, (CFTypeRef *)&passwordData) == noErr) + { + // Remove the search, class, and identifier key/value, we don't need them anymore. + [returnDictionary removeObjectForKey:(id)kSecReturnData]; + + // Add the password to the dictionary, converting from NSData to NSString. + NSString *password = [[[NSString alloc] initWithBytes:[passwordData bytes] length:[passwordData length] + encoding:NSUTF8StringEncoding] autorelease]; + [returnDictionary setObject:password forKey:(id)kSecValueData]; + } + else + { + // Don't do anything if nothing is found. + NSAssert(NO, @"Serious error, no matching item found in the keychain.\n"); + } + + [passwordData release]; + + return returnDictionary; +} + +- (void)writeToKeychain +{ + NSDictionary *attributes = NULL; + NSMutableDictionary *updateItem = NULL; + OSStatus result; + + if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr) + { + // First we need the attributes from the Keychain. + updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes]; + // Second we need to add the appropriate search key/values. + [updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass]; + + // Lastly, we need to set up the updated attribute list being careful to remove the class. + NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData]; + [tempCheck removeObjectForKey:(id)kSecClass]; + +#if TARGET_IPHONE_SIMULATOR + // Remove the access group if running on the iPhone simulator. + // + // Apps that are built for the simulator aren't signed, so there's no keychain access group + // for the simulator to check. This means that all apps can see all keychain items when run + // on the simulator. + // + // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the + // simulator will return -25243 (errSecNoAccessForItem). + // + // The access group attribute will be included in items returned by SecItemCopyMatching, + // which is why we need to remove it before updating the item. + [tempCheck removeObjectForKey:(id)kSecAttrAccessGroup]; +#endif + + // An implicit assumption is that you can only update a single item at a time. + + result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck); + NSAssert( result == noErr, @"Couldn't update the Keychain Item." ); + } + else + { + // No previous item found; add the new one. + result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL); + NSAssert( result == noErr, @"Couldn't add the Keychain Item." ); + } +} + +@end diff --git a/GenericKeychain/Default.png b/GenericKeychain/Default.png new file mode 100644 index 0000000..00f8000 Binary files /dev/null and b/GenericKeychain/Default.png differ diff --git a/GenericKeychain/Default2.png b/GenericKeychain/Default2.png new file mode 100644 index 0000000..23860fc Binary files /dev/null and b/GenericKeychain/Default2.png differ diff --git a/GenericKeychain/GenericKeychain.xcodeproj/project.pbxproj b/GenericKeychain/GenericKeychain.xcodeproj/project.pbxproj new file mode 100755 index 0000000..c1b8c97 --- /dev/null +++ b/GenericKeychain/GenericKeychain.xcodeproj/project.pbxproj @@ -0,0 +1,501 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 3076250C0DCF9C26000C2DC4 /* EditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3076250B0DCF9C26000C2DC4 /* EditorController.m */; }; + 309905A10DF6082100331083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3099059F0DF6082100331083 /* MainWindow.xib */; }; + 4A33F3AA0DC14C5E00DB5950 /* KeychainItemWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A33F3A90DC14C5E00DB5950 /* KeychainItemWrapper.m */; }; + 4AFC07D30DC14824003666A7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AFC07D20DC14824003666A7 /* Security.framework */; }; + 4AFC08090DC148ED003666A7 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC08010DC148ED003666A7 /* DetailViewController.m */; }; + 4AFC080A0DC148ED003666A7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC08030DC148ED003666A7 /* AppDelegate.m */; }; + BF063AFF11CC031A009EDACA /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = BF063AFE11CC031A009EDACA /* Default.png */; }; + BF063B0911CC0518009EDACA /* Default2.png in Resources */ = {isa = PBXBuildFile; fileRef = BF063B0711CC0518009EDACA /* Default2.png */; }; + BF0CAFA011E66FB300FBB82B /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9911E66FB300FBB82B /* Icon-72.png */; }; + BF0CAFA111E66FB300FBB82B /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9A11E66FB300FBB82B /* Icon-Small-50.png */; }; + BF0CAFA211E66FB300FBB82B /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9B11E66FB300FBB82B /* Icon-Small.png */; }; + BF0CAFA311E66FB300FBB82B /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9C11E66FB300FBB82B /* Icon-Small@2x.png */; }; + BF0CAFA411E66FB300FBB82B /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9D11E66FB300FBB82B /* Icon.png */; }; + BF0CAFA511E66FB300FBB82B /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9E11E66FB300FBB82B /* Icon@2x.png */; }; + BF0CAFA611E66FB300FBB82B /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9F11E66FB300FBB82B /* iTunesArtwork */; }; + BF0CAFA711E66FB300FBB82B /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9911E66FB300FBB82B /* Icon-72.png */; }; + BF0CAFA811E66FB300FBB82B /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9A11E66FB300FBB82B /* Icon-Small-50.png */; }; + BF0CAFA911E66FB300FBB82B /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9B11E66FB300FBB82B /* Icon-Small.png */; }; + BF0CAFAA11E66FB300FBB82B /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9C11E66FB300FBB82B /* Icon-Small@2x.png */; }; + BF0CAFAB11E66FB300FBB82B /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9D11E66FB300FBB82B /* Icon.png */; }; + BF0CAFAC11E66FB300FBB82B /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9E11E66FB300FBB82B /* Icon@2x.png */; }; + BF0CAFAD11E66FB300FBB82B /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = BF0CAF9F11E66FB300FBB82B /* iTunesArtwork */; }; + BF4B93220F8ABE3600E4CD44 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + BF4B93230F8ABE3600E4CD44 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC08010DC148ED003666A7 /* DetailViewController.m */; }; + BF4B93240F8ABE3600E4CD44 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC08030DC148ED003666A7 /* AppDelegate.m */; }; + BF4B93250F8ABE3600E4CD44 /* KeychainItemWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A33F3A90DC14C5E00DB5950 /* KeychainItemWrapper.m */; }; + BF4B93270F8ABE3600E4CD44 /* EditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3076250B0DCF9C26000C2DC4 /* EditorController.m */; }; + BF4B93290F8ABE3600E4CD44 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + BF4B932A0F8ABE3600E4CD44 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + BF4B932B0F8ABE3600E4CD44 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + BF4B932C0F8ABE3600E4CD44 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AFC07D20DC14824003666A7 /* Security.framework */; }; + BF4B933E0F8ABF1B00E4CD44 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = BF4B933B0F8ABF1500E4CD44 /* Localizable.strings */; }; + BF4B933F0F8ABF1B00E4CD44 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = BF4B933B0F8ABF1500E4CD44 /* Localizable.strings */; }; + BF4B93520F8ABFA900E4CD44 /* MainWindow2.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF4B93500F8ABFA900E4CD44 /* MainWindow2.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* GenericKeychain.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GenericKeychain.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 3076250A0DCF9C26000C2DC4 /* EditorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditorController.h; sourceTree = ""; }; + 3076250B0DCF9C26000C2DC4 /* EditorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditorController.m; sourceTree = ""; }; + 307625DF0DCFAEB4000C2DC4 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 309905A00DF6082100331083 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* GenericKeychain_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericKeychain_Prefix.pch; sourceTree = ""; }; + 4A33F3A80DC14C5E00DB5950 /* KeychainItemWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainItemWrapper.h; sourceTree = ""; }; + 4A33F3A90DC14C5E00DB5950 /* KeychainItemWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainItemWrapper.m; sourceTree = ""; }; + 4AFC07D20DC14824003666A7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + 4AFC08010DC148ED003666A7 /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; + 4AFC08020DC148ED003666A7 /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + 4AFC08030DC148ED003666A7 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 4AFC08040DC148ED003666A7 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BF063AFE11CC031A009EDACA /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + BF063B0711CC0518009EDACA /* Default2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default2.png; sourceTree = ""; }; + BF0CAF9911E66FB300FBB82B /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + BF0CAF9A11E66FB300FBB82B /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + BF0CAF9B11E66FB300FBB82B /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + BF0CAF9C11E66FB300FBB82B /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + BF0CAF9D11E66FB300FBB82B /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + BF0CAF9E11E66FB300FBB82B /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + BF0CAF9F11E66FB300FBB82B /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + BF4B93310F8ABE3600E4CD44 /* GenericKeychain2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GenericKeychain2.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BF4B93380F8ABEB300E4CD44 /* KeychainAccessGroups2.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = KeychainAccessGroups2.plist; sourceTree = ""; }; + BF4B934D0F8ABF4A00E4CD44 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + BF4B93510F8ABFA900E4CD44 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow2.xib; sourceTree = ""; }; + BF4B93640F8AC0D900E4CD44 /* Info2.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info2.plist; sourceTree = ""; }; + BFC6BB2F0F8A8D3A00710EDC /* KeychainAccessGroups.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = KeychainAccessGroups.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 4AFC07D30DC14824003666A7 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF4B93280F8ABE3600E4CD44 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BF4B93290F8ABE3600E4CD44 /* Foundation.framework in Frameworks */, + BF4B932A0F8ABE3600E4CD44 /* UIKit.framework in Frameworks */, + BF4B932B0F8ABE3600E4CD44 /* CoreGraphics.framework in Frameworks */, + BF4B932C0F8ABE3600E4CD44 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 4AFC08040DC148ED003666A7 /* AppDelegate.h */, + 4AFC08030DC148ED003666A7 /* AppDelegate.m */, + 4A33F3A80DC14C5E00DB5950 /* KeychainItemWrapper.h */, + 4A33F3A90DC14C5E00DB5950 /* KeychainItemWrapper.m */, + 4AFC08020DC148ED003666A7 /* DetailViewController.h */, + 4AFC08010DC148ED003666A7 /* DetailViewController.m */, + 3076250A0DCF9C26000C2DC4 /* EditorController.h */, + 3076250B0DCF9C26000C2DC4 /* EditorController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GenericKeychain.app */, + BF4B93310F8ABE3600E4CD44 /* GenericKeychain2.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 307625DF0DCFAEB4000C2DC4 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* GenericKeychain_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* Info.plist */, + BF4B93640F8AC0D900E4CD44 /* Info2.plist */, + BFC6BB2F0F8A8D3A00710EDC /* KeychainAccessGroups.plist */, + BF4B93380F8ABEB300E4CD44 /* KeychainAccessGroups2.plist */, + 3099059F0DF6082100331083 /* MainWindow.xib */, + BF4B93500F8ABFA900E4CD44 /* MainWindow2.xib */, + BF4B933B0F8ABF1500E4CD44 /* Localizable.strings */, + BF063AFE11CC031A009EDACA /* Default.png */, + BF063B0711CC0518009EDACA /* Default2.png */, + BF0CAF9811E66FB300FBB82B /* images */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4AFC07D20DC14824003666A7 /* Security.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + BF0CAF9811E66FB300FBB82B /* images */ = { + isa = PBXGroup; + children = ( + BF0CAF9911E66FB300FBB82B /* Icon-72.png */, + BF0CAF9A11E66FB300FBB82B /* Icon-Small-50.png */, + BF0CAF9B11E66FB300FBB82B /* Icon-Small.png */, + BF0CAF9C11E66FB300FBB82B /* Icon-Small@2x.png */, + BF0CAF9D11E66FB300FBB82B /* Icon.png */, + BF0CAF9E11E66FB300FBB82B /* Icon@2x.png */, + BF0CAF9F11E66FB300FBB82B /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GenericKeychain */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GenericKeychain" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + 4AAA61280DC8EAC100820955 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GenericKeychain; + productName = GenericKeychain; + productReference = 1D6058910D05DD3D006BFB54 /* GenericKeychain.app */; + productType = "com.apple.product-type.application"; + }; + BF4B931C0F8ABE3600E4CD44 /* GenericKeychain2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = BF4B932E0F8ABE3600E4CD44 /* Build configuration list for PBXNativeTarget "GenericKeychain2" */; + buildPhases = ( + BF4B931D0F8ABE3600E4CD44 /* Resources */, + BF4B93210F8ABE3600E4CD44 /* Sources */, + BF4B93280F8ABE3600E4CD44 /* Frameworks */, + BF4B932D0F8ABE3600E4CD44 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GenericKeychain2; + productName = GenericKeychain; + productReference = BF4B93310F8ABE3600E4CD44 /* GenericKeychain2.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GenericKeychain" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GenericKeychain */, + BF4B931C0F8ABE3600E4CD44 /* GenericKeychain2 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 309905A10DF6082100331083 /* MainWindow.xib in Resources */, + BF4B933E0F8ABF1B00E4CD44 /* Localizable.strings in Resources */, + BF063AFF11CC031A009EDACA /* Default.png in Resources */, + BF0CAFA011E66FB300FBB82B /* Icon-72.png in Resources */, + BF0CAFA111E66FB300FBB82B /* Icon-Small-50.png in Resources */, + BF0CAFA211E66FB300FBB82B /* Icon-Small.png in Resources */, + BF0CAFA311E66FB300FBB82B /* Icon-Small@2x.png in Resources */, + BF0CAFA411E66FB300FBB82B /* Icon.png in Resources */, + BF0CAFA511E66FB300FBB82B /* Icon@2x.png in Resources */, + BF0CAFA611E66FB300FBB82B /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF4B931D0F8ABE3600E4CD44 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF4B933F0F8ABF1B00E4CD44 /* Localizable.strings in Resources */, + BF4B93520F8ABFA900E4CD44 /* MainWindow2.xib in Resources */, + BF063B0911CC0518009EDACA /* Default2.png in Resources */, + BF0CAFA711E66FB300FBB82B /* Icon-72.png in Resources */, + BF0CAFA811E66FB300FBB82B /* Icon-Small-50.png in Resources */, + BF0CAFA911E66FB300FBB82B /* Icon-Small.png in Resources */, + BF0CAFAA11E66FB300FBB82B /* Icon-Small@2x.png in Resources */, + BF0CAFAB11E66FB300FBB82B /* Icon.png in Resources */, + BF0CAFAC11E66FB300FBB82B /* Icon@2x.png in Resources */, + BF0CAFAD11E66FB300FBB82B /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4AAA61280DC8EAC100820955 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = ""; + }; + BF4B932D0F8ABE3600E4CD44 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = ""; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 4AFC08090DC148ED003666A7 /* DetailViewController.m in Sources */, + 4AFC080A0DC148ED003666A7 /* AppDelegate.m in Sources */, + 4A33F3AA0DC14C5E00DB5950 /* KeychainItemWrapper.m in Sources */, + 3076250C0DCF9C26000C2DC4 /* EditorController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF4B93210F8ABE3600E4CD44 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF4B93220F8ABE3600E4CD44 /* main.m in Sources */, + BF4B93230F8ABE3600E4CD44 /* DetailViewController.m in Sources */, + BF4B93240F8ABE3600E4CD44 /* AppDelegate.m in Sources */, + BF4B93250F8ABE3600E4CD44 /* KeychainItemWrapper.m in Sources */, + BF4B93270F8ABE3600E4CD44 /* EditorController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 3099059F0DF6082100331083 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 309905A00DF6082100331083 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + BF4B933B0F8ABF1500E4CD44 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + BF4B934D0F8ABF4A00E4CD44 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + BF4B93500F8ABFA900E4CD44 /* MainWindow2.xib */ = { + isa = PBXVariantGroup; + children = ( + BF4B93510F8ABFA900E4CD44 /* en */, + ); + name = MainWindow2.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = KeychainAccessGroups.plist; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GenericKeychain_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = GenericKeychain; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = KeychainAccessGroups.plist; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GenericKeychain_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = GenericKeychain; + }; + name = Release; + }; + BF4B932F0F8ABE3600E4CD44 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = KeychainAccessGroups2.plist; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GenericKeychain_Prefix.pch; + INFOPLIST_FILE = Info2.plist; + PRODUCT_NAME = GenericKeychain2; + }; + name = Debug; + }; + BF4B93300F8ABE3600E4CD44 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = KeychainAccessGroups2.plist; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = GenericKeychain_Prefix.pch; + INFOPLIST_FILE = Info2.plist; + PRODUCT_NAME = GenericKeychain2; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GenericKeychain" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BF4B932E0F8ABE3600E4CD44 /* Build configuration list for PBXNativeTarget "GenericKeychain2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BF4B932F0F8ABE3600E4CD44 /* Debug */, + BF4B93300F8ABE3600E4CD44 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GenericKeychain" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/GenericKeychain/GenericKeychain_Prefix.pch b/GenericKeychain/GenericKeychain_Prefix.pch new file mode 100644 index 0000000..a17c026 --- /dev/null +++ b/GenericKeychain/GenericKeychain_Prefix.pch @@ -0,0 +1,51 @@ +/* + File: GenericKeychain_Prefix.pch + Abstract: Prefix header for all source files of the 'GenericKeychain' target in the 'GenericKeychain' project + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/GenericKeychain/Info.plist b/GenericKeychain/Info.plist new file mode 100644 index 0000000..d565e80 --- /dev/null +++ b/GenericKeychain/Info.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + NSMainNibFile + MainWindow + + diff --git a/GenericKeychain/Info2.plist b/GenericKeychain/Info2.plist new file mode 100755 index 0000000..ebc14c3 --- /dev/null +++ b/GenericKeychain/Info2.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + NSMainNibFile + MainWindow2 + UILaunchImageFile + Default2.png + + diff --git a/GenericKeychain/KeychainAccessGroups.plist b/GenericKeychain/KeychainAccessGroups.plist new file mode 100644 index 0000000..01359f2 --- /dev/null +++ b/GenericKeychain/KeychainAccessGroups.plist @@ -0,0 +1,11 @@ + + + + + keychain-access-groups + + YOUR_APP_ID_HERE.com.yourcompany.GenericKeychain + YOUR_APP_ID_HERE.com.yourcompany.GenericKeychainSuite + + + diff --git a/GenericKeychain/KeychainAccessGroups2.plist b/GenericKeychain/KeychainAccessGroups2.plist new file mode 100644 index 0000000..2b75489 --- /dev/null +++ b/GenericKeychain/KeychainAccessGroups2.plist @@ -0,0 +1,11 @@ + + + + + keychain-access-groups + + YOUR_APP_ID_HERE.com.yourcompany.GenericKeychain2 + YOUR_APP_ID_HERE.com.yourcompany.GenericKeychainSuite + + + diff --git a/GenericKeychain/ReadMe.txt b/GenericKeychain/ReadMe.txt new file mode 100644 index 0000000..1818bd9 --- /dev/null +++ b/GenericKeychain/ReadMe.txt @@ -0,0 +1,87 @@ +### GenericKeychain ### + +================================================================================ +DESCRIPTION: + +This sample shows how to navigate through the Keychain Services API +provided by iOS. Its demonstration leverages the Generic +Keychain Item class and provides a template on how to successfully set up calls +to: SecItemAdd, SecItemCopyMatching, SecItemDelete, and SecItemUpdate. + +The user interface is a master-detail designed in Interface Builder, archived in the MainWindow nib. +The user interface is modeled on a typical iOS app preferences screen. + +The sample builds two separate applications from the same code base. Both applications +have their own keychain item that stores a username and password. Both apps also share +a second keychain item that stores an account number. This takes advantage +of the shared keychain item capability added in iOS 3.0. + +Testing: + +The ability to share keychain items between apps is based on code signing entitlements. These +in turn are based on the app ID prefix that is contained in your provisioning profile. All +apps that share a keychain item must be built using the same app ID prefix. + +The sample must be edited to include your app ID prefix in five places where the text "YOUR_APP_ID_HERE" +appears before building and running the sample apps. The easiest way to do that is to use Xcode's Find in Project +command to locate the places that must be edited first. Just change the app ID prefix; leave the rest unchanged. + +Next, make GenericKeychain the active target and select Build and Go to run the first app GenericKeychain. + +Finally, make GenericKeychain2 the active target and select Build and Go to run the second app GenericKeychain2. + +NOTE: + +Apps that are built for the simulator aren't signed, so there's no keychain access group +for the simulator to check. This means that all keychain items are in the same default access group +and all apps can see all keychain items when run on the simulator. + +If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the +simulator will return -25243 (errSecNoAccessForItem). + +The sample is written to ignore the access group if built for the simulator. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +AppDelegate +Adds the root navigation controller's view to the main window and displays the window when the +application launches. + +KeychainItemWrapper +Abstract interface to Keychain Services that wraps a single keychain item. + +DetailViewController +Custom detail view controller. + +EditorController +View controller subclass for abstracting an interface to either a text field or a text view. + +MainWindow.xib +The nib file containing the main window and the view controllers used in the application. + + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.2 + Fixed minor memory leak and upgraded project to build with the iOS 4 SDK. + +Version 1.1 + Adopted UITableView and UITableViewCell API for iPhone OS 3.0. Added support for + shared keychain items. + +Version 1.0 + N/A + +Copyright (c) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/GenericKeychain/en.lproj/Localizable.strings b/GenericKeychain/en.lproj/Localizable.strings new file mode 100644 index 0000000..9f415cc Binary files /dev/null and b/GenericKeychain/en.lproj/Localizable.strings differ diff --git a/GenericKeychain/en.lproj/MainWindow.xib b/GenericKeychain/en.lproj/MainWindow.xib new file mode 100644 index 0000000..a9b0c51 --- /dev/null +++ b/GenericKeychain/en.lproj/MainWindow.xib @@ -0,0 +1,661 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 416} + + NO + YES + NO + 1 + 0 + YES + 4.400000e+01 + 1.800000e+01 + 1.000000e+01 + + + + App 1 Settings + + Reset + 1 + + + + + + + + + + 274 + + YES + + + 268 + {{20, 82}, {280, 31}} + + NO + NO + 0 + + 3 + + 3 + MAA + + 2 + + + YES + YES + 1.700000e+01 + + + + {{0, 22}, {320, 416}} + + + 3 + MQA + + + NO + + + + + + 1 + 1 + + + 1 + 3 + + + + + + + + 274 + + YES + + + 268 + {{20, 20}, {280, 151}} + + + NO + + + {{0, 22}, {320, 416}} + + + 3 + MQA + + + NO + + + + + + 1 + 1 + + + 1 + 3 + + + + + + + + YES + + + delegate + + + + 5 + + + + window + + + + 6 + + + + textFieldController + + + + 27 + + + + navigationController + + + + 29 + + + + detailViewController + + + + 30 + + + + dataSource + + + + 31 + + + + delegate + + + + 32 + + + + resetKeychain: + + + + 33 + + + + cancel: + + + + 37 + + + + textControl + + + + 41 + + + + save: + + + + 45 + + + + textControl + + + + 48 + + + + save: + + + + 52 + + + + cancel: + + + + 53 + + + + tableView + + + + 54 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 4 + + + App Delegate + + + -2 + + + + + 7 + + + YES + + + + + + + 8 + + + YES + + + + + + + 9 + + + + + 10 + + + YES + + + + + + 12 + + + YES + + + + + + + 14 + + + YES + + + + + + 15 + + + + + 18 + + + + + 20 + + + YES + + + + + + + 21 + + + YES + + + + + + 22 + + + YES + + + + + + + 23 + + + + + 44 + + + + + 47 + + + + + 49 + + + YES + + + + + + + 50 + + + + + 51 + + + + + 11 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 12.CustomClassName + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 18.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 20.CustomClassName + 20.IBEditorWindowLastContentRect + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 23.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + 44.IBPluginDependency + 47.CustomClassName + 47.IBPluginDependency + 49.IBPluginDependency + 50.IBPluginDependency + 51.IBPluginDependency + 7.IBEditorWindowLastContentRect + 7.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EditorController + {{602, 52}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{593, 416}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + EditorController + {{602, 279}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UITextView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{86, 481}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DetailViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 55 + + + + YES + + AppDelegate + NSObject + + YES + + YES + detailViewController + navigationController + window + + + YES + DetailViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + DetailViewController + UIViewController + + resetKeychain: + id + + + YES + + YES + tableView + textFieldController + + + YES + UITableView + EditorController + + + + IBProjectSource + Classes/DetailViewController.h + + + + EditorController + UIViewController + + YES + + YES + cancel: + save: + + + YES + id + id + + + + textControl + id + + + IBProjectSource + Classes/EditorController.h + + + + + 0 + ../GenericKeychain.xcodeproj + 3 + 3.0 + + diff --git a/GenericKeychain/en.lproj/MainWindow2.xib b/GenericKeychain/en.lproj/MainWindow2.xib new file mode 100755 index 0000000..ea8fcee --- /dev/null +++ b/GenericKeychain/en.lproj/MainWindow2.xib @@ -0,0 +1,658 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 416} + + NO + YES + NO + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 6.000000e+00 + + + + App 2 Settings + + Reset + 1 + + + + + + + + + + 274 + + YES + + + 268 + {{20, 82}, {280, 31}} + + NO + NO + 0 + + 3 + + 3 + MAA + + 2 + + + YES + YES + 1.700000e+01 + + + + {{0, 22}, {320, 416}} + + 3 + MQA + + + NO + + + + + 1 + 1 + + + 1 + 3 + + + + + + + + 274 + + YES + + + 268 + {{20, 20}, {280, 151}} + + + + NO + + + {{0, 22}, {320, 416}} + + + + 3 + MQA + + + NO + + + + + 1 + 1 + + + 1 + 3 + + + + + + + + YES + + + delegate + + + + 5 + + + + window + + + + 6 + + + + textFieldController + + + + 27 + + + + navigationController + + + + 29 + + + + detailViewController + + + + 30 + + + + dataSource + + + + 31 + + + + delegate + + + + 32 + + + + resetKeychain: + + + + 33 + + + + cancel: + + + + 37 + + + + textControl + + + + 41 + + + + save: + + + + 45 + + + + textControl + + + + 48 + + + + save: + + + + 52 + + + + cancel: + + + + 53 + + + + tableView + + + + 54 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 4 + + + App Delegate + + + -2 + + + + + 7 + + + YES + + + + + + + 8 + + + YES + + + + + + + 9 + + + + + 10 + + + YES + + + + + + 12 + + + YES + + + + + + + 14 + + + YES + + + + + + 15 + + + + + 18 + + + + + 20 + + + YES + + + + + + + 21 + + + YES + + + + + + 22 + + + YES + + + + + + + 23 + + + + + 44 + + + + + 47 + + + + + 49 + + + YES + + + + + + + 50 + + + + + 51 + + + + + 11 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 12.CustomClassName + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 18.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 20.CustomClassName + 20.IBEditorWindowLastContentRect + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 23.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + 44.IBPluginDependency + 47.CustomClassName + 47.IBPluginDependency + 49.IBPluginDependency + 50.IBPluginDependency + 51.IBPluginDependency + 7.IBEditorWindowLastContentRect + 7.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EditorController + {{602, 52}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{593, 416}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + EditorController + {{602, 279}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UITextView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{86, 481}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DetailViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 55 + + + + YES + + AppDelegate + NSObject + + YES + + YES + detailViewController + navigationController + window + + + YES + DetailViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + DetailViewController + UIViewController + + resetKeychain: + id + + + YES + + YES + tableView + textFieldController + + + YES + UITableView + EditorController + + + + IBProjectSource + Classes/DetailViewController.h + + + + EditorController + UIViewController + + YES + + YES + cancel: + save: + + + YES + id + id + + + + textControl + id + + + IBProjectSource + Classes/EditorController.h + + + + + 0 + ../GenericKeychain.xcodeproj + 3 + 3.0 + + diff --git a/GenericKeychain/images/Icon-72.png b/GenericKeychain/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/GenericKeychain/images/Icon-72.png differ diff --git a/GenericKeychain/images/Icon-Small-50.png b/GenericKeychain/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/GenericKeychain/images/Icon-Small-50.png differ diff --git a/GenericKeychain/images/Icon-Small.png b/GenericKeychain/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/GenericKeychain/images/Icon-Small.png differ diff --git a/GenericKeychain/images/Icon-Small@2x.png b/GenericKeychain/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/GenericKeychain/images/Icon-Small@2x.png differ diff --git a/GenericKeychain/images/Icon.png b/GenericKeychain/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/GenericKeychain/images/Icon.png differ diff --git a/GenericKeychain/images/Icon@2x.png b/GenericKeychain/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/GenericKeychain/images/Icon@2x.png differ diff --git a/GenericKeychain/images/iTunesArtwork b/GenericKeychain/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/GenericKeychain/images/iTunesArtwork differ diff --git a/GenericKeychain/main.m b/GenericKeychain/main.m new file mode 100644 index 0000000..ef3fce4 --- /dev/null +++ b/GenericKeychain/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Application main entry point, starts the run loop and loads resources. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/HazardMap.zip b/HazardMap.zip new file mode 100644 index 0000000..e895e7b Binary files /dev/null and b/HazardMap.zip differ diff --git a/HazardMap/Classes/HazardMap.h b/HazardMap/Classes/HazardMap.h new file mode 100644 index 0000000..133a74d --- /dev/null +++ b/HazardMap/Classes/HazardMap.h @@ -0,0 +1,80 @@ +/* + File: HazardMap.h + Abstract: MKOverlay model object representing a USGS earthquake hazard map. + See http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/. + This class demonstrates how to project latitude and longitude coordinates representing the corners + of a square into an MKMapRect. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface HazardMap : NSObject { + CLLocationCoordinate2D origin; // position of upper left hazard + CLLocationDegrees gridSize; // delta degrees for each square in the grid + + int gridWidth; // number of squares in the grid in the x direction + int gridHeight; // "" y direction + + float *grid; // actual hazard values in row-major order +} + +// path points to a USGS earthquake hazard map grid file converted to binary +// format by the compactgrid utility. +- (id)initWithHazardMapFile:(NSString *)path; + +- (MKMapRect)boundingMapRect; + +@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; + +// Sample the hazard values within rect into values. Boundaries will contain +// the bounding map rects for each respective value in values. Caller is +// responsible for freeing both values and boundaries. +- (void)hazardsInMapRect:(MKMapRect)rect + atScale:(MKZoomScale)scale + values:(float **)values + boundaries:(MKMapRect **)boundaries + count:(int *)count; + +@end diff --git a/HazardMap/Classes/HazardMap.m b/HazardMap/Classes/HazardMap.m new file mode 100644 index 0000000..4af6018 --- /dev/null +++ b/HazardMap/Classes/HazardMap.m @@ -0,0 +1,225 @@ +/* + File: HazardMap.m + Abstract: MKOverlay model object representing a USGS earthquake hazard map. + See http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/. + This class demonstrates how to project latitude and longitude coordinates representing the corners + of a square into an MKMapRect. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "HazardMap.h" + + +@implementation HazardMap + +- (BOOL)parseGridFile:(NSString *)path +{ + free(grid); + grid = NULL; + + FILE *f = fopen([path UTF8String], "r"); + if (!f) { + perror("Couldn't open grid file"); + return NO; + } + + // [4 bytes] - int32 little endian - grid origin latitudeE6 + // [4 bytes] - int32 little endian - grid origin longitudeE6 + // [4 bytes] - int32 little endian - grid step sizeE6 + // [4 bytes] - int32 little endian - grid width + // [4 bytes] - int32 little endian - grid height + // [N bytes] - list of width*height int16 little endian grid data as E4 fixed point + +#define E6 (1000000.0) +#define E4 (10000.0) + + int32_t latE6, lonE6, gridSizeE6, widthSwapped, heightSwapped; + + fread(&latE6, sizeof(int32_t), 1, f); + fread(&lonE6, sizeof(int32_t), 1, f); + fread(&gridSizeE6, sizeof(int32_t), 1, f); + fread(&widthSwapped, sizeof(int32_t), 1, f); + fread(&heightSwapped, sizeof(int32_t), 1, f); + + origin.latitude = (CLLocationDegrees)((int32_t)OSSwapLittleToHostInt32(latE6)) / E6; + origin.longitude = (CLLocationDegrees)((int32_t)OSSwapLittleToHostInt32(lonE6)) / E6; + gridSize = (CLLocationDegrees)(OSSwapLittleToHostInt32(gridSizeE6)) / E6; + gridWidth = OSSwapLittleToHostInt32(widthSwapped); + gridHeight = OSSwapLittleToHostInt32(heightSwapped); + + size_t toRead = gridWidth * gridHeight; + grid = malloc(sizeof(float) * toRead); + + int i; + for (i = 0; i < toRead; i++) { + int16_t valueE4; + fread(&valueE4, sizeof(int16_t), 1, f); + float value = (float)((int16_t)OSSwapLittleToHostInt16(valueE4)) / E4; + grid[i] = value; + } + +#undef E6 +#undef E4 + + fclose(f); + + NSLog(@"Read %d records from %@", toRead, path); + + return YES; +} + +- (id)initWithHazardMapFile:(NSString *)path +{ + if (self = [super init]) { + if (![self parseGridFile:path]) { + NSLog(@"Couldn't parse file at path: %@", path); + [self release]; + return nil; + } + } + return self; +} + +- (void)dealloc +{ + free(grid); + [super dealloc]; +} + +- (CLLocationCoordinate2D)coordinate +{ + return CLLocationCoordinate2DMake(origin.latitude - (gridHeight * gridSize / 2.0), + origin.longitude - (gridWidth * gridSize / 2.0)); +} + +- (MKMapRect)boundingMapRect +{ + // Compute the boundingMapRect given the origin, the gridSize and the grid width and height + + MKMapPoint upperLeft = MKMapPointForCoordinate(origin); + + CLLocationCoordinate2D lowerRightCoord = + CLLocationCoordinate2DMake(origin.latitude - (gridSize * gridHeight), + origin.longitude + (gridSize * gridWidth)); + + MKMapPoint lowerRight = MKMapPointForCoordinate(lowerRightCoord); + + double width = lowerRight.x - upperLeft.x; + double height = lowerRight.y - upperLeft.y; + + MKMapRect bounds = MKMapRectMake(upperLeft.x, upperLeft.y, width, height); + return bounds; +} + +- (void)hazardsInMapRect:(MKMapRect)rect + atScale:(MKZoomScale)scale + values:(float **)valuesOut + boundaries:(MKMapRect **)boundariesOut + count:(int *)count +{ + CLLocationCoordinate2D rectOrigin = MKCoordinateForMapPoint(rect.origin); + CLLocationCoordinate2D rectMax = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(rect), MKMapRectGetMaxY(rect))); + + // Don't want any returned grid square to be drawn smaller than 2pt. + // When the map is zoomed way out at world level, apply a reduction to + // the grid and just do nearest neighbor sampling to find the a value + double approximatePtsPerSquare = scale * (MKMapSizeWorld.width / (180.0 / gridSize)); + int gridReduction = MAX(1, (int)(4.0 / approximatePtsPerSquare)); + + // Find the bounding indices (left, right, top, bottom) into the grid array + int left = (rectOrigin.longitude - origin.longitude) / gridSize; + left = MAX(left, 0); + left = MIN(left, gridWidth - 1); + + int right = (rectMax.longitude - origin.longitude) / gridSize; + right = MAX(right, 0); + right = MIN(right, gridWidth - 1); + + int top = (origin.latitude - rectOrigin.latitude) / gridSize; + top = MAX(top, 0); + top = MIN(top, gridHeight - 1); + + int bottom = (origin.latitude - rectMax.latitude) / gridSize; + bottom = MAX(bottom, 0); + bottom = MIN(bottom, gridHeight - 1); + + int width = 1 + ((right - left) / gridReduction); + int height = 1 + ((bottom - top) / gridReduction); + + *count = (width) * (height); + MKMapRect *boundaries = malloc(sizeof(MKMapRect) * *count); + float *values = malloc(sizeof(float) * *count); + + // Loop through the grid by the gridReduction factor, sampling values along the way + int x, y, read = 0; + for (y = top; y <= bottom; y += gridReduction) { + for (x = left; x <= right; x += gridReduction) { + // Convert an upper-left, lower-right latitude and longitude to an MKMapRect + CLLocationCoordinate2D valueOrigin = + CLLocationCoordinate2DMake(origin.latitude - (y * gridSize), + origin.longitude + (x * gridSize)); + CLLocationCoordinate2D valueLowerRight = + CLLocationCoordinate2DMake(valueOrigin.latitude - (gridSize * gridReduction), + valueOrigin.longitude + (gridSize * gridReduction)); + + MKMapPoint upperLeft = MKMapPointForCoordinate(valueOrigin); + MKMapPoint lowerRight = MKMapPointForCoordinate(valueLowerRight); + + boundaries[read] = MKMapRectMake(upperLeft.x, + upperLeft.y, + lowerRight.x - upperLeft.x, + lowerRight.y - upperLeft.y); + + // Read the grid value into the values array + values[read] = *(grid + (gridWidth * y) + x); + + read++; + } + } + + *boundariesOut = boundaries; + *valuesOut = values; +} + +@end diff --git a/HazardMap/Classes/HazardMapAppDelegate.h b/HazardMap/Classes/HazardMapAppDelegate.h new file mode 100644 index 0000000..48dd95b --- /dev/null +++ b/HazardMap/Classes/HazardMapAppDelegate.h @@ -0,0 +1,61 @@ +/* + File: HazardMapAppDelegate.h + Abstract: UIApplication delegate for the application. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class HazardMapViewController; + +@interface HazardMapAppDelegate : NSObject { + UIWindow *window; + HazardMapViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet HazardMapViewController *viewController; + +@end + diff --git a/HazardMap/Classes/HazardMapAppDelegate.m b/HazardMap/Classes/HazardMapAppDelegate.m new file mode 100644 index 0000000..86dd7f3 --- /dev/null +++ b/HazardMap/Classes/HazardMapAppDelegate.m @@ -0,0 +1,127 @@ +/* + File: HazardMapAppDelegate.m + Abstract: UIApplication delegate for the application. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "HazardMapAppDelegate.h" +#import "HazardMapViewController.h" + +@implementation HazardMapAppDelegate + +@synthesize window; +@synthesize viewController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + // Override point for customization after application launch. + + // Add the view controller's view to the window and display. + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; + + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + /* + Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + */ +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + /* + Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + If your application supports background execution, called instead of applicationWillTerminate: when the user quits. + */ +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + /* + Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. + */ +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + /* + Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + */ +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + /* + Called when the application is about to terminate. + See also applicationDidEnterBackground:. + */ +} + + +#pragma mark - +#pragma mark Memory management + +- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { + /* + Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. + */ +} + + +- (void)dealloc { + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/HazardMap/Classes/HazardMapView.h b/HazardMap/Classes/HazardMapView.h new file mode 100644 index 0000000..b1eb650 --- /dev/null +++ b/HazardMap/Classes/HazardMapView.h @@ -0,0 +1,57 @@ +/* + File: HazardMapView.h + Abstract: MKOverlayView subclass that renders a USGS earthquake hazard map represented by the + HazardMap class. This class demonstrates how to convert points represented as MKMapRects into + the local coordinate system and then fill those rectangles to visualize earthquake hazards across + the continental United States. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface HazardMapView : MKOverlayView { + CGColorRef *colors; +} + +@end diff --git a/HazardMap/Classes/HazardMapView.m b/HazardMap/Classes/HazardMapView.m new file mode 100644 index 0000000..600c02b --- /dev/null +++ b/HazardMap/Classes/HazardMapView.m @@ -0,0 +1,163 @@ +/* + File: HazardMapView.m + Abstract: MKOverlayView subclass that renders a USGS earthquake hazard map represented by the + HazardMap class. This class demonstrates how to convert points represented as MKMapRects into + the local coordinate system and then fill those rectangles to visualize earthquake hazards across + the continental United States. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "HazardMapView.h" +#import "HazardMap.h" + +#import + +#define NUM_COLORS 14 + +@implementation HazardMapView + +// Create a table of possible colors to draw a grid cell with +- (void)initColors +{ + CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); + colors = malloc(sizeof(CGColorRef) * NUM_COLORS); + int i = 0; + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .588, .294, .78, 1 }); // 1.00 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .784, .471, .82, 1 }); // 0.77 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, 0, 0, 1 }); // 0.59 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, .392, 0, 1 }); // 0.46 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, .392, 0, 1 }); // 0.35 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, .784, 0, 1 }); // 0.27 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ 1, 1, .5, 1 }); // 0.21 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .745, .941, .467, 1 }); // 0.16 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .122, 1, .31, 1 }); // 0.12 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .588, 1, .941, 1 }); // 0.10 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .784, 1, 1, 1 }); // 0.08 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .843, 1, 1, 1 }); // 0.06 + colors[i++] = CGColorCreate(rgb, (CGFloat[]){ .902, 1, 1, 1 }); // 0.04 + colors[i] = CGColorCreate(rgb, (CGFloat[]){ .784, .784, .784, 1 }); // 0.03 + CGColorSpaceRelease(rgb); +} + +// Look up a color in the table of colors for a peak ground acceleration +- (CGColorRef)colorForAcceleration:(CGFloat)value +{ + if (value > 0.77) return colors[0]; + if (value > 0.59) return colors[1]; + if (value > 0.46) return colors[2]; + if (value > 0.35) return colors[3]; + if (value > 0.27) return colors[4]; + if (value > 0.21) return colors[5]; + if (value > 0.16) return colors[6]; + if (value > 0.12) return colors[7]; + if (value > 0.10) return colors[8]; + if (value > 0.08) return colors[9]; + if (value > 0.06) return colors[10]; + if (value > 0.04) return colors[11]; + if (value > 0.03) return colors[12]; + if (value > 0.02) return colors[13]; + return NULL; +} + +- (id)initWithOverlay:(id )overlay +{ + if (self = [super initWithOverlay:overlay]) { + [self initColors]; + } + return self; +} + +- (void)dealloc +{ + int i; + for (i = 0; i < NUM_COLORS; i++) { + CGColorRelease(colors[i]); + } + free(colors); + [super dealloc]; +} + +- (void)drawMapRect:(MKMapRect)mapRect + zoomScale:(MKZoomScale)zoomScale + inContext:(CGContextRef)ctx +{ + HazardMap *hazards = (HazardMap *)self.overlay; + + float *values = NULL; + MKMapRect *boundaries = NULL; + int count = 0; + + // Fetch the grid values out of the model for this mapRect and zoomScale. + [hazards hazardsInMapRect:mapRect + atScale:zoomScale + values:&values + boundaries:&boundaries + count:&count]; + + CGContextSetAlpha(ctx, 0.5); + + // For each grid value that is colorable, color in its corresponding + // boundary MKMapRect with the appropriate color. + int i; + for (i = 0; i < count; i++) { + float value = values[i]; + MKMapRect boundary = boundaries[i]; + + CGColorRef color = [self colorForAcceleration:value]; + if (color) { + CGContextSetFillColorWithColor(ctx, color); + + // Convert the MKMapRect (absolute points on the map proportional to screen points) to + // a CGRect (points relative to the origin of this view) that can be drawn. + CGRect boundaryCGRect = [self rectForMapRect:boundary]; + + CGContextFillRect(ctx, boundaryCGRect); + } + } + + free(values); + free(boundaries); +} + +@end diff --git a/HazardMap/Classes/HazardMapViewController.h b/HazardMap/Classes/HazardMapViewController.h new file mode 100644 index 0000000..133ccd0 --- /dev/null +++ b/HazardMap/Classes/HazardMapViewController.h @@ -0,0 +1,57 @@ +/* + File: HazardMapViewController.h + Abstract: Main view controller for the application. Implements MKMapViewDelegate to manage adding + a HazardMap overlay to a MKMapView and to manage display of a HazardMapView on the MKMapView. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@interface HazardMapViewController : UIViewController { + IBOutlet MKMapView *map; +} + +@end + diff --git a/HazardMap/Classes/HazardMapViewController.m b/HazardMap/Classes/HazardMapViewController.m new file mode 100644 index 0000000..34f1c64 --- /dev/null +++ b/HazardMap/Classes/HazardMapViewController.m @@ -0,0 +1,86 @@ +/* + File: HazardMapViewController.m + Abstract: Main view controller for the application. Implements MKMapViewDelegate to manage adding + a HazardMap overlay to a MKMapView and to manage display of a HazardMapView on the MKMapView. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "HazardMapViewController.h" + +#import "HazardMap.h" +#import "HazardMapView.h" + +@implementation HazardMapViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Find and load the earthquake hazard grid from the application's bundle + NSString *hazardPath = [[NSBundle mainBundle] pathForResource:@"UShazard.20081229.pga.5pc50" + ofType:@"bin"]; + HazardMap *hazards = [[HazardMap alloc] initWithHazardMapFile:hazardPath]; + + // Position and zoom the map to just fit the grid loaded on screen + [map setVisibleMapRect:[hazards boundingMapRect]]; + + // Add the earthquake hazard map to the map view + [map addOverlay:hazards]; + + // Let the map view own the hazards model object now + [hazards release]; +} + +- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay +{ + HazardMapView *view = [[HazardMapView alloc] initWithOverlay:overlay]; + return [view autorelease]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation +{ + return YES; +} + +@end diff --git a/HazardMap/HazardMap-Info.plist b/HazardMap/HazardMap-Info.plist new file mode 100644 index 0000000..9dafb2b --- /dev/null +++ b/HazardMap/HazardMap-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/HazardMap/HazardMap.xcodeproj/project.pbxproj b/HazardMap/HazardMap.xcodeproj/project.pbxproj new file mode 100755 index 0000000..0faf1b9 --- /dev/null +++ b/HazardMap/HazardMap.xcodeproj/project.pbxproj @@ -0,0 +1,427 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1A2D2271118E4AA800142450 /* compactgrid.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D2265118E450500142450 /* compactgrid.c */; }; + 1A2D22A4118E4E7300142450 /* UShazard.20081229.pga.5pc50.bin in Resources */ = {isa = PBXBuildFile; fileRef = 1A2D22A3118E4E7300142450 /* UShazard.20081229.pga.5pc50.bin */; }; + 1A316F2C118B8DD00091CC7B /* HazardMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A316F2B118B8DD00091CC7B /* HazardMap.m */; }; + 1A316F64118BB0390091CC7B /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A316F63118BB0390091CC7B /* MapKit.framework */; }; + 1A316F81118BB04C0091CC7B /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A316F80118BB04C0091CC7B /* CoreLocation.framework */; }; + 1A316F9E118BB1AF0091CC7B /* HazardMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A316F9D118BB1AF0091CC7B /* HazardMapView.m */; }; + 1D3623260D0F684500981E51 /* HazardMapAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* HazardMapAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 28D7ACF80DDB3853001CB0EB /* HazardMapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* HazardMapViewController.m */; }; + 53ACD36911F6408700EA03E3 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36211F6408700EA03E3 /* Icon-72.png */; }; + 53ACD36A11F6408700EA03E3 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36311F6408700EA03E3 /* Icon-Small-50.png */; }; + 53ACD36B11F6408700EA03E3 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36411F6408700EA03E3 /* Icon-Small.png */; }; + 53ACD36C11F6408700EA03E3 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36511F6408700EA03E3 /* Icon-Small@2x.png */; }; + 53ACD36D11F6408700EA03E3 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36611F6408700EA03E3 /* Icon.png */; }; + 53ACD36E11F6408700EA03E3 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36711F6408700EA03E3 /* Icon@2x.png */; }; + 53ACD36F11F6408700EA03E3 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 53ACD36811F6408700EA03E3 /* iTunesArtwork */; }; + 53F418A311F6088C00740D86 /* HazardMapViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53F4189F11F6088C00740D86 /* HazardMapViewController.xib */; }; + 53F418A411F6088C00740D86 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53F418A111F6088C00740D86 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1A2D2265118E450500142450 /* compactgrid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compactgrid.c; sourceTree = ""; }; + 1A2D226D118E4A7600142450 /* compactgrid */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = compactgrid; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A2D22A3118E4E7300142450 /* UShazard.20081229.pga.5pc50.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = UShazard.20081229.pga.5pc50.bin; sourceTree = ""; }; + 1A316F2A118B8DD00091CC7B /* HazardMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HazardMap.h; sourceTree = ""; }; + 1A316F2B118B8DD00091CC7B /* HazardMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HazardMap.m; sourceTree = ""; }; + 1A316F63118BB0390091CC7B /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 1A316F80118BB04C0091CC7B /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 1A316F9C118BB1AF0091CC7B /* HazardMapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HazardMapView.h; sourceTree = ""; }; + 1A316F9D118BB1AF0091CC7B /* HazardMapView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HazardMapView.m; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* HazardMapAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HazardMapAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* HazardMapAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HazardMapAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* HazardMap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HazardMap.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28D7ACF60DDB3853001CB0EB /* HazardMapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HazardMapViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* HazardMapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HazardMapViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* HazardMap_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HazardMap_Prefix.pch; sourceTree = ""; }; + 53ACD36211F6408700EA03E3 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 53ACD36311F6408700EA03E3 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 53ACD36411F6408700EA03E3 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 53ACD36511F6408700EA03E3 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 53ACD36611F6408700EA03E3 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 53ACD36711F6408700EA03E3 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 53ACD36811F6408700EA03E3 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 53F418A011F6088C00740D86 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/HazardMapViewController.xib; sourceTree = ""; }; + 53F418A211F6088C00740D86 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 53FD493C11F61F2A00222043 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* HazardMap-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "HazardMap-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A2D226B118E4A7600142450 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 1A316F64118BB0390091CC7B /* MapKit.framework in Frameworks */, + 1A316F81118BB04C0091CC7B /* CoreLocation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1A316F29118B8DC30091CC7B /* Overlay */, + 1D3623240D0F684500981E51 /* HazardMapAppDelegate.h */, + 1D3623250D0F684500981E51 /* HazardMapAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* HazardMapViewController.h */, + 28D7ACF70DDB3853001CB0EB /* HazardMapViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* HazardMap.app */, + 1A2D226D118E4A7600142450 /* compactgrid */, + ); + name = Products; + sourceTree = ""; + }; + 1A316F29118B8DC30091CC7B /* Overlay */ = { + isa = PBXGroup; + children = ( + 1A316F2A118B8DD00091CC7B /* HazardMap.h */, + 1A316F2B118B8DD00091CC7B /* HazardMap.m */, + 1A316F9C118BB1AF0091CC7B /* HazardMapView.h */, + 1A316F9D118BB1AF0091CC7B /* HazardMapView.m */, + ); + name = Overlay; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53FD493C11F61F2A00222043 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* HazardMap_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 1A2D2265118E450500142450 /* compactgrid.c */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 53ACD36111F6408700EA03E3 /* images */, + 53F4189F11F6088C00740D86 /* HazardMapViewController.xib */, + 53F418A111F6088C00740D86 /* MainWindow.xib */, + 1A2D22A3118E4E7300142450 /* UShazard.20081229.pga.5pc50.bin */, + 8D1107310486CEB800E47090 /* HazardMap-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1A316F80118BB04C0091CC7B /* CoreLocation.framework */, + 1A316F63118BB0390091CC7B /* MapKit.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53ACD36111F6408700EA03E3 /* images */ = { + isa = PBXGroup; + children = ( + 53ACD36211F6408700EA03E3 /* Icon-72.png */, + 53ACD36311F6408700EA03E3 /* Icon-Small-50.png */, + 53ACD36411F6408700EA03E3 /* Icon-Small.png */, + 53ACD36511F6408700EA03E3 /* Icon-Small@2x.png */, + 53ACD36611F6408700EA03E3 /* Icon.png */, + 53ACD36711F6408700EA03E3 /* Icon@2x.png */, + 53ACD36811F6408700EA03E3 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A2D226C118E4A7600142450 /* compactgrid */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A2D2287118E4B3700142450 /* Build configuration list for PBXNativeTarget "compactgrid" */; + buildPhases = ( + 1A2D226A118E4A7600142450 /* Sources */, + 1A2D226B118E4A7600142450 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = compactgrid; + productName = compactgrid; + productReference = 1A2D226D118E4A7600142450 /* compactgrid */; + productType = "com.apple.product-type.tool"; + }; + 1D6058900D05DD3D006BFB54 /* HazardMap */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HazardMap" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HazardMap; + productName = HazardMap; + productReference = 1D6058910D05DD3D006BFB54 /* HazardMap.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HazardMap" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* HazardMap */, + 1A2D226C118E4A7600142450 /* compactgrid */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A2D22A4118E4E7300142450 /* UShazard.20081229.pga.5pc50.bin in Resources */, + 53F418A311F6088C00740D86 /* HazardMapViewController.xib in Resources */, + 53F418A411F6088C00740D86 /* MainWindow.xib in Resources */, + 53ACD36911F6408700EA03E3 /* Icon-72.png in Resources */, + 53ACD36A11F6408700EA03E3 /* Icon-Small-50.png in Resources */, + 53ACD36B11F6408700EA03E3 /* Icon-Small.png in Resources */, + 53ACD36C11F6408700EA03E3 /* Icon-Small@2x.png in Resources */, + 53ACD36D11F6408700EA03E3 /* Icon.png in Resources */, + 53ACD36E11F6408700EA03E3 /* Icon@2x.png in Resources */, + 53ACD36F11F6408700EA03E3 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A2D226A118E4A7600142450 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A2D2271118E4AA800142450 /* compactgrid.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* HazardMapAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* HazardMapViewController.m in Sources */, + 1A316F2C118B8DD00091CC7B /* HazardMap.m in Sources */, + 1A316F9E118BB1AF0091CC7B /* HazardMapView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53F4189F11F6088C00740D86 /* HazardMapViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 53F418A011F6088C00740D86 /* en */, + ); + name = HazardMapViewController.xib; + sourceTree = ""; + }; + 53F418A111F6088C00740D86 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53F418A211F6088C00740D86 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A2D226F118E4A7700142450 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/bin; + PREBINDING = NO; + PRODUCT_NAME = compactgrid; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1A2D2270118E4A7700142450 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/bin; + PREBINDING = NO; + PRODUCT_NAME = compactgrid; + SDKROOT = macosx10.6; + ZERO_LINK = NO; + }; + name = Release; + }; + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = HazardMap_Prefix.pch; + INFOPLIST_FILE = "HazardMap-Info.plist"; + PRODUCT_NAME = HazardMap; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = HazardMap_Prefix.pch; + INFOPLIST_FILE = "HazardMap-Info.plist"; + PRODUCT_NAME = HazardMap; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A2D2287118E4B3700142450 /* Build configuration list for PBXNativeTarget "compactgrid" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A2D226F118E4A7700142450 /* Debug */, + 1A2D2270118E4A7700142450 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HazardMap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HazardMap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/HazardMap/HazardMap_Prefix.pch b/HazardMap/HazardMap_Prefix.pch new file mode 100644 index 0000000..4549128 --- /dev/null +++ b/HazardMap/HazardMap_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'HazardMap' target in the 'HazardMap' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/HazardMap/ReadMe.txt b/HazardMap/ReadMe.txt new file mode 100644 index 0000000..c831975 --- /dev/null +++ b/HazardMap/ReadMe.txt @@ -0,0 +1,73 @@ +### HazardMap ### + +=========================================================================== +DESCRIPTION: + +The HazardMap sample demonstrates how to create a custom Map Kit overlay and corresponding view to display USGS earthquake hazard data on top of an MKMapView. + +For more information on earthquake hazard data, see http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/. +This site includes 2008 NSHM Gridded Data files. + +=========================================================================== +BUILDING A HAZARD MAP: + +This sample already comes with a gridded hazard map showing quake severity zones in North America, "UShazard.20081229.pga.5pc50.bin", and it is included in this Xcode project.  You can create your own hazard maps by going to the USGS website, "http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/", and downloading another map. + +"compactgrid" +This sample includes a command-line tool called "compactgrid".  This is a standalone command line program to be run on Mac OS X's Terminal utility that performs preprocessing to compact a USGS tab separated earthquake hazard grid file into a smaller binary format that is faster to load on devices. + +To build the tool: +Select "compactgrid" as the active target in Xcode and select "Build" from the Build menu. +It requires the Mac OS X SDK, not iOS SDK.  If you experience build errors, that probably is due to having the wrong Active SDK selected for that target.  In this case, hold the option-key and select either your "Overview" or "Active SDK" popup menus.  Then proceed to select "Mac OS X 10.6" and build again. + +To run the tool: +1) navigate to the "Debug" or "Release" folders inside the "build" folder to find "compactgrid". +2) run the tool using Terminal as follows: + + compactgrid sourcehazardfile mygridfile.bin + +note: "sourcehazardfile" is the map file you just downloaded from the USGS site, "mygridfile.bin" is the output file. +This tool will write a file called "mygridfile.bin" in the current directory. +You can name that file any way you like but be sure to include .bin extension. + +To configure the new map into Xcode: +1) add the new .bin map file to your Xcode project in the "Resources" group. +2) open HazardMapViewController.m and change the "viewDidLoad" method to use that new file name. + + +=========================================================================== +BUILD REQUIREMENTS: + +iOS SDK 4.0 or later + +=========================================================================== +RUNTIME REQUIREMENTS: + +iOS OS 4.0 + +=========================================================================== +PACKAGING LIST: + +HazardMap +- Custom MKOverlay model class representing USGS Earthquake hazard data. + +HazardMapView +- Custom MKOverlayView class corresponding to the HazardMap model class. Demonstrates how to draw unprojected gridded data. + +HazardMapViewController +- Implements MKMapView delegate and shows how to display the custom HazardMap overlay on an MKMapView. + +UShazard.20081229.pga.5pc50.bin +- USGS Earthquake Hazard data fetched from http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/2008.US.pga.5pc50.txt.gz. This file has been compressed from the text version available directly from the USGS using compactgrid.c program included with the HazardMap sample project in order to reduce app launch time. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.1 +- Localized xib files, editorial changes. + +Version 1.0 +- First version. + +=========================================================================== +Copyright (C) 2010 Apple Inc. All rights reserved. diff --git a/HazardMap/UShazard.20081229.pga.5pc50.bin b/HazardMap/UShazard.20081229.pga.5pc50.bin new file mode 100644 index 0000000..67ee988 Binary files /dev/null and b/HazardMap/UShazard.20081229.pga.5pc50.bin differ diff --git a/HazardMap/compactgrid.c b/HazardMap/compactgrid.c new file mode 100644 index 0000000..6f20baf --- /dev/null +++ b/HazardMap/compactgrid.c @@ -0,0 +1,158 @@ +/* + File: compactgrid.c +Abstract: +This is a standalone command line program to be run on Mac OS X that performs preprocessing to compact +a USGS tab separated earthquake hazard grid file into a smaller binary format that is faster to load +on a mobile device. + +See http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/. + + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#include +#include +#include + +#include + +int main(int argc, char **argv) { + if (argc != 3) { + fprintf(stderr, "Usage %s gridfile.tab gridfile.bin\n", argv[0]); + exit(1); + } + + char *inpath = argv[1]; + char *outpath = argv[2]; + + // read in the whole file first in order to establish the bounds of the grid. + + FILE *in = fopen(inpath, "r"); + + size_t gridCount = 1000; + int read = 0; + float *grid = malloc(sizeof(float) * gridCount); + + double lastLat = -500; + double lastLon = -500; + float gridSize = -1; + int32_t gridWidth = -1; + double originLat = 0; + double originLon = 0; + + char line[50]; + + while (fgets(line, sizeof(line), in)) { + double lon, lat; + float value; + if (3 != sscanf(line, "%lf %lf %f", &lon, &lat, &value)) { + fprintf(stderr, "unparseable line: %s", line); + exit(2); + } + + if (lastLat < -200 && lastLon < -200) { + // first value, set the origin + originLat = lat; + originLon = lon; + } else if (gridSize == -1) { + // second value, set the grid size + gridSize = fabs(lon - lastLon); + } else if (lat != lastLat && gridWidth < 0) { + // end of first row, set the gridWidth + gridWidth = read; + } + + if (read == gridCount) { + gridCount *= 2; + grid = realloc(grid, sizeof(float) * gridCount); + } + + grid[read] = value; + + lastLon = lon; + lastLat = lat; + + read++; + } + + int32_t gridHeight = read / gridWidth; + + fclose(in); + + // write out the binary version of the file + // [4 bytes] - int32 little endian - grid origin latitudeE6 + // [4 bytes] - int32 little endian - grid origin longitudeE6 + // [4 bytes] - int32 little endian - grid step sizeE6 + // [4 bytes] - int32 little endian - grid width + // [4 bytes] - int32 little endian - grid height + // [N bytes] - list of width*height int16 little endian grid data as E4 fixed point + +#define E6 (1000000.0) +#define E4 (10000.0) + + FILE *out = fopen(outpath, "wb"); + + int32_t latE6 = OSSwapHostToLittleInt32(originLat * E6); + int32_t lonE6 = OSSwapHostToLittleInt32(originLon * E6); + int32_t gridSizeE6 = OSSwapHostToLittleInt32(gridSize * E6); + int32_t widthSwapped = OSSwapHostToLittleInt32(gridWidth); + int32_t heightSwapped = OSSwapHostToLittleInt32(gridHeight); + + fwrite(&latE6, sizeof(int32_t), 1, out); + fwrite(&lonE6, sizeof(int32_t), 1, out); + fwrite(&gridSizeE6, sizeof(int32_t), 1, out); + fwrite(&widthSwapped, sizeof(int32_t), 1, out); + fwrite(&heightSwapped, sizeof(int32_t), 1, out); + + int i; + for (i = 0; i < read; i++) { + int16_t valueSwapped = OSSwapHostToLittleInt16(grid[i] * E4); + fwrite(&valueSwapped, sizeof(int16_t), 1, out); + } + + fclose(out); + + return 0; +} + diff --git a/HazardMap/en.lproj/HazardMapViewController.xib b/HazardMap/en.lproj/HazardMapViewController.xib new file mode 100644 index 0000000..2200993 --- /dev/null +++ b/HazardMap/en.lproj/HazardMapViewController.xib @@ -0,0 +1,383 @@ + + + + 1024 + 10D573 + 786 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 114 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 274 + {320, 460} + + YES + YES + IBCocoaTouchFramework + + + {320, 460} + + + 3 + MC43NQA + + 2 + + + NO + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 7 + + + + delegate + + + + 9 + + + + map + + + + 10 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + YES + + + + + + 8 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 8.IBPluginDependency + + + YES + HazardMapViewController + UIResponder + {{239, 526}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 10 + + + + YES + + HazardMapViewController + UIViewController + + map + MKMapView + + + map + + map + MKMapView + + + + IBProjectSource + Classes/HazardMapViewController.h + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + HazardMap.xcodeproj + 3 + 114 + + diff --git a/HazardMap/en.lproj/MainWindow.xib b/HazardMap/en.lproj/MainWindow.xib new file mode 100644 index 0000000..cdca125 --- /dev/null +++ b/HazardMap/en.lproj/MainWindow.xib @@ -0,0 +1,444 @@ + + + + 1024 + 10D571 + 786 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 112 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + HazardMapViewController + + + 1 + + IBCocoaTouchFramework + NO + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + IBCocoaTouchFramework + YES + + + + + YES + + + delegate + + + + 4 + + + + viewController + + + + 11 + + + + window + + + + 14 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + HazardMap App Delegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + HazardMapViewController + {{234, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + HazardMapAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 15 + + + + YES + + UIWindow + UIView + + IBUserSource + + + + + HazardMapAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + HazardMapViewController + UIWindow + + + + YES + + YES + viewController + window + + + YES + + viewController + HazardMapViewController + + + window + UIWindow + + + + + IBProjectSource + Classes/HazardMapAppDelegate.h + + + + HazardMapAppDelegate + NSObject + + IBUserSource + + + + + HazardMapViewController + UIViewController + + IBProjectSource + Classes/HazardMapViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + HazardMap.xcodeproj + 3 + 112 + + diff --git a/HazardMap/images/Icon-72.png b/HazardMap/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/HazardMap/images/Icon-72.png differ diff --git a/HazardMap/images/Icon-Small-50.png b/HazardMap/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/HazardMap/images/Icon-Small-50.png differ diff --git a/HazardMap/images/Icon-Small.png b/HazardMap/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/HazardMap/images/Icon-Small.png differ diff --git a/HazardMap/images/Icon-Small@2x.png b/HazardMap/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/HazardMap/images/Icon-Small@2x.png differ diff --git a/HazardMap/images/Icon.png b/HazardMap/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/HazardMap/images/Icon.png differ diff --git a/HazardMap/images/Icon@2x.png b/HazardMap/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/HazardMap/images/Icon@2x.png differ diff --git a/HazardMap/images/iTunesArtwork b/HazardMap/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/HazardMap/images/iTunesArtwork differ diff --git a/HazardMap/main.m b/HazardMap/main.m new file mode 100644 index 0000000..4532498 --- /dev/null +++ b/HazardMap/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Template main function. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/HeaderFooter.zip b/HeaderFooter.zip new file mode 100644 index 0000000..0960398 Binary files /dev/null and b/HeaderFooter.zip differ diff --git a/HeaderFooter/AppDelegate.h b/HeaderFooter/AppDelegate.h new file mode 100755 index 0000000..4145256 --- /dev/null +++ b/HeaderFooter/AppDelegate.h @@ -0,0 +1,61 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for loading our navigation controller. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class MyTableViewController; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *myNavController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *myNavController; + +@end diff --git a/HeaderFooter/AppDelegate.m b/HeaderFooter/AppDelegate.m new file mode 100755 index 0000000..52efc62 --- /dev/null +++ b/HeaderFooter/AppDelegate.m @@ -0,0 +1,71 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for loading our navigation controller. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MyTableViewController.h" + +@implementation AppDelegate; + +@synthesize window, myNavController; + +- (void)dealloc +{ + [myNavController release]; + [window release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + [window addSubview:myNavController.view]; + + [window makeKeyAndVisible]; +} + +@end diff --git a/HeaderFooter/HeaderFooter.xcodeproj/project.pbxproj b/HeaderFooter/HeaderFooter.xcodeproj/project.pbxproj new file mode 100755 index 0000000..a2d73b2 --- /dev/null +++ b/HeaderFooter/HeaderFooter.xcodeproj/project.pbxproj @@ -0,0 +1,312 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 18247EFB11D91D770022009F /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18247EFA11D91D770022009F /* iTunesArtwork */; }; + 182B397B11D1631F003EE100 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B397911D1631F003EE100 /* Default.png */; }; + 182B397C11D1631F003EE100 /* GenericContact.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B397A11D1631F003EE100 /* GenericContact.png */; }; + 182B398411D1632E003EE100 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B397D11D1632E003EE100 /* Icon-72.png */; }; + 182B398511D1632E003EE100 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B397E11D1632E003EE100 /* Icon-Small-50.png */; }; + 182B398611D1632E003EE100 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B397F11D1632E003EE100 /* Icon-Small.png */; }; + 182B398711D1632E003EE100 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B398011D1632E003EE100 /* Icon-Small@2x.png */; }; + 182B398811D1632E003EE100 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B398111D1632E003EE100 /* Icon.png */; }; + 182B398911D1632E003EE100 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182B398211D1632E003EE100 /* Icon@2x.png */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 5363CC231003C33D006CE070 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5363CC1F1003C33D006CE070 /* main.m */; }; + 5363CC261003C342006CE070 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5363CC251003C342006CE070 /* AppDelegate.m */; }; + 53A7EA9011D1569100137A2C /* MyTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A7EA8F11D1569100137A2C /* MyTableViewController.m */; }; + 53D27A0E100E80D100026599 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53D27A0D100E80D100026599 /* AudioToolbox.framework */; }; + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EACC050DDA319F00908D73 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 18247EFA11D91D770022009F /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 182B397911D1631F003EE100 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 182B397A11D1631F003EE100 /* GenericContact.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = GenericContact.png; path = images/GenericContact.png; sourceTree = ""; }; + 182B397D11D1632E003EE100 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 182B397E11D1632E003EE100 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 182B397F11D1632E003EE100 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 182B398011D1632E003EE100 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 182B398111D1632E003EE100 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 182B398211D1632E003EE100 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* HeaderFooter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HeaderFooter.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 53063B351178C93800B6DA5A /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 5363CC1F1003C33D006CE070 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5363CC201003C33D006CE070 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 5363CC241003C342006CE070 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5363CC251003C342006CE070 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 53A7EA8E11D1569100137A2C /* MyTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTableViewController.h; sourceTree = ""; }; + 53A7EA8F11D1569100137A2C /* MyTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTableViewController.m; sourceTree = ""; }; + 53D27A0D100E80D100026599 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 53EACC060DDA319F00908D73 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 53D27A0E100E80D100026599 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* HeaderFooter.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53063B351178C93800B6DA5A /* ReadMe.txt */, + 53AF8AEC0D9C50B700726DBA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18247EFA11D91D770022009F /* iTunesArtwork */, + 182B397D11D1632E003EE100 /* Icon-72.png */, + 182B397E11D1632E003EE100 /* Icon-Small-50.png */, + 182B397F11D1632E003EE100 /* Icon-Small.png */, + 182B398011D1632E003EE100 /* Icon-Small@2x.png */, + 182B398111D1632E003EE100 /* Icon.png */, + 182B398211D1632E003EE100 /* Icon@2x.png */, + 182B397911D1631F003EE100 /* Default.png */, + 182B397A11D1631F003EE100 /* GenericContact.png */, + 8D1107310486CEB800E47090 /* Info.plist */, + 53EACC050DDA319F00908D73 /* MainWindow.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 53D27A0D100E80D100026599 /* AudioToolbox.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53AF8AEC0D9C50B700726DBA /* Sources */ = { + isa = PBXGroup; + children = ( + 5363CC201003C33D006CE070 /* Prefix.pch */, + 5363CC1F1003C33D006CE070 /* main.m */, + 5363CC241003C342006CE070 /* AppDelegate.h */, + 5363CC251003C342006CE070 /* AppDelegate.m */, + 53A7EA8E11D1569100137A2C /* MyTableViewController.h */, + 53A7EA8F11D1569100137A2C /* MyTableViewController.m */, + ); + name = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* HeaderFooter */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HeaderFooter" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HeaderFooter; + productName = IBTest; + productReference = 1D6058910D05DD3D006BFB54 /* HeaderFooter.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HeaderFooter" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* HeaderFooter */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */, + 182B397B11D1631F003EE100 /* Default.png in Resources */, + 182B397C11D1631F003EE100 /* GenericContact.png in Resources */, + 182B398411D1632E003EE100 /* Icon-72.png in Resources */, + 182B398511D1632E003EE100 /* Icon-Small-50.png in Resources */, + 182B398611D1632E003EE100 /* Icon-Small.png in Resources */, + 182B398711D1632E003EE100 /* Icon-Small@2x.png in Resources */, + 182B398811D1632E003EE100 /* Icon.png in Resources */, + 182B398911D1632E003EE100 /* Icon@2x.png in Resources */, + 18247EFB11D91D770022009F /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5363CC231003C33D006CE070 /* main.m in Sources */, + 5363CC261003C342006CE070 /* AppDelegate.m in Sources */, + 53A7EA9011D1569100137A2C /* MyTableViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53EACC050DDA319F00908D73 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53EACC060DDA319F00908D73 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = HeaderFooter; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = HeaderFooter; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HeaderFooter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HeaderFooter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/HeaderFooter/Info.plist b/HeaderFooter/Info.plist new file mode 100755 index 0000000..877b81c --- /dev/null +++ b/HeaderFooter/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.3 + NSMainNibFile + MainWindow + LSRequiresIPhoneOS + + + diff --git a/HeaderFooter/MyTableViewController.h b/HeaderFooter/MyTableViewController.h new file mode 100644 index 0000000..fb93536 --- /dev/null +++ b/HeaderFooter/MyTableViewController.h @@ -0,0 +1,65 @@ +/* + File: MyTableViewController.h + Abstract: The main view controller of this app. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface MyTableViewController : UITableViewController +{ + UIView *myHeaderView; + UIView *myFooterView; + + NSArray *tableArray; +} + +@property (nonatomic, retain) IBOutlet UIView *myHeaderView; +@property (nonatomic, retain) IBOutlet UIView *myFooterView; +@property (nonatomic, retain) NSArray *tableArray; + +- (IBAction)button1Action:(id)sender; +- (IBAction)button2Action:(id)sender; + +@end diff --git a/HeaderFooter/MyTableViewController.m b/HeaderFooter/MyTableViewController.m new file mode 100644 index 0000000..a848f27 --- /dev/null +++ b/HeaderFooter/MyTableViewController.m @@ -0,0 +1,138 @@ +/* + File: MyTableViewController.m + Abstract: The main view controller of this app. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyTableViewController.h" + +@implementation MyTableViewController + +@synthesize myHeaderView, myFooterView, tableArray; + +- (void)viewDidLoad +{ + // setup our table data + self.tableArray = [NSArray arrayWithObjects:@"Camping", @"Water Skiing", @"Weight Lifting", @"Stamp Collecting", nil]; + + // set up the table's header view based on our UIView 'myHeaderView' outlet + CGRect newFrame = CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, self.myHeaderView.frame.size.height); + self.myHeaderView.backgroundColor = [UIColor clearColor]; + self.myHeaderView.frame = newFrame; + self.tableView.tableHeaderView = self.myHeaderView; // note this will override UITableView's 'sectionHeaderHeight' property + + // set up the table's footer view based on our UIView 'myFooterView' outlet + newFrame = CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, self.myFooterView.frame.size.height); + self.myFooterView.backgroundColor = [UIColor clearColor]; + self.myFooterView.frame = newFrame; + self.tableView.tableFooterView = self.myFooterView; // note this will override UITableView's 'sectionFooterHeight' property +} + +// called after the view controller's view is released and set to nil. +// For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc. +// So release any properties that are loaded in viewDidLoad or can be recreated lazily. +// +- (void)viewDidUnload +{ + self.myHeaderView = nil; + self.myFooterView = nil; + self.tableArray = nil; +} + +- (void)dealloc +{ + [myFooterView release]; + [myHeaderView release]; + [tableArray release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark UITableViewDataSource + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return @"Hobby Information:"; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [tableArray count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kCellID = @"cellID"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease]; + cell.accessoryType = UITableViewCellAccessoryNone; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + + cell.textLabel.text = [tableArray objectAtIndex:[indexPath row]]; + + return cell; +} + + +#pragma mark - +#pragma mark Action methods + +- (IBAction)button1Action:(id)sender +{ + // Button1 was pressed +} + +- (IBAction)button2Action:(id)sender +{ + // Button2 was pressed +} + +@end + diff --git a/HeaderFooter/Prefix.pch b/HeaderFooter/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/HeaderFooter/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/HeaderFooter/ReadMe.txt b/HeaderFooter/ReadMe.txt new file mode 100644 index 0000000..7cc5ceb --- /dev/null +++ b/HeaderFooter/ReadMe.txt @@ -0,0 +1,36 @@ +HeaderFooter + +Demonstrates how to implement and customize the 2 UIView properties of UITableView: + header ('tableHeaderView') and footer ('tableFooterView'). +It is designed to somewhat resemble the "Contacts" application, showing you ways to design your own header and footer content. It uses the UITableViewStyle: UITableViewStyleGrouped to achieve a more similar appearance as well. + +This sample implements two basic UIViews from a nib file: one for the header and one for the footer. Each as IBOutlets are set as header and footer properties of the UITableView. Additional code is provided to illustrate how to set their transparent background colors, but the same work that can also be done in the UIView's xib. + + +Build Requirements +iOS 4.0 SDK + + +Runtime Requirements +iPhone OS 3.2 or later + + +Using the Sample +Launch the HeaderFooter project using Xcode. + +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. When launched notice the customized header and footer for the grouped-style UITableView. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application's delegate to setup its window and content. +MyTableViewController.h/.m - The main UIViewController containing the header/footer example for UITableView. + + +Changes from Previous Versions +1.0 - First release. +1.1 - Upgraded for 3.0 SDK due to deprecated APIs; in "cellForRowAtIndexPath" it now uses UITableViewCell's initWithStyle. +1.2 - Upgraded project to build with the iOS 4.0 SDK. +1.3 - Added CFBundleIconFiles in Info.plist. + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/HeaderFooter/en.lproj/MainWindow.xib b/HeaderFooter/en.lproj/MainWindow.xib new file mode 100644 index 0000000..85a7355 --- /dev/null +++ b/HeaderFooter/en.lproj/MainWindow.xib @@ -0,0 +1,543 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + 292 + + YES + + + 292 + {{20, 18}, {62, 62}} + + NO + NO + 4 + NO + + NSImage + GenericContact.png + + + + + 291 + {{96, 39}, {221, 21}} + + NO + YES + NO + Johnny Appleseed + + Helvetica-Bold + 1.700000e+01 + 16 + + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + + + {332, 80} + + + 3 + MQA + + 2 + + + NO + + + + 292 + + YES + + + 292 + {{8, 0}, {145, 44}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + Button 1 + Button 1 + Button 1 + Button 1 + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + 292 + {{165, 0}, {145, 44}} + + NO + NO + 0 + 0 + + 1 + Button 2 + Button 2 + Button 2 + Button 2 + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + {320, 44} + + + 3 + MQA + + + NO + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 416} + + NO + YES + NO + 1 + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + + HeaderFooter + + + + + + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + delegate + + + + 57 + + + + dataSource + + + + 58 + + + + myHeaderView + + + + 63 + + + + myFooterView + + + + 68 + + + + myNavController + + + + 74 + + + + button1Action: + + + 7 + + 88 + + + + button2Action: + + + 7 + + 89 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 60 + + + YES + + + + + HeaderView + + + 61 + + + + + 64 + + + + + 65 + + + YES + + + + + FooterView + + + 66 + + + + + 67 + + + + + 69 + + + YES + + + + + + + 71 + + + + + 55 + + + YES + + + + + MyTableViewController + + + 56 + + + + + 73 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 55.CustomClassName + 55.IBEditorWindowLastContentRect + 55.IBPluginDependency + 56.IBPluginDependency + 60.IBEditorWindowLastContentRect + 60.IBPluginDependency + 61.IBPluginDependency + 64.IBPluginDependency + 65.IBEditorWindowLastContentRect + 65.IBPluginDependency + 66.IBPluginDependency + 67.IBPluginDependency + 69.IBEditorWindowLastContentRect + 69.IBPluginDependency + 71.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyTableViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{360, 678}, {332, 80}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{603, 400}, {320, 44}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 89 + + + + YES + + AppDelegate + NSObject + + YES + + YES + myNavController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + MyTableViewController + UITableViewController + + YES + + YES + button1Action: + button2Action: + + + YES + id + id + + + + YES + + YES + myFooterView + myHeaderView + + + YES + UIView + UIView + + + + IBProjectSource + MyTableViewController.h + + + + + 0 + ../HeaderFooter.xcodeproj + 3 + + diff --git a/HeaderFooter/images/Default.png b/HeaderFooter/images/Default.png new file mode 100644 index 0000000..05af97d Binary files /dev/null and b/HeaderFooter/images/Default.png differ diff --git a/HeaderFooter/images/GenericContact.png b/HeaderFooter/images/GenericContact.png new file mode 100644 index 0000000..c441c02 Binary files /dev/null and b/HeaderFooter/images/GenericContact.png differ diff --git a/HeaderFooter/images/Icon-72.png b/HeaderFooter/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/HeaderFooter/images/Icon-72.png differ diff --git a/HeaderFooter/images/Icon-Small-50.png b/HeaderFooter/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/HeaderFooter/images/Icon-Small-50.png differ diff --git a/HeaderFooter/images/Icon-Small.png b/HeaderFooter/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/HeaderFooter/images/Icon-Small.png differ diff --git a/HeaderFooter/images/Icon-Small@2x.png b/HeaderFooter/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/HeaderFooter/images/Icon-Small@2x.png differ diff --git a/HeaderFooter/images/Icon.png b/HeaderFooter/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/HeaderFooter/images/Icon.png differ diff --git a/HeaderFooter/images/Icon@2x.png b/HeaderFooter/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/HeaderFooter/images/Icon@2x.png differ diff --git a/HeaderFooter/images/iTunesArtwork b/HeaderFooter/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/HeaderFooter/images/iTunesArtwork differ diff --git a/HeaderFooter/main.m b/HeaderFooter/main.m new file mode 100755 index 0000000..ca088f5 --- /dev/null +++ b/HeaderFooter/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/Icons.zip b/Icons.zip new file mode 100644 index 0000000..74ed930 Binary files /dev/null and b/Icons.zip differ diff --git a/Icons/Icons-Info.plist b/Icons/Icons-Info.plist new file mode 100644 index 0000000..4ad7fda --- /dev/null +++ b/Icons/Icons-Info.plist @@ -0,0 +1,48 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon-72.png + Icon@2x.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Icons/Icons.xcodeproj/jakebehrens.mode1v3 b/Icons/Icons.xcodeproj/jakebehrens.mode1v3 new file mode 100644 index 0000000..3ff98bf --- /dev/null +++ b/Icons/Icons.xcodeproj/jakebehrens.mode1v3 @@ -0,0 +1,1424 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 9FEDA338125BC11000D0F59C + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 303 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 28EEBF621118D79A00187D67 + 29B97315FDCFA39411CA2CEA + 9F2BD5DB1263DA490016473B + 9FC6A52B126D05E2008D73BA + 9FC6A52D126D05E2008D73BA + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 11 + 10 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {303, 760}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {320, 778}} + GroupTreeTableConfiguration + + MainColumn + 303 + + RubberWindowFrame + 0 59 1440 819 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 320pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + ReadMe.txt + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + ReadMe.txt + _historyCapacity + 0 + bookmark + 9FC6A546126D0AE8008D73BA + history + + 9FEDA354125BC1F400D0F59C + 9FEDA355125BC1F400D0F59C + 9FEDA356125BC1F400D0F59C + 9FEDA357125BC1F400D0F59C + 9FEDA358125BC1F400D0F59C + 9FEDA359125BC1F400D0F59C + 9F0A0C9F1263838B003A4DDB + 9F0A0CA21263838B003A4DDB + 9F0A0CB712638484003A4DDB + 9F0A0CBA12638484003A4DDB + 9F26331C1263A47C00DA83F1 + 9F26331D1263A47C00DA83F1 + 9F2633551263ADBC00DA83F1 + 9F2BD5DC1263DA590016473B + 9F0C8952126CE2D40016DE7E + 9FC6A47E126CE597008D73BA + 9FC6A487126CE6D5008D73BA + 9FC6A488126CE6D5008D73BA + 9FC6A535126D05F6008D73BA + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1115, 773}} + RubberWindowFrame + 0 59 1440 819 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 773pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 778}, {1115, 0}} + RubberWindowFrame + 0 59 1440 819 0 0 1440 878 + + Module + XCDetailModule + Proportion + 0pt + + + Proportion + 1115pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 9FC6A547126D0AE8008D73BA + 1CE0B1FE06471DED0097A5F4 + 9FC6A548126D0AE8008D73BA + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 9FEDA339125BC11000D0F59C + /Users/jakebehrens/Code/Sample Code GM/Icons/Icons.xcodeproj + + WindowString + 0 59 1440 819 0 0 1440 878 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {936, 148}} + RubberWindowFrame + 347 346 936 430 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 148pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 153}, {936, 236}} + RubberWindowFrame + 347 346 936 430 0 0 1440 878 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 389pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 9FEDA339125BC11000D0F59C + 9FC6A549126D0AE8008D73BA + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 347 346 936 430 0 0 1440 878 + WindowToolGUID + 9FEDA339125BC11000D0F59C + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 21 433 694 422 0 0 1440 878 + + RubberWindowFrame + 21 433 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 9FC6A539126D05F6008D73BA + 1C162984064C10D400B95A72 + 9FC6A53A126D05F6008D73BA + 9FC6A53B126D05F6008D73BA + 9FC6A53C126D05F6008D73BA + 9FC6A53D126D05F6008D73BA + 9FC6A53E126D05F6008D73BA + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 21 433 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + ReadMe.txt + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {938, 283}} + RubberWindowFrame + 42 201 938 631 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 938pt + + + Proportion + 283pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 288}, {938, 302}} + RubberWindowFrame + 42 201 938 631 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 302pt + + + Proportion + 590pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 9FC6A46B126CE4CF008D73BA + 9FC6A46C126CE4CF008D73BA + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 42 201 938 631 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {967, 563}} + RubberWindowFrame + 21 251 967 604 0 0 1440 878 + + Module + PBXDebugCLIModule + Proportion + 563pt + + + Proportion + 563pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 9FC6A53F126D05F6008D73BA + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 21 251 967 604 0 0 1440 878 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 9F0C8960126CE2D40016DE7E + + GeometryConfiguration + + Frame + {{0, 0}, {500, 315}} + RubberWindowFrame + 21 499 500 356 0 0 1440 878 + + Module + XCRefactoringModule + Proportion + 315pt + + + Proportion + 315pt + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + StatusbarIsVisible + + TableOfContents + + 9F0C8961126CE2D40016DE7E + 9F0C8962126CE2D40016DE7E + 9F0C8960126CE2D40016DE7E + + WindowString + 21 499 500 356 0 0 1440 878 + WindowToolGUID + 9F0C8961126CE2D40016DE7E + WindowToolIsVisible + + + + + diff --git a/Icons/Icons.xcodeproj/project.pbxproj b/Icons/Icons.xcodeproj/project.pbxproj new file mode 100755 index 0000000..8d1d3f2 --- /dev/null +++ b/Icons/Icons.xcodeproj/project.pbxproj @@ -0,0 +1,342 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 9F2632C01263890E00DA83F1 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9F2632BF1263890E00DA83F1 /* ReadMe.txt */; }; + 9F2632D812638B5C00DA83F1 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F2632D512638B5C00DA83F1 /* RootViewController.m */; }; + 9F2632DC12638B8700DA83F1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F2632DB12638B8700DA83F1 /* main.m */; }; + 9F2633171263A45F00DA83F1 /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F2633131263A45F00DA83F1 /* Default-Landscape.png */; }; + 9F2633181263A45F00DA83F1 /* Default-Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F2633141263A45F00DA83F1 /* Default-Portrait.png */; }; + 9F2633191263A45F00DA83F1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F2633151263A45F00DA83F1 /* Default.png */; }; + 9F26331A1263A45F00DA83F1 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F2633161263A45F00DA83F1 /* Default@2x.png */; }; + 9F2BD5F31263DA8A0016473B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 9F2BD5F21263DA8A0016473B /* Settings.bundle */; }; + 9FC6A492126CE71E008D73BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FC6A491126CE71E008D73BA /* AppDelegate.m */; }; + 9FC6A52F126D05E2008D73BA /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FC6A52B126D05E2008D73BA /* MainWindow.xib */; }; + 9FC6A530126D05E2008D73BA /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FC6A52D126D05E2008D73BA /* RootViewController.xib */; }; + 9FEDA345125BC13100D0F59C /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA33E125BC13100D0F59C /* Icon-72.png */; }; + 9FEDA346125BC13100D0F59C /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA33F125BC13100D0F59C /* Icon-Small-50.png */; }; + 9FEDA347125BC13100D0F59C /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA340125BC13100D0F59C /* Icon-Small.png */; }; + 9FEDA348125BC13100D0F59C /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA341125BC13100D0F59C /* Icon-Small@2x.png */; }; + 9FEDA349125BC13100D0F59C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA342125BC13100D0F59C /* Icon.png */; }; + 9FEDA34A125BC13100D0F59C /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA343125BC13100D0F59C /* Icon@2x.png */; }; + 9FEDA34B125BC13100D0F59C /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 9FEDA344125BC13100D0F59C /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* Icons.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Icons.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* Icons_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Icons_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Icons-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Icons-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + 9F2632BF1263890E00DA83F1 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 9F2632D412638B5C00DA83F1 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RootViewController.h; path = Shared/RootViewController.h; sourceTree = ""; }; + 9F2632D512638B5C00DA83F1 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RootViewController.m; path = Shared/RootViewController.m; sourceTree = ""; }; + 9F2632DB12638B8700DA83F1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 9F2633131263A45F00DA83F1 /* Default-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape.png"; sourceTree = ""; }; + 9F2633141263A45F00DA83F1 /* Default-Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait.png"; sourceTree = ""; }; + 9F2633151263A45F00DA83F1 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 9F2633161263A45F00DA83F1 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; + 9F2BD5F21263DA8A0016473B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; + 9FC6A490126CE71E008D73BA /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Shared/AppDelegate.h; sourceTree = ""; }; + 9FC6A491126CE71E008D73BA /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Shared/AppDelegate.m; sourceTree = ""; }; + 9FC6A52C126D05E2008D73BA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 9FC6A52E126D05E2008D73BA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; + 9FEDA33E125BC13100D0F59C /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 9FEDA33F125BC13100D0F59C /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 9FEDA340125BC13100D0F59C /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 9FEDA341125BC13100D0F59C /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 9FEDA342125BC13100D0F59C /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 9FEDA343125BC13100D0F59C /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 9FEDA344125BC13100D0F59C /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Icons.app */, + ); + name = Products; + sourceTree = ""; + }; + 28EEBF621118D79A00187D67 /* Shared */ = { + isa = PBXGroup; + children = ( + 9FC6A490126CE71E008D73BA /* AppDelegate.h */, + 9FC6A491126CE71E008D73BA /* AppDelegate.m */, + 9F2632D412638B5C00DA83F1 /* RootViewController.h */, + 9F2632D512638B5C00DA83F1 /* RootViewController.m */, + ); + name = Shared; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 9F2632BF1263890E00DA83F1 /* ReadMe.txt */, + 28EEBF621118D79A00187D67 /* Shared */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 9F2BD5DB1263DA490016473B /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Icons_Prefix.pch */, + 9F2632DB12638B8700DA83F1 /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9F2BD5DB1263DA490016473B /* Resources */ = { + isa = PBXGroup; + children = ( + 9FC6A52B126D05E2008D73BA /* MainWindow.xib */, + 9FC6A52D126D05E2008D73BA /* RootViewController.xib */, + 8D1107310486CEB800E47090 /* Icons-Info.plist */, + 9FEDA33D125BC13100D0F59C /* Images */, + 9F2BD5F21263DA8A0016473B /* Settings.bundle */, + ); + name = Resources; + sourceTree = ""; + }; + 9FEDA33D125BC13100D0F59C /* Images */ = { + isa = PBXGroup; + children = ( + 9FEDA33E125BC13100D0F59C /* Icon-72.png */, + 9FEDA33F125BC13100D0F59C /* Icon-Small-50.png */, + 9FEDA340125BC13100D0F59C /* Icon-Small.png */, + 9FEDA341125BC13100D0F59C /* Icon-Small@2x.png */, + 9FEDA342125BC13100D0F59C /* Icon.png */, + 9FEDA343125BC13100D0F59C /* Icon@2x.png */, + 9FEDA344125BC13100D0F59C /* iTunesArtwork */, + 9F2633151263A45F00DA83F1 /* Default.png */, + 9F2633161263A45F00DA83F1 /* Default@2x.png */, + 9F2633141263A45F00DA83F1 /* Default-Portrait.png */, + 9F2633131263A45F00DA83F1 /* Default-Landscape.png */, + ); + path = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Icons */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Icons" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Icons; + productName = Icons; + productReference = 1D6058910D05DD3D006BFB54 /* Icons.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Icons" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Icons */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9FEDA345125BC13100D0F59C /* Icon-72.png in Resources */, + 9FEDA346125BC13100D0F59C /* Icon-Small-50.png in Resources */, + 9FEDA347125BC13100D0F59C /* Icon-Small.png in Resources */, + 9FEDA348125BC13100D0F59C /* Icon-Small@2x.png in Resources */, + 9FEDA349125BC13100D0F59C /* Icon.png in Resources */, + 9FEDA34A125BC13100D0F59C /* Icon@2x.png in Resources */, + 9FEDA34B125BC13100D0F59C /* iTunesArtwork in Resources */, + 9F2632C01263890E00DA83F1 /* ReadMe.txt in Resources */, + 9F2633171263A45F00DA83F1 /* Default-Landscape.png in Resources */, + 9F2633181263A45F00DA83F1 /* Default-Portrait.png in Resources */, + 9F2633191263A45F00DA83F1 /* Default.png in Resources */, + 9F26331A1263A45F00DA83F1 /* Default@2x.png in Resources */, + 9F2BD5F31263DA8A0016473B /* Settings.bundle in Resources */, + 9FC6A52F126D05E2008D73BA /* MainWindow.xib in Resources */, + 9FC6A530126D05E2008D73BA /* RootViewController.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9F2632D812638B5C00DA83F1 /* RootViewController.m in Sources */, + 9F2632DC12638B8700DA83F1 /* main.m in Sources */, + 9FC6A492126CE71E008D73BA /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 9FC6A52B126D05E2008D73BA /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 9FC6A52C126D05E2008D73BA /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 9FC6A52D126D05E2008D73BA /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 9FC6A52E126D05E2008D73BA /* en */, + ); + name = RootViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Icons_Prefix.pch; + INFOPLIST_FILE = "Icons-Info.plist"; + PRODUCT_NAME = Icons; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Icons_Prefix.pch; + INFOPLIST_FILE = "Icons-Info.plist"; + PRODUCT_NAME = Icons; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Icons" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Icons" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Icons/Icons_Prefix.pch b/Icons/Icons_Prefix.pch new file mode 100644 index 0000000..15b3b7e --- /dev/null +++ b/Icons/Icons_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'Icons' target in the 'Icons' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Icons/Images/Default-Landscape.png b/Icons/Images/Default-Landscape.png new file mode 100644 index 0000000..a761e72 Binary files /dev/null and b/Icons/Images/Default-Landscape.png differ diff --git a/Icons/Images/Default-Portrait.png b/Icons/Images/Default-Portrait.png new file mode 100644 index 0000000..8d8250c Binary files /dev/null and b/Icons/Images/Default-Portrait.png differ diff --git a/Icons/Images/Default.png b/Icons/Images/Default.png new file mode 100644 index 0000000..9ba7f5b Binary files /dev/null and b/Icons/Images/Default.png differ diff --git a/Icons/Images/Default@2x.png b/Icons/Images/Default@2x.png new file mode 100644 index 0000000..bdd696c Binary files /dev/null and b/Icons/Images/Default@2x.png differ diff --git a/Icons/Images/Icon-72.png b/Icons/Images/Icon-72.png new file mode 100644 index 0000000..84b77fc Binary files /dev/null and b/Icons/Images/Icon-72.png differ diff --git a/Icons/Images/Icon-Small-50.png b/Icons/Images/Icon-Small-50.png new file mode 100644 index 0000000..e16b3c6 Binary files /dev/null and b/Icons/Images/Icon-Small-50.png differ diff --git a/Icons/Images/Icon-Small.png b/Icons/Images/Icon-Small.png new file mode 100644 index 0000000..40182fa Binary files /dev/null and b/Icons/Images/Icon-Small.png differ diff --git a/Icons/Images/Icon-Small@2x.png b/Icons/Images/Icon-Small@2x.png new file mode 100644 index 0000000..ebb08bc Binary files /dev/null and b/Icons/Images/Icon-Small@2x.png differ diff --git a/Icons/Images/Icon.png b/Icons/Images/Icon.png new file mode 100644 index 0000000..092f773 Binary files /dev/null and b/Icons/Images/Icon.png differ diff --git a/Icons/Images/Icon@2x.png b/Icons/Images/Icon@2x.png new file mode 100644 index 0000000..dff9029 Binary files /dev/null and b/Icons/Images/Icon@2x.png differ diff --git a/Icons/Images/iTunesArtwork b/Icons/Images/iTunesArtwork new file mode 100644 index 0000000..7e80282 Binary files /dev/null and b/Icons/Images/iTunesArtwork differ diff --git a/Icons/ReadMe.txt b/Icons/ReadMe.txt new file mode 100644 index 0000000..9f3aea9 --- /dev/null +++ b/Icons/ReadMe.txt @@ -0,0 +1,41 @@ +Icons + +================================================================================ +ABSTRACT: + +This sample demonstrates the proper use of application icons on iOS. +This is a universal binary that supports iPhone/iPod touch/iPad and includes +support for high resolution displays. + +Each icon has one dimension of the pixel dimensions on it to display which icon is being used by various areas of iOS. +The various icons display when using the Homescreen, Spotlight, the Settings app, different devices, and when creating an Ad Hoc build and adding it to iTunes. + + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.1 or later + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +AppDelegate +The application delegate sets up the initial iPhone/iPod touch/iPad view and makes the window visible. + +RootViewController +The view controller displays what each icon does on iOS. +The proper orientations supported by each device type are configured in the -shouldAutorotateToInterfaceOrientation: method. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.0 +- First version. + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/Icons/Settings.bundle/Root.plist b/Icons/Settings.bundle/Root.plist new file mode 100644 index 0000000..b1b6fea --- /dev/null +++ b/Icons/Settings.bundle/Root.plist @@ -0,0 +1,61 @@ + + + + + StringsTable + Root + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Group + + + Type + PSTextFieldSpecifier + Title + Name + Key + name_preference + DefaultValue + + IsSecure + + KeyboardType + Alphabet + AutocapitalizationType + None + AutocorrectionType + No + + + Type + PSToggleSwitchSpecifier + Title + Enabled + Key + enabled_preference + DefaultValue + + + + Type + PSSliderSpecifier + Key + slider_preference + DefaultValue + 0.5 + MinimumValue + 0 + MaximumValue + 1 + MinimumValueImage + + MaximumValueImage + + + + + diff --git a/Icons/Settings.bundle/en.lproj/Root.strings b/Icons/Settings.bundle/en.lproj/Root.strings new file mode 100644 index 0000000..8cd87b9 Binary files /dev/null and b/Icons/Settings.bundle/en.lproj/Root.strings differ diff --git a/Icons/Shared/AppDelegate.h b/Icons/Shared/AppDelegate.h new file mode 100644 index 0000000..284f588 --- /dev/null +++ b/Icons/Shared/AppDelegate.h @@ -0,0 +1,61 @@ +/* + File: AppDelegate.h + Abstract: The application delegate sets up the initial iPhone/iPod touch/iPad view and makes the window visible. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class RootViewController; + +@interface AppDelegate : NSObject { + UIWindow *window; + RootViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet RootViewController *viewController; + +@end + diff --git a/Icons/Shared/AppDelegate.m b/Icons/Shared/AppDelegate.m new file mode 100644 index 0000000..56e708b --- /dev/null +++ b/Icons/Shared/AppDelegate.m @@ -0,0 +1,123 @@ +/* + File: AppDelegate.m + Abstract: The application delegate sets up the initial iPhone/iPod touch/iPad view and makes the window visible. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "RootViewController.h" + +@implementation AppDelegate + +@synthesize window, viewController; + +#pragma mark - +#pragma mark Application lifecycle + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Add the root view controller view to the window. + [window addSubview:viewController.view]; + // Make the window the first responder and visible on launch. + [window makeKeyAndVisible]; + + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + /* + Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + */ +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + /* + Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + If your application supports background execution, called instead of applicationWillTerminate: when the user quits. + */ +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + /* + Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. + */ +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + /* + Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + */ +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + /* + Called when the application is about to terminate. + See also applicationDidEnterBackground:. + */ +} + + +#pragma mark - +#pragma mark Memory management + +- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { + /* + Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. + */ +} + + +- (void)dealloc { + [window release]; + [viewController release]; + [super dealloc]; +} + + +@end diff --git a/Icons/Shared/RootViewController.h b/Icons/Shared/RootViewController.h new file mode 100644 index 0000000..1809ab3 --- /dev/null +++ b/Icons/Shared/RootViewController.h @@ -0,0 +1,55 @@ +/* + File: RootViewController.h + Abstract: The view controller displays what each icon does on iOS. The proper orientations supported by each device type are configured in the -shouldAutorotateToInterfaceOrientation: method. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + + +@interface RootViewController : UIViewController { + +} + +@end diff --git a/Icons/Shared/RootViewController.m b/Icons/Shared/RootViewController.m new file mode 100644 index 0000000..28cc035 --- /dev/null +++ b/Icons/Shared/RootViewController.m @@ -0,0 +1,98 @@ +/* + File: RootViewController.m + Abstract: The view controller displays what each icon does on iOS. The proper orientations supported by each device type are configured in the -shouldAutorotateToInterfaceOrientation: method. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" + +@implementation RootViewController + +/* + // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { + // Custom initialization + } + return self; +} +*/ + +/* +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; +} +*/ + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Following the HIG for supported orientations per device. + // Do not support UIInterfaceOrientationPortraitUpsideDown if the device is not an iPad. + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { + return NO; + } + + return YES; +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/Icons/en.lproj/MainWindow.xib b/Icons/en.lproj/MainWindow.xib new file mode 100644 index 0000000..ca58493 --- /dev/null +++ b/Icons/en.lproj/MainWindow.xib @@ -0,0 +1,449 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + IBCocoaTouchFramework + YES + + + RootViewController + + + 1 + + IBCocoaTouchFramework + NO + + + + + YES + + + viewController + + + + 17 + + + + delegate + + + + 20 + + + + window + + + + 21 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + -2 + + + + + 12 + + + + + 16 + + + App Delegate + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 12.CustomClassName + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 16.CustomClassName + 16.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + + + YES + UIApplication + UIResponder + RootViewController + {{329, 354}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{347, 74}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + YES + + + YES + + + + + YES + + + YES + + + + 21 + + + + YES + + AppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + RootViewController + UIWindow + + + + YES + + YES + viewController + window + + + YES + + viewController + RootViewController + + + window + UIWindow + + + + + IBProjectSource + iPhone/AppDelegate.h + + + + AppDelegate + NSObject + + IBUserSource + + + + + RootViewController + UIViewController + + IBProjectSource + Shared/RootViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../Icons.xcodeproj + 3 + 123 + + diff --git a/Icons/en.lproj/RootViewController.xib b/Icons/en.lproj/RootViewController.xib new file mode 100644 index 0000000..2a3a41e --- /dev/null +++ b/Icons/en.lproj/RootViewController.xib @@ -0,0 +1,385 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 274 + {320, 460} + + + 1 + MSAxIDEAA + + YES + YES + IBCocoaTouchFramework + NO + SWNvbi5wbmcgLSBIb21lc2NyZWVuIGljb24gb24gaVBob25lL2lQb2QgdG91Y2guCgpJY29uLTcyLnBu +ZyAtIEhvbWVzY3JlZW4gaWNvbiBvbiBpUGFkLgoKSWNvbkAyeC5wbmcgLSBIb21lc2NyZWVuIGljb24g +b24gaVBob25lIDQuCgpJY29uLVNtYWxsLnBuZyAtIEljb24gaW4gU3BvdGxpZ2h0IGFuZCBTZXR0aW5n +cyBhcHAgb24gaVBob25lL2lQb2QgdG91Y2ggYW5kIGljb24gaW4gU2V0dGluZ3MgYXBwIG9uIGlQYWQu +CgpJY29uLVNtYWxsLTUwLnBuZyAtIEljb24gaW4gU3BvdGxpZ2h0IG9uIGlQYWQuCgpJY29uLVNtYWxs +QDJ4LnBuZyAtIEljb24gaW4gU3BvdGxpZ2h0IGFuZCBTZXR0aW5ncyBhcHAgb24gaVBob25lIDQuCgpp +VHVuZXNBcnR3b3JrIC0gSWNvbiBpbiBpVHVuZXMgZm9yIEFkIEhvYyBkaXN0cmlidXRpb24gYnVpbGRz +Lg + + 2 + IBCocoaTouchFramework + + + + {320, 460} + + + 3 + MQA + + 2 + + + NO + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 3 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + 4.IBViewBoundsToFrameTransform + + + YES + RootViewController + UIResponder + {{637, 354}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAAAAAAAAw/kAAA + + + + + YES + + + YES + + + + + YES + + + YES + + + + 4 + + + + YES + + RootViewController + UIViewController + + IBProjectSource + RootViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITextView.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Icons.xcodeproj + 3 + 123 + + diff --git a/Icons/main.m b/Icons/main.m new file mode 100644 index 0000000..fee404f --- /dev/null +++ b/Icons/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file for this sample. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/LaunchMe.zip b/LaunchMe.zip new file mode 100644 index 0000000..c3cdfa1 Binary files /dev/null and b/LaunchMe.zip differ diff --git a/LaunchMe/Classes/LaunchMeAppDelegate.h b/LaunchMe/Classes/LaunchMeAppDelegate.h new file mode 100755 index 0000000..b01f2ec --- /dev/null +++ b/LaunchMe/Classes/LaunchMeAppDelegate.h @@ -0,0 +1,61 @@ +/* + File: LaunchMeAppDelegate.h + Abstract: + Version: 1.6 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface LaunchMeAppDelegate : NSObject { + IBOutlet UIWindow *window; + UIAlertView *usageAlertView; + BOOL showUsageAlert; +} + +@property (nonatomic, retain) UIWindow *window; +@property (nonatomic, retain) UIAlertView *usageAlertView; +@property BOOL showUsageAlert; + +@end + diff --git a/LaunchMe/Classes/LaunchMeAppDelegate.m b/LaunchMe/Classes/LaunchMeAppDelegate.m new file mode 100755 index 0000000..48520ed --- /dev/null +++ b/LaunchMe/Classes/LaunchMeAppDelegate.m @@ -0,0 +1,138 @@ +/* + File: LaunchMeAppDelegate.m + Abstract: + Version: 1.6 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "LaunchMeAppDelegate.h" + +@implementation LaunchMeAppDelegate + +@synthesize window; +@synthesize usageAlertView; +@synthesize showUsageAlert; + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + // Override point for customization after app launch + + // Schedule -showUsageAlertDialog on the next cycle of the event loop to give the + // application:handleOpenURL: delegate method an opportunity to handle an incoming URL. + // If that delegate method is called, it sets the showUsageAlert to NO, which prevents + // the usage dialog from being shown. + showUsageAlert = YES; + [self performSelector:@selector(showUsageAlertDialog) withObject:nil afterDelay:0.0]; +} + +- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url +{ + showUsageAlert = NO; + + // You should be extremely careful when handling URL requests. + // You must take steps to validate the URL before handling it. + + if (!url) { + // The URL is nil. There's nothing more to do. + return NO; + } + + NSString *URLString = [url absoluteString]; + + NSString *message = [NSString stringWithFormat:@"The application received a request to open this URL: %@. Be careful when servicing handleOpenURL requests!", URLString]; + + UIAlertView *openURLAlert = [[UIAlertView alloc] initWithTitle:@"handleOpenURL:" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [openURLAlert show]; + [openURLAlert release]; + + if (!URLString) { + // The URL's absoluteString is nil. There's nothing more to do. + return NO; + } + + // Your application is defining the new URL type, so you should know the maximum character + // count of the URL. Anything longer than what you expect is likely to be dangerous. + NSInteger maximumExpectedLength = 50; + + if ([URLString length] > maximumExpectedLength) { + // The URL is longer than we expect. Stop servicing it. + return NO; + } + + return YES; +} + +- (void)showUsageAlertDialog +{ + if (showUsageAlert) { + NSString *message = @"To demonstrate how this application handles a URL request for the new URL type that it registers, enter a URL in Safari that begins the with scheme of the URL type (launchme://) and press the Go button."; + self.usageAlertView = [[UIAlertView alloc] initWithTitle:@"Usage" message:message delegate:self cancelButtonTitle:@"Launch Safari" otherButtonTitles:nil]; + [self.usageAlertView show]; + } +} + +- (void)dismissUsageAlert +{ + [self.usageAlertView dismissWithClickedButtonIndex:-1 animated:YES]; +} + +- (void)modalViewCancel:(UIAlertView *)alertView +{ + [alertView release]; +} + +- (void)modalView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + if (buttonIndex != -1) { + // Open Safari only if the user clicked the 'Launch Safari' button, but not if this + // delegate method is called by UIKit to cancel it. In that case, buttonIndex is -1. + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.apple.com"]]; + } + [alertView release]; +} + +- (void)dealloc { + [window release]; + [super dealloc]; +} + +@end diff --git a/LaunchMe/Info.plist b/LaunchMe/Info.plist new file mode 100755 index 0000000..f43c237 --- /dev/null +++ b/LaunchMe/Info.plist @@ -0,0 +1,48 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + LSRequiresIPhoneOS + true + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.6 + NSMainNibFile + MainWindow + CFBundleURLTypes + + + CFBundleURLName + com.applesamplecode.LaunchMe + CFBundleURLSchemes + + launchme + + + + + diff --git a/LaunchMe/LaunchMe.xcodeproj/project.pbxproj b/LaunchMe/LaunchMe.xcodeproj/project.pbxproj new file mode 100755 index 0000000..de96f0b --- /dev/null +++ b/LaunchMe/LaunchMe.xcodeproj/project.pbxproj @@ -0,0 +1,296 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 18026CC011D2D120005B6728 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CB811D2D120005B6728 /* Default.png */; }; + 18026CC111D2D120005B6728 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CB911D2D120005B6728 /* Icon-72.png */; }; + 18026CC211D2D120005B6728 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CBA11D2D120005B6728 /* Icon-Small-50.png */; }; + 18026CC311D2D120005B6728 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CBB11D2D120005B6728 /* Icon-Small.png */; }; + 18026CC411D2D120005B6728 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CBC11D2D120005B6728 /* Icon-Small@2x.png */; }; + 18026CC511D2D120005B6728 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CBD11D2D120005B6728 /* Icon.png */; }; + 18026CC611D2D120005B6728 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18026CBE11D2D120005B6728 /* Icon@2x.png */; }; + 18026CC711D2D120005B6728 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18026CBF11D2D120005B6728 /* iTunesArtwork */; }; + 18026CCA11D2D125005B6728 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18026CC811D2D125005B6728 /* MainWindow.xib */; }; + 1D3623260D0F684500981E51 /* LaunchMeAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LaunchMeAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 8416460C0DB9150A004010DE /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 8416460B0DB9150A004010DE /* ReadMe.txt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 18026CB811D2D120005B6728 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 18026CB911D2D120005B6728 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18026CBA11D2D120005B6728 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18026CBB11D2D120005B6728 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18026CBC11D2D120005B6728 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18026CBD11D2D120005B6728 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18026CBE11D2D120005B6728 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18026CBF11D2D120005B6728 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 18026CC911D2D125005B6728 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* LaunchMeAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchMeAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* LaunchMeAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LaunchMeAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* LaunchMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LaunchMe.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* LaunchMe_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchMe_Prefix.pch; sourceTree = ""; }; + 8416460B0DB9150A004010DE /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* LaunchMeAppDelegate.h */, + 1D3623250D0F684500981E51 /* LaunchMeAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* LaunchMe.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 8416460B0DB9150A004010DE /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* LaunchMe_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18026CC811D2D125005B6728 /* MainWindow.xib */, + 18026CB811D2D120005B6728 /* Default.png */, + 18026CB911D2D120005B6728 /* Icon-72.png */, + 18026CBA11D2D120005B6728 /* Icon-Small-50.png */, + 18026CBB11D2D120005B6728 /* Icon-Small.png */, + 18026CBC11D2D120005B6728 /* Icon-Small@2x.png */, + 18026CBD11D2D120005B6728 /* Icon.png */, + 18026CBE11D2D120005B6728 /* Icon@2x.png */, + 18026CBF11D2D120005B6728 /* iTunesArtwork */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* LaunchMe */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "LaunchMe" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LaunchMe; + productName = LaunchMe; + productReference = 1D6058910D05DD3D006BFB54 /* LaunchMe.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "LaunchMe" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* LaunchMe */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8416460C0DB9150A004010DE /* ReadMe.txt in Resources */, + 18026CC011D2D120005B6728 /* Default.png in Resources */, + 18026CC111D2D120005B6728 /* Icon-72.png in Resources */, + 18026CC211D2D120005B6728 /* Icon-Small-50.png in Resources */, + 18026CC311D2D120005B6728 /* Icon-Small.png in Resources */, + 18026CC411D2D120005B6728 /* Icon-Small@2x.png in Resources */, + 18026CC511D2D120005B6728 /* Icon.png in Resources */, + 18026CC611D2D120005B6728 /* Icon@2x.png in Resources */, + 18026CC711D2D120005B6728 /* iTunesArtwork in Resources */, + 18026CCA11D2D125005B6728 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* LaunchMeAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 18026CC811D2D125005B6728 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 18026CC911D2D125005B6728 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = LaunchMe_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = LaunchMe; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = LaunchMe_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = LaunchMe; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "LaunchMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "LaunchMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/LaunchMe/LaunchMe_Prefix.pch b/LaunchMe/LaunchMe_Prefix.pch new file mode 100755 index 0000000..9de8264 --- /dev/null +++ b/LaunchMe/LaunchMe_Prefix.pch @@ -0,0 +1,55 @@ +/* + File: LaunchMe_Prefix.pch + Abstract: + Version: 1.6 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +// +// Prefix header for all source files of the 'LaunchMe' target in the 'LaunchMe' project +// + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/LaunchMe/ReadMe.txt b/LaunchMe/ReadMe.txt new file mode 100644 index 0000000..ebaeb32 --- /dev/null +++ b/LaunchMe/ReadMe.txt @@ -0,0 +1,48 @@ +### LaunchMe ### + +================================================================================ +DESCRIPTION: + +The LaunchMe sample application demonstrates how to register a new URL type. Registering a new URL type allows other applications to interact with yours. This sample also shows how to handle an incoming openURL: message from another application. When servicing an openURL: message from another application, you must be very careful to validate the URL in the message before allowing your application to proceed. After you build and run LaunchMe, it displays a dialog with instructions on how to use the application. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +LaunchMeAppDelegate.h +LaunchMeAppDelegate.m +The controller for the application. Handles incoming URL requests. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.6 +- Upgraded project to build with the iOS 4.0 SDK. + +Version 1.5 +- Updated for and tested with iPhone OS 2.0. First public release. + +Version 1.4 +- Updated for Beta 6. +- Added LSRequiresIPhoneOS key to Info.plist. + +Version 1.3 +- Updated for Beta 4. + +Version 1.2 +- Added code signing. + +Version 1.1 +- Updated for Beta 3. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/LaunchMe/en.lproj/MainWindow.xib b/LaunchMe/en.lproj/MainWindow.xib new file mode 100644 index 0000000..24ac0de --- /dev/null +++ b/LaunchMe/en.lproj/MainWindow.xib @@ -0,0 +1,162 @@ + + + + 1050 + 9C7010 + 651 + 949.26 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + + + YES + + YES + -1.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + + YES + + YES + + + YES + + + {{362, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + LaunchMeAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 7 + + + + YES + + LaunchMeAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/LaunchMeAppDelegate.h + + + + + 0 + LaunchMe.xcodeproj + 3 + + diff --git a/LaunchMe/images/Default.png b/LaunchMe/images/Default.png new file mode 100644 index 0000000..5d44c79 Binary files /dev/null and b/LaunchMe/images/Default.png differ diff --git a/LaunchMe/images/Icon-72.png b/LaunchMe/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/LaunchMe/images/Icon-72.png differ diff --git a/LaunchMe/images/Icon-Small-50.png b/LaunchMe/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/LaunchMe/images/Icon-Small-50.png differ diff --git a/LaunchMe/images/Icon-Small.png b/LaunchMe/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/LaunchMe/images/Icon-Small.png differ diff --git a/LaunchMe/images/Icon-Small@2x.png b/LaunchMe/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/LaunchMe/images/Icon-Small@2x.png differ diff --git a/LaunchMe/images/Icon.png b/LaunchMe/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/LaunchMe/images/Icon.png differ diff --git a/LaunchMe/images/Icon@2x.png b/LaunchMe/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/LaunchMe/images/Icon@2x.png differ diff --git a/LaunchMe/images/iTunesArtwork b/LaunchMe/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/LaunchMe/images/iTunesArtwork differ diff --git a/LaunchMe/main.m b/LaunchMe/main.m new file mode 100755 index 0000000..be0b217 --- /dev/null +++ b/LaunchMe/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: + Version: 1.6 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/ListAdder.zip b/ListAdder.zip new file mode 100644 index 0000000..81e31ef Binary files /dev/null and b/ListAdder.zip differ diff --git a/ListAdder/AdderOperation.h b/ListAdder/AdderOperation.h new file mode 100644 index 0000000..e10ce11 --- /dev/null +++ b/ListAdder/AdderOperation.h @@ -0,0 +1,112 @@ +/* + File: AdderOperation.h + + Contains: Adds an array of numbers (very slowly) and returns the result. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +/* + AdderOperation is an example of using NSOperation to do asynchronous processing + in a sane fashion. It follows the thread confinement model. That is, you + initialise the operation with an array of numbers to operate on, and it adds up + those numbers and vends the result through read-only properties. + + The data used by the operation are made thread safe in a number of different ways: + + o Some properties (for example, numbers) are set up at initialisation time and + can't be changed. These are immutable, thus can be safely shared between threads. + + o Some properties must be set before the operation is queued and should be immutable + after that. Again, these are thread safe because there's no possibility of two + threads trying to mutate the same value at the same time. interNumberDelay + is an example of this. + + o Some properties are set by the operation but shouldn't be read by the client + until the operation is finished. total and formattedTotal are examples of this. + + o Some properties, like formatter, are private to the operation and are only ever + accessed by the thread running the operation. + + o Global data, like sSequenceNumber, is protected by a lock. + + It's obvious that adding a few numbers is going to happen very quickly, so we + artifically slow things down by sleeping for an extended period of time between + additions. This delay is controlled by the interNumberDelay, which defaults to + one second. +*/ + +@interface AdderOperation : NSOperation +{ + NSArray * _numbers; + NSUInteger _sequenceNumber; + NSTimeInterval _interNumberDelay; + NSInteger _total; + NSNumberFormatter * _formatter; + NSString * _formattedTotal; +} + +- (id)initWithNumbers:(NSArray *)numbers; + +// set up by the init method that can't be changed + +@property (copy, readonly ) NSArray * numbers; // of NSNumber +@property (assign, readonly ) NSUInteger sequenceNumber; + +// must be configured before the operation is started + +@property (assign, readwrite) NSTimeInterval interNumberDelay; // defaults to 1.0 + +// only meaningful after the operation is finished + +@property (assign, readonly ) NSInteger total; +@property (copy, readonly ) NSString * formattedTotal; + +@end diff --git a/ListAdder/AdderOperation.m b/ListAdder/AdderOperation.m new file mode 100644 index 0000000..8edaedf --- /dev/null +++ b/ListAdder/AdderOperation.m @@ -0,0 +1,261 @@ +/* + File: AdderOperation.m + + Contains: Adds an array of numbers (very slowly) and returns the result. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "AdderOperation.h" + +@interface AdderOperation () + +// only accessed by the operation thread + +@property (retain, readwrite) NSNumberFormatter * formatter; + +// read/write versions of public properties + +@property (assign, readwrite) NSInteger total; +@property (copy, readwrite) NSString * formattedTotal; + +@end + +@implementation AdderOperation + +- (id)initWithNumbers:(NSArray *)numbers +{ + // can be called on any thread + + // An NSOperation's init method does not have to be thread safe; it's relatively + // easy to enforce the requirement that the init method is only called by the + // main thread, or just one single thread. However, in this case it's easy to + // make the init method thread safe, so we do that. + + assert(numbers != nil); + self = [super init]; + if (self != nil) { + + // Initialise our numbers property by taking a copy of the incoming + // numbers array. Note that we use a copy here. If you just retain + // the incoming value then the program will crash because our client + // passes us an NSMutableArray (which is type compatible with NSArray) + // and can then mutate it behind our back. + + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"retainNotCopy"] ) { + self->_numbers = [numbers retain]; + } else { + self->_numbers = [numbers copy]; + } + assert(self->_numbers != nil); + + // Set up our sequenceNumber property. Note that, because we can be called + // from any thread, we have to use a lock to protect sSequenceNumber (that + // is, to guarantee that each operation gets a unique sequence number). + // In this case locking isn't a problem because we do very little within + // that lock; there's no possibility of deadlock, and the chances of lock + // contention are slight. + + @synchronized ([AdderOperation class]) { + static NSUInteger sSequenceNumber; + self->_sequenceNumber = sSequenceNumber; + sSequenceNumber += 1; + } + + self->_interNumberDelay = 1.0; + } + return self; +} + +- (id)initWithNumbers2:(NSArray *)numbers +{ + // IMPORTANT: This is method is not actually used. It is here because it's a code + // snippet in the technote, and i wanted to make sure it compiles. + + assert(NO); + + assert(numbers != nil); + self = [super init]; + if (self != nil) { + self->_numbers = [numbers copy]; + assert(self->_numbers != nil); + } + return self; +} + +- (void)dealloc +{ + // can be called on any thread + + // Note that we can safely release our properties here, even properties like + // formatter, which are meant to only be accessed by the operation's thread. + // That's because -retain and -release are always fully thread safe, even in + // situations where other methods on an object are not. + + [self->_numbers release]; + [self->_formatter release]; + [self->_formattedTotal release]; + [super dealloc]; +} + +@synthesize numbers = _numbers; +@synthesize sequenceNumber = _sequenceNumber; +@synthesize interNumberDelay = _interNumberDelay; +@synthesize total = _total; +@synthesize formatter = _formatter; +@synthesize formattedTotal = _formattedTotal; + +- (void)main +{ + NSUInteger numberCount; + NSUInteger numberIndex; + NSTimeInterval localInterNumberDelay; + NSInteger localTotal; + + // This method is called by a thread that's set up for us by the NSOperationQueue. + + assert( ! [NSThread isMainThread] ); + + // We latch interNumberDelay at this point so that, if the client changes + // it after they've queued the operation (something they shouldn't be doing, + // but hey, we're cautious), we always see a consistent value. + + localInterNumberDelay = self.interNumberDelay; + + // Set up the formatter. This is a private property that's only accessed by + // the operation thread, so we don't have to worry about synchronising access to it. + + self.formatter = [[[NSNumberFormatter alloc] init] autorelease]; + assert(self.formatter != nil); + + [self.formatter setNumberStyle:NSNumberFormatterDecimalStyle]; + [self.formatter setUsesGroupingSeparator:YES]; + + // Do the heavy lifting (-: + + localTotal = 0; + numberCount = [self.numbers count]; + for (numberIndex = 0; numberIndex < numberCount; numberIndex++) { + NSNumber * numberObj; + + // Check for cancellation. + + if ([self isCancelled]) { + break; + } + + // Sleep for the inter-number delay. This makes it easiest to + // test cancellation and so on. + + [NSThread sleepForTimeInterval:localInterNumberDelay]; + + // Do the maths (but they said there'd be no maths!). + + numberObj = [self.numbers objectAtIndex:numberIndex]; + assert([numberObj isKindOfClass:[NSNumber class]]); + + localTotal += [numberObj integerValue]; + } + + // Set our output properties base on the value we calculated. Our client + // shouldn't look at these until -isFinished goes to YES (which happens when + // we return from this method). + + self.total = localTotal; + self.formattedTotal = [self.formatter stringFromNumber:[NSNumber numberWithInteger:localTotal]]; +} + +- (void)main2 +{ + NSUInteger numberCount; + NSUInteger numberIndex; + NSInteger total; + + // IMPORTANT: This is method is not actually used. It is here because it's a code + // snippet in the technote, and i wanted to make sure it compiles. + + assert(NO); + + // This method is called by a thread that's set up for us by the NSOperationQueue. + + assert( ! [NSThread isMainThread] ); + + // Do the heavy lifting (-: + + total = 0; + numberCount = [self.numbers count]; + for (numberIndex = 0; numberIndex < numberCount; numberIndex++) { + NSNumber * numberObj; + + // Check for cancellation. + + if ([self isCancelled]) { + break; + } + + // Sleep for a second. This makes it easiest to test cancellation + // and so on. + + [NSThread sleepForTimeInterval:1.0]; + + // Do the maths (but they said there'd be no maths!). + + numberObj = [self.numbers objectAtIndex:numberIndex]; + assert([numberObj isKindOfClass:[NSNumber class]]); + + total += [numberObj integerValue]; + } + + // Set our output properties base on the value we calculated. Our client + // shouldn't look at these until -isFinished goes to YES (which happens when + // we return from this method). + + self.formattedTotal = [self.formatter stringFromNumber:[NSNumber numberWithInteger:total]]; +} + +@end diff --git a/ListAdder/AppDelegate.h b/ListAdder/AppDelegate.h new file mode 100644 index 0000000..b38f6ad --- /dev/null +++ b/ListAdder/AppDelegate.h @@ -0,0 +1,65 @@ +/* + File: AppDelegate.h + + Contains: Main app controller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@interface AppDelegate : NSObject +{ + UIWindow * _window; + UINavigationController * _navController; +} + +@property (nonatomic, retain) IBOutlet UIWindow * window; +@property (nonatomic, retain) IBOutlet UINavigationController * navController; + +@end diff --git a/ListAdder/AppDelegate.m b/ListAdder/AppDelegate.m new file mode 100644 index 0000000..517ded6 --- /dev/null +++ b/ListAdder/AppDelegate.m @@ -0,0 +1,80 @@ +/* + File: AppDelegate.m + + Contains: Main app controller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "AppDelegate.h" + +#import "ListAdderViewController.h" + +@implementation AppDelegate + +@synthesize window = _window; +@synthesize navController = _navController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + #pragma unused(application) + ListAdderViewController * vc; + + assert(self.window != nil); + assert(self.navController != nil); + + vc = [[[ListAdderViewController alloc] init] autorelease]; + assert(vc != nil); + + [self.navController pushViewController:vc animated:NO]; + + [self.window addSubview:self.navController.view]; + [self.window makeKeyAndVisible]; +} + +@end diff --git a/ListAdder/Info.plist b/ListAdder/Info.plist new file mode 100644 index 0000000..662b9b4 --- /dev/null +++ b/ListAdder/Info.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small@2x.png + Icon-Small-50.png + + CFBundleIdentifier + com.apple.dts.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainWindow + + \ No newline at end of file diff --git a/ListAdder/ListAdder.xcodeproj/project.pbxproj b/ListAdder/ListAdder.xcodeproj/project.pbxproj new file mode 100755 index 0000000..26c8cb4 --- /dev/null +++ b/ListAdder/ListAdder.xcodeproj/project.pbxproj @@ -0,0 +1,313 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + E418B7DF10FD13A10095D411 /* ListAdderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E418B7DE10FD13A10095D411 /* ListAdderViewController.m */; }; + E4233102121008DA00081252 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = E42330FB121008DA00081252 /* Icon-72.png */; }; + E4233103121008DA00081252 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = E42330FC121008DA00081252 /* Icon-Small-50.png */; }; + E4233104121008DA00081252 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = E42330FD121008DA00081252 /* Icon-Small.png */; }; + E4233105121008DA00081252 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E42330FE121008DA00081252 /* Icon-Small@2x.png */; }; + E4233106121008DA00081252 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = E42330FF121008DA00081252 /* Icon.png */; }; + E4233107121008DA00081252 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E4233100121008DA00081252 /* Icon@2x.png */; }; + E4233108121008DA00081252 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = E4233101121008DA00081252 /* iTunesArtwork */; }; + E45D9E660DAFDA3E00649782 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E45D9E650DAFDA3E00649782 /* AppDelegate.m */; }; + E47180F1120815BC00FB1DF9 /* NumberPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = E47180F0120815BC00FB1DF9 /* NumberPickerController.m */; }; + E4718201120821A100FB1DF9 /* AdderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E4718200120821A100FB1DF9 /* AdderOperation.m */; }; + E471842A120874C600FB1DF9 /* OptionsController.m in Sources */ = {isa = PBXBuildFile; fileRef = E4718429120874C600FB1DF9 /* OptionsController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* ListAdder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ListAdder.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E4012C76120AB2960059195F /* Read Me About ListAdder.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Read Me About ListAdder.txt"; sourceTree = ""; wrapsLines = 1; }; + E418B7DD10FD13A10095D411 /* ListAdderViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListAdderViewController.h; sourceTree = ""; }; + E418B7DE10FD13A10095D411 /* ListAdderViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ListAdderViewController.m; sourceTree = ""; }; + E42330FB121008DA00081252 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + E42330FC121008DA00081252 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + E42330FD121008DA00081252 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + E42330FE121008DA00081252 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + E42330FF121008DA00081252 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + E4233100121008DA00081252 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + E4233101121008DA00081252 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + E45D9E640DAFDA3E00649782 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + E45D9E650DAFDA3E00649782 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + E47180EF120815BC00FB1DF9 /* NumberPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumberPickerController.h; sourceTree = ""; }; + E47180F0120815BC00FB1DF9 /* NumberPickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NumberPickerController.m; sourceTree = ""; }; + E47181FF120821A100FB1DF9 /* AdderOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdderOperation.h; sourceTree = ""; }; + E4718200120821A100FB1DF9 /* AdderOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AdderOperation.m; sourceTree = ""; }; + E4718428120874C600FB1DF9 /* OptionsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionsController.h; sourceTree = ""; }; + E4718429120874C600FB1DF9 /* OptionsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionsController.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ListAdder.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + E4012C76120AB2960059195F /* Read Me About ListAdder.txt */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 8D1107310486CEB800E47090 /* Info.plist */, + E42330FA121008DA00081252 /* images */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + E45D9E640DAFDA3E00649782 /* AppDelegate.h */, + E45D9E650DAFDA3E00649782 /* AppDelegate.m */, + E418B7DD10FD13A10095D411 /* ListAdderViewController.h */, + E418B7DE10FD13A10095D411 /* ListAdderViewController.m */, + E47180EF120815BC00FB1DF9 /* NumberPickerController.h */, + E47180F0120815BC00FB1DF9 /* NumberPickerController.m */, + E4718428120874C600FB1DF9 /* OptionsController.h */, + E4718429120874C600FB1DF9 /* OptionsController.m */, + E47181FF120821A100FB1DF9 /* AdderOperation.h */, + E4718200120821A100FB1DF9 /* AdderOperation.m */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + E42330FA121008DA00081252 /* images */ = { + isa = PBXGroup; + children = ( + E42330FB121008DA00081252 /* Icon-72.png */, + E42330FC121008DA00081252 /* Icon-Small-50.png */, + E42330FD121008DA00081252 /* Icon-Small.png */, + E42330FE121008DA00081252 /* Icon-Small@2x.png */, + E42330FF121008DA00081252 /* Icon.png */, + E4233100121008DA00081252 /* Icon@2x.png */, + E4233101121008DA00081252 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ListAdder */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ListAdder" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ListAdder; + productName = ListAdder; + productReference = 1D6058910D05DD3D006BFB54 /* ListAdder.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ListAdder" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ListAdder */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + E4233102121008DA00081252 /* Icon-72.png in Resources */, + E4233103121008DA00081252 /* Icon-Small-50.png in Resources */, + E4233104121008DA00081252 /* Icon-Small.png in Resources */, + E4233105121008DA00081252 /* Icon-Small@2x.png in Resources */, + E4233106121008DA00081252 /* Icon.png in Resources */, + E4233107121008DA00081252 /* Icon@2x.png in Resources */, + E4233108121008DA00081252 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + E45D9E660DAFDA3E00649782 /* AppDelegate.m in Sources */, + E418B7DF10FD13A10095D411 /* ListAdderViewController.m in Sources */, + E47180F1120815BC00FB1DF9 /* NumberPickerController.m in Sources */, + E4718201120821A100FB1DF9 /* AdderOperation.m in Sources */, + E471842A120874C600FB1DF9 /* OptionsController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = ListAdder; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = ListAdder; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_POSTPROCESSING = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + WARNING_CFLAGS = ( + "-Wall", + "-Wextra", + "-Wfloat-equal", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wold-style-definition", + ); + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + WARNING_CFLAGS = ( + "-Wall", + "-Wextra", + "-Wfloat-equal", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wold-style-definition", + ); + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ListAdder" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ListAdder" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/ListAdder/ListAdderViewController.h b/ListAdder/ListAdderViewController.h new file mode 100644 index 0000000..a0b01a0 --- /dev/null +++ b/ListAdder/ListAdderViewController.h @@ -0,0 +1,69 @@ +/* + File: ListAdderViewController.h + + Contains: Main view controller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@class AdderOperation; + +@interface ListAdderViewController : UITableViewController +{ + NSMutableArray * _numbers; + NSOperationQueue * _queue; + BOOL _recalculating; + AdderOperation * _inProgressAdder; + NSString * _formattedTotal; +} + +- (id)init; + +@end diff --git a/ListAdder/ListAdderViewController.m b/ListAdder/ListAdderViewController.m new file mode 100644 index 0000000..9760550 --- /dev/null +++ b/ListAdder/ListAdderViewController.m @@ -0,0 +1,847 @@ +/* + File: ListAdderViewController.m + + Contains: Main view controller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "ListAdderViewController.h" + +#import "NumberPickerController.h" +#import "OptionsController.h" + +#import "AdderOperation.h" + +@interface ListAdderViewController () + +// private properties + +@property (nonatomic, retain, readonly ) NSMutableArray * numbers; +@property (nonatomic, retain, readonly ) NSOperationQueue * queue; +@property (nonatomic, assign, readwrite) BOOL recalculating; +@property (nonatomic, retain, readwrite) AdderOperation * inProgressAdder; +@property (nonatomic, copy, readwrite) NSString * formattedTotal; + +// forward declarations + +- (void)presentNumberPickerModally; +- (void)recalculateTotal; +- (void)recalculateTotalUsingThread; +- (void)recalculateTotalUsingOperation; +- (void)adderOperationDone:(AdderOperation *)op; + +@end + +static char CharForCurrentThread(void) + // Returns 'M' if we're running on the main thread, or 'S' otherwies. +{ + return [NSThread isMainThread] ? 'M' : 'S'; +} + +@implementation ListAdderViewController + ++ (NSArray *)defaultNumbers + // Returns the default numbers that we initialise the view with. +{ + return [NSArray arrayWithObjects: + [NSNumber numberWithInt:7], + [NSNumber numberWithInt:5], + [NSNumber numberWithInt:8], + [NSNumber numberWithInt:9], + [NSNumber numberWithInt:7], + [NSNumber numberWithInt:6], + nil + ]; +} + +- (id)init +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self != nil) { + // Set up some private properties. + + self->_numbers = [[[self class] defaultNumbers] mutableCopy]; + assert(self->_numbers != nil); + + self->_queue = [[NSOperationQueue alloc] init]; + assert(self->_queue != nil); + + // Set up our navigation bar. + + self.title = @"ListAdder"; + self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Options" style:UIBarButtonItemStyleBordered target:self action:@selector(optionsAction:) ] autorelease]; + self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Minimum" style:UIBarButtonItemStyleBordered target:self action:@selector(defaultsMinimumAction:)] autorelease]; + self.navigationItem.leftBarButtonItem.possibleTitles = [NSSet setWithObjects:@"Defaults", @"Minimum", nil]; + } + return self; +} + +- (void)dealloc +{ + // This is the root view controller of our application, so it can never be + // deallocated. Supporting -dealloc in the presence of threading, even highly + // constrained threading as used by this example, is tricky. My recommended + // technique for doing this is the QWatchedOperationQueue class in the + // LinkedImageFetcher sample code. + // + // + // + // However, I didn't want to drag parts of that sample into this sample (especially + // given that -dealloc can never be called in this sample and thus I can't test it), + // nor did I want to demonstrate an ad hoc, and potentially buggy, version of + // -dealloc. So, for the moment, we just don't support -dealloc. + + assert(NO); + + // Despite the above, I've left in the following just as an example of how you + // manage self observation in a view controller. + + // If we got -dealloc'd without ever releasing our observer, do that now. + + if (self.isViewLoaded) { + [self removeObserver:self forKeyPath:@"recalculating"]; + } + + [super dealloc]; +} + +- (void)syncLeftBarButtonTitle +{ + if ([self.numbers count] <= 1) { + self.navigationItem.leftBarButtonItem.title = @"Defaults"; + } else { + self.navigationItem.leftBarButtonItem.title = @"Minimum"; + } +} + +#pragma mark * Properties + +@synthesize numbers = _numbers; +@synthesize formattedTotal = _formattedTotal; +@synthesize queue = _queue; +@synthesize recalculating = _recalculating; +@synthesize inProgressAdder = _inProgressAdder; + +#pragma mark * View controller stuff + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Configure our table view. + + self.tableView.editing = YES; + self.tableView.allowsSelectionDuringEditing = YES; + + // Observe recalculating to trigger reloads of the cell in the first + // section (kListAdderSectionIndexTotal). + + [self addObserver:self forKeyPath:@"recalculating" options:0 context:&self->_inProgressAdder]; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + [self removeObserver:self forKeyPath:@"recalculating"]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // When we come on screen, if we don't have a current value and we're not + // already calculating a value, kick off an operation to calculate the initial + // value of the total. + + if ( (self.formattedTotal == nil) && ! self.recalculating ) { + [self recalculateTotal]; + } +} + +#pragma mark * Table view callbacks + +enum { + kListAdderSectionIndexTotal = 0, + kListAdderSectionIndexAddNumber, + kListAdderSectionIndexNumbers, + kListAdderSectionIndexCount +}; + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv +{ + #pragma unused(tv) + assert(tv == self.tableView); + return kListAdderSectionIndexCount; +} + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + assert(tv == self.tableView); + assert(section < kListAdderSectionIndexCount); + + return (section == kListAdderSectionIndexNumbers) ? [self.numbers count] : 1; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + UITableViewCell * cell; + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section < kListAdderSectionIndexCount); + assert(indexPath.row < ((indexPath.section == kListAdderSectionIndexNumbers) ? [self.numbers count] : 1)); + + // Get a cell to work with. + + cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"] autorelease]; + assert(cell != nil); + } + + // Reset it to default values. + + cell.editingAccessoryView = nil; + cell.detailTextLabel.text = nil; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + + // Set it up based on the section and row. + + switch (indexPath.section) { + default: + assert(NO); + // fall through + case kListAdderSectionIndexTotal: { + cell.textLabel.text = @"Total"; + if (self.recalculating) { + UIActivityIndicatorView * activityView; + + activityView = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; + assert(activityView != nil); + + [activityView startAnimating]; + + cell.editingAccessoryView = activityView; + } else { + cell.detailTextLabel.text = self.formattedTotal; + } + } break; + case kListAdderSectionIndexAddNumber: { + cell.textLabel.text = @"Add Number…"; + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + } break; + case kListAdderSectionIndexNumbers: { + cell.textLabel.text = [[self.numbers objectAtIndex:indexPath.row] description]; + } break; + } + + return cell; +} + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tv editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCellEditingStyle result; + + #pragma unused(tv) + assert(tv == self.tableView); + assert(indexPath.section < kListAdderSectionIndexCount); + assert(indexPath.row < ((indexPath.section == kListAdderSectionIndexNumbers) ? [self.numbers count] : 1)); + + switch (indexPath.section) { + default: + assert(NO); + // fall through + case kListAdderSectionIndexTotal: { + result = UITableViewCellEditingStyleNone; + } break; + case kListAdderSectionIndexAddNumber: { + result = UITableViewCellEditingStyleInsert; + } break; + case kListAdderSectionIndexNumbers: { + // We don't allow the user to delete the last cell. + if ([self.numbers count] == 1) { + result = UITableViewCellEditingStyleNone; + } else { + result = UITableViewCellEditingStyleDelete; + } + } break; + } + return result; +} + +// I would like to suppress the delete confirmation button but I don't think there's a +// supported way to do this. + +- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + assert(tv == self.tableView); + assert(indexPath.section < kListAdderSectionIndexCount); + assert(indexPath.row < ((indexPath.section == kListAdderSectionIndexNumbers) ? [self.numbers count] : 1)); + + switch (indexPath.section) { + default: + assert(NO); + // fall through + case kListAdderSectionIndexTotal: { + assert(NO); + } break; + case kListAdderSectionIndexAddNumber: { + #pragma unused(editingStyle) + assert(editingStyle == UITableViewCellEditingStyleInsert); + + // The user has tapped on the plus button. Bring up the number picker. + + [self presentNumberPickerModally]; + } break; + case kListAdderSectionIndexNumbers: { + #pragma unused(editingStyle) + assert(editingStyle == UITableViewCellEditingStyleDelete); + assert([self.numbers count] != 0); // because otherwise we'd have no delete button + + // Remove the row from our model and the table view. + + [self.numbers removeObjectAtIndex:indexPath.row]; + [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + + // If we've transitioned from 2 rows to 1 row, remove the delete button for the + // remaining row; we don't want folks deleting that now, do we? Also, set the + // title of the left bar button to "Defaults" to reflect its updated function. + + if ([self.numbers count] == 1) { + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:kListAdderSectionIndexNumbers]] withRowAnimation:UITableViewRowAnimationNone]; + + [self syncLeftBarButtonTitle]; + } + + // We've modified numbers, so kick off a recalculation. + + [self recalculateTotal]; + } break; + } +} + +- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section < kListAdderSectionIndexCount); + assert(indexPath.row < ((indexPath.section == kListAdderSectionIndexNumbers) ? [self.numbers count] : 1)); + + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + switch (indexPath.section) { + default: + assert(NO); + // fall through + case kListAdderSectionIndexTotal: { + // do nothing + } break; + case kListAdderSectionIndexAddNumber: { + + // The user has tapped on the body of the cell associated with plus button. + // Bring up the number picker. + + [self presentNumberPickerModally]; + } break; + case kListAdderSectionIndexNumbers: { + // do nothing + } break; + } +} + +#pragma mark * Number picker management + +- (void)presentNumberPickerModally + // Displays the number picker so that the user can add a new number to the + // list of numbers to add up. +{ + NumberPickerController * vc; + + vc = [[[NumberPickerController alloc] init] autorelease]; + assert(vc != nil); + + vc.delegate = self; + + [vc presentModallyOn:self]; +} + +- (void)numberPicker:(NumberPickerController *)controller didChooseNumber:(NSNumber *)number + // Called by the number picker when the user chooses a number or taps cancel. +{ + #pragma unused(controller) + assert(controller != nil); + + // If it wasn't cancelled... + + if (number != nil) { + + // Add the number to our model and the table view. + + [self.numbers addObject:number]; + [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:[self.numbers count] - 1 inSection:kListAdderSectionIndexNumbers]] withRowAnimation:UITableViewRowAnimationFade]; + + // If we've transitioned from 1 row to 2 rows, add the delete button back for + // the first row. Also change the left bar button item back to "Minimum". + + if ([self.numbers count] == 2) { + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:kListAdderSectionIndexNumbers]] withRowAnimation:UITableViewRowAnimationNone]; + + [self syncLeftBarButtonTitle]; + } + + // We've modified numbers, so kick off a recalculation. + + [self recalculateTotal]; + } + [self dismissModalViewControllerAnimated:YES]; +} + +#pragma mark * Options management + +- (void)presentOptionsModally + // Displays the options view so that the user can add a new number to the + // list of numbers to add up. +{ + OptionsController * vc; + + vc = [[[OptionsController alloc] init] autorelease]; + assert(vc != nil); + + vc.delegate = self; + + [vc presentModallyOn:self]; +} + +- (void)didSaveOptions:(OptionsController *)controller + // Called when the user taps Save in the options view. The options + // view has already saved the options, so we have nothing to do other + // than to tear down the view. +{ + #pragma unused(controller) + assert(controller != nil); + [self dismissModalViewControllerAnimated:YES]; +} + +- (void)didCancelOptions:(OptionsController *)controller + // Called when the user taps Cancel in the options view. +{ + #pragma unused(controller) + assert(controller != nil); + [self dismissModalViewControllerAnimated:YES]; +} + +#pragma mark * Async recalculation + +- (void)recalculateTotal + // Starts a recalculation using either the thread- or NSOperation-based code. +{ + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"useThreadsDirectly"] ) { + [self recalculateTotalUsingThread]; + } else { + [self recalculateTotalUsingOperation]; + } +} + +#pragma mark - NSThread + +- (void)recalculateTotalUsingThread + // Starts a recalculation using a thread. +{ + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"retainNotCopy"] ) { + self.recalculating = YES; + + [self performSelectorInBackground:@selector(threadRecalculateNumbers:) withObject:self.numbers]; + } else { + NSArray * immutableNumbers; + + self.recalculating = YES; + + immutableNumbers = [[self.numbers copy] autorelease]; + assert(immutableNumbers != nil); + [self performSelectorInBackground:@selector(threadRecalculateNumbers:) withObject:immutableNumbers]; + } +} + +- (void)threadRecalculateNumbers:(NSArray *)immutableNumbers + // Does the actual recalculation when we're in threaded mode. Always + // called on a secondary thread. +{ + NSAutoreleasePool * pool; + NSInteger total; + NSUInteger numberCount; + NSUInteger numberIndex; + NSString * totalStr; + + assert( ! [NSThread isMainThread] ); + + pool = [[NSAutoreleasePool alloc] init]; + assert(pool != nil); + + total = 0; + numberCount = [immutableNumbers count]; + for (numberIndex = 0; numberIndex < numberCount; numberIndex++) { + NSNumber * numberObj; + + // Sleep for a while. This makes it easiest to test various problematic cases. + + [NSThread sleepForTimeInterval:1.0]; + + // Do the maths. + + numberObj = [immutableNumbers objectAtIndex:numberIndex]; + assert([numberObj isKindOfClass:[NSNumber class]]); + + total += [numberObj integerValue]; + } + + totalStr = [NSString stringWithFormat:@"%ld", (long) total]; + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"applyResultsFromThread"] ) { + self.formattedTotal = totalStr; + self.recalculating = NO; + } else { + [self performSelectorOnMainThread:@selector(threadRecalculateDone:) withObject:totalStr waitUntilDone:NO]; + } + + [pool drain]; +} + +- (void)threadRecalculateDone:(NSString *)result + // In threaded mode, called on the main thread to apply the results to the UI. +{ + assert([NSThread isMainThread]); + + // The user interface is adjusted by a KVO observer on recalculating. + + self.formattedTotal = result; + self.recalculating = NO; +} + +- (void)threadRecalculateNumbers +{ + NSAutoreleasePool * pool; + NSInteger total; + NSUInteger numberCount; + NSUInteger numberIndex; + NSString * totalStr; + + // IMPORTANT: This method is not actually used. It is here because it's a code + // snippet in the technote, and i wanted to make sure it compiles. + + assert(NO); + + pool = [[NSAutoreleasePool alloc] init]; + assert(pool != nil); + + total = 0; + numberCount = [self.numbers count]; + for (numberIndex = 0; numberIndex < numberCount; numberIndex++) { + NSNumber * numberObj; + + // Sleep for a while. This makes it easiest to test various problematic cases. + + [NSThread sleepForTimeInterval:1.0]; + + // Do the maths. + + numberObj = [self.numbers objectAtIndex:numberIndex]; + assert([numberObj isKindOfClass:[NSNumber class]]); + + total += [numberObj integerValue]; + } + + // The user interface is adjusted by a KVO observer on recalculating. + + totalStr = [NSString stringWithFormat:@"%ld", (long) total]; + self.formattedTotal = totalStr; + self.recalculating = NO; + + [pool drain]; +} + +- (void)threadRecalculateNumbers2 +{ + NSAutoreleasePool * pool; + NSInteger total; + NSUInteger numberCount; + NSUInteger numberIndex; + NSString * totalStr; + + // IMPORTANT: This method is not actually used. It is here because it's a code + // snippet in the technote, and i wanted to make sure it compiles. + + assert(NO); + + pool = [[NSAutoreleasePool alloc] init]; + assert(pool != nil); + + total = 0; + numberCount = [self.numbers count]; + for (numberIndex = 0; numberIndex < numberCount; numberIndex++) { + NSNumber * numberObj; + + // Sleep for a while. This makes it easiest to test various problematic cases. + + [NSThread sleepForTimeInterval:1.0]; + + // Do the maths. + + numberObj = [self.numbers objectAtIndex:numberIndex]; + assert([numberObj isKindOfClass:[NSNumber class]]); + + total += [numberObj integerValue]; + } + + // Update the user interface on the main thread. + + totalStr = [NSString stringWithFormat:@"%ld", (long) total]; + [self performSelectorOnMainThread:@selector(threadRecalculateDone:) withObject:totalStr waitUntilDone:NO]; + + [pool drain]; +} + +#pragma mark - NSOperation + +- (void)recalculateTotalUsingOperation + // Starts a recalculation using an NSOperation. +{ + // If we're already calculating, cancel that operation. It's going to + // yield stale results. We don't remove the observer here, but rather + // remove the observer when it completes. Also, we don't nil out + // inProgressAdder because it'll just get replaced in the next line + // and changing the value triggers an unnecessary KVO notification of + // recalculating. + + if (self.inProgressAdder != nil) { + fprintf(stderr, "%c %3lu cancelled\n", CharForCurrentThread(), (unsigned long) self.inProgressAdder.sequenceNumber); + [self.inProgressAdder cancel]; + } + + // Start up a replacement operation. + + self.inProgressAdder = [[[AdderOperation alloc] initWithNumbers:self.numbers] autorelease]; + assert(self.inProgressAdder != nil); + + [self.inProgressAdder addObserver:self forKeyPath:@"isFinished" options:0 context:&self->_formattedTotal]; + [self.inProgressAdder addObserver:self forKeyPath:@"isExecuting" options:0 context:&self->_queue]; + + fprintf(stderr, "%c %3lu queuing\n", CharForCurrentThread(), (unsigned long) self.inProgressAdder.sequenceNumber); + [self.queue addOperation:self.inProgressAdder]; + + // The user interface is adjusted by a KVO observer on recalculating. + + self.recalculating = YES; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == &self->_formattedTotal) { + AdderOperation * op; + + // If the operation has finished, call -adderOperationDone: on the main thread to deal + // with the results. + + // can be running on any thread + assert([keyPath isEqual:@"isFinished"]); + op = (AdderOperation *) object; + assert([op isKindOfClass:[AdderOperation class]]); + assert([op isFinished]); + + fprintf(stderr, "%c %3lu finished\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"applyResultsFromThread"]) { + [self adderOperationDone:op]; + } else { + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"allowStale"]) { + [self performSelectorOnMainThread:@selector(adderOperationDoneWrong:) withObject:op waitUntilDone:NO]; + } else { + [self performSelectorOnMainThread:@selector(adderOperationDone:) withObject:op waitUntilDone:NO]; + } + } + } else if (context == &self->_queue) { + AdderOperation * op; + + // We observe -isExecuting purely for logging purposes. + + // can be running on any thread + assert([keyPath isEqual:@"isExecuting"]); + op = (AdderOperation *) object; + assert([op isKindOfClass:[AdderOperation class]]); + if ([op isExecuting]) { + fprintf(stderr, "%c %3lu executing\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + } else { + fprintf(stderr, "%c %3lu stopped\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + } + } else if (context == &self->_inProgressAdder) { + + // If recalculating changes, reload the first section (kListAdderSectionIndexTotal) + // which causes the activity indicator to come or go. + + assert([NSThread isMainThread]); + assert([keyPath isEqual:@"recalculating"]); + assert(object == self); + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:kListAdderSectionIndexTotal]] withRowAnimation:UITableViewRowAnimationNone]; + } + if (NO) { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (void)adderOperationDone:(AdderOperation *)op +{ + assert([NSThread isMainThread]); + assert([op isKindOfClass:[AdderOperation class]]); + + assert(self.recalculating); + + // Always remove our observer, regardless of whether we care about + // the results of this operation. + + fprintf(stderr, "%c %3lu done\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + [op removeObserver:self forKeyPath:@"isFinished"]; + [op removeObserver:self forKeyPath:@"isExecuting"]; + + // Check to see whether these are the results we're looking for. + // If not, we just discard the results; later on we'll be notified + // of the latest add operation completing. + + if (op == self.inProgressAdder) { + assert( ! [op isCancelled] ); + + // Commit the value to our model. + + fprintf(stderr, "%c %3lu commit\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + + self.formattedTotal = op.formattedTotal; + + // Clear out our record of the operation. The user interface is adjusted + // by a KVO observer on recalculating. + + self.inProgressAdder = nil; + self.recalculating = NO; + } else { + fprintf(stderr, "%c %3lu discard\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + } +} + +- (void)adderOperationDoneWrong:(AdderOperation *)op +{ + assert([NSThread isMainThread]); + assert([op isKindOfClass:[AdderOperation class]]); + + // Because we're ignoring stale operations, the following assert will + // trips. + // + // assert(self.recalculating); + + // Always remove our observer, regardless of whether we care about + // the results of this operation. + + fprintf(stderr, "%c %3lu done\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + [op removeObserver:self forKeyPath:@"isFinished"]; + [op removeObserver:self forKeyPath:@"isExecuting"]; + + // Check to see whether these are the results we're looking for. + // If not, we just discard the results; later on we'll be notified + // of the latest add operation completing. + + // Because we're ignoring stale operations, the following assert will + // trips. + // + // assert( ! [op isCancelled] ); + + // Commit the value to our model. + + fprintf(stderr, "%c %3lu commit\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber); + + self.formattedTotal = op.formattedTotal; + + // Clear out our record of the operation. The user interface is adjusted + // by a KVO observer on recalculating. + + self.inProgressAdder = nil; + self.recalculating = NO; +} + +#pragma mark * UI actions + +- (void)defaultsMinimumAction:(id)sender + // Called when the user taps the left bar button ("Defaults" or "Minimum"). + // If we have lots of numbers, set the list to contain a sigle entry. If we have + // just one number, reset the list back to the defaults. This allows us to easily + // test cancellation and the discard of stale results. +{ + #pragma unused(sender) + if ([self.numbers count] > 1) { + [self.numbers removeAllObjects]; + [self.numbers addObject:[NSNumber numberWithInteger:41]]; + } else { + [self.numbers replaceObjectsInRange:NSMakeRange(0, [self.numbers count]) withObjectsFromArray:[[self class] defaultNumbers]]; + } + [self syncLeftBarButtonTitle]; + if (self.isViewLoaded) { + [self.tableView reloadData]; + } + [self recalculateTotal]; +} + +- (void)optionsAction:(id)sender + // Called when the user taps the option button. We just bring up the + // options view. +{ + #pragma unused(sender) + [self presentOptionsModally]; +} + +@end diff --git a/ListAdder/MainWindow.xib b/ListAdder/MainWindow.xib new file mode 100644 index 0000000..8370787 --- /dev/null +++ b/ListAdder/MainWindow.xib @@ -0,0 +1,465 @@ + + + + 512 + 10F569 + 788 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 117 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + IBCocoaTouchFramework + + + + + 1 + + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + NO + YES + YES + IBCocoaTouchFramework + + + YES + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navController + + + + 21 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + 16 + + + YES + + + + + + 18 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 16.IBEditorWindowLastContentRect + 16.IBPluginDependency + 18.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + {{333, 365}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{333, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 21 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navController + window + + + YES + UIViewController + UIWindow + + + + YES + + YES + navController + window + + + YES + + navController + UIViewController + + + window + UIWindow + + + + + IBProjectSource + AppDelegate.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ListAdder.xcodeproj + 3 + 117 + + diff --git a/ListAdder/NumberPickerController.h b/ListAdder/NumberPickerController.h new file mode 100644 index 0000000..1172577 --- /dev/null +++ b/ListAdder/NumberPickerController.h @@ -0,0 +1,81 @@ +/* + File: NumberPickerController.h + + Contains: Controller that lets the user pick a number. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@protocol NumberPickerControllerDelegate; + +@interface NumberPickerController : UITableViewController +{ + NSArray * _numbers; + id _delegate; +} + +- (id)init; + +@property (nonatomic, assign, readwrite) id delegate; + +- (void)presentModallyOn:(UIViewController *)parent; + // This wraps the controller is a UINavigationController and presents + // that modally on the specified parent controller. + +@end + +@protocol NumberPickerControllerDelegate + +@required + +- (void)numberPicker:(NumberPickerController *)controller didChooseNumber:(NSNumber *)number; + // nil for cancellation + +@end diff --git a/ListAdder/NumberPickerController.m b/ListAdder/NumberPickerController.m new file mode 100644 index 0000000..3087f71 --- /dev/null +++ b/ListAdder/NumberPickerController.m @@ -0,0 +1,176 @@ +/* + File: NumberPickerController.m + + Contains: Controller that lets the user pick a number. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "NumberPickerController.h" + +@interface NumberPickerController () + +@property (nonatomic, copy, readonly ) NSArray * numbers; + +@end + +@implementation NumberPickerController + +- (id)init +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self != nil) { + self->_numbers = [[NSMutableArray alloc] initWithObjects: + [NSNumber numberWithInt:0], + [NSNumber numberWithInt:1], + [NSNumber numberWithInt:2], + [NSNumber numberWithInt:3], + [NSNumber numberWithInt:4], + [NSNumber numberWithInt:5], + [NSNumber numberWithInt:6], + [NSNumber numberWithInt:7], + [NSNumber numberWithInt:8], + [NSNumber numberWithInt:9], + nil + ]; + self.title = @"Number to Add"; + } + return self; +} + +- (void)dealloc +{ + [self->_numbers release]; + [super dealloc]; +} + +@synthesize numbers = _numbers; +@synthesize delegate = _delegate; + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + assert(tv == self.tableView); + assert(section == 0); + + return [self.numbers count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + UITableViewCell * cell; + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < [self.numbers count]); + + cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"] autorelease]; + assert(cell != nil); + } + cell.textLabel.text = [[self.numbers objectAtIndex:indexPath.row] description]; + + return cell; +} + +- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < [self.numbers count]); + + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + + // Tell the delegate about the selection. + + if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(numberPicker:didChooseNumber:)] ) { + [self.delegate numberPicker:self didChooseNumber:[self.numbers objectAtIndex:indexPath.row]]; + } +} + +- (void)cancelAction:(id)sender +{ + #pragma unused(sender) + + // Tell the delegate about the cancellation. + + if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(numberPicker:didChooseNumber:)] ) { + [self.delegate numberPicker:self didChooseNumber:nil]; + } +} + +- (void)presentModallyOn:(UIViewController *)parent +{ + UINavigationController * nav; + + // Create a navigation controller with us as its root. + + nav = [[[UINavigationController alloc] initWithRootViewController:self] autorelease]; + assert(nav != nil); + + // Set up the Cancel button on the left of the navigation bar. + + self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction:)] autorelease]; + assert(self.navigationItem.leftBarButtonItem != nil); + + // Present the navigation controller on the specified parent + // view controller. + + [parent presentModalViewController:nav animated:YES]; +} + +@end diff --git a/ListAdder/OptionsController.h b/ListAdder/OptionsController.h new file mode 100644 index 0000000..330f8e2 --- /dev/null +++ b/ListAdder/OptionsController.h @@ -0,0 +1,81 @@ +/* + File: OptionsController.h + + Contains: Controller to set various debugging options. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@protocol OptionsControllerDelegate; + +@interface OptionsController : UITableViewController +{ + NSMutableDictionary * _currentState; // NSString (key) to NSNumber (Boolean) + id _delegate; +} + +- (id)init; + +@property (nonatomic, assign, readwrite) id delegate; + +- (void)presentModallyOn:(UIViewController *)parent; + // This wraps the controller is a UINavigationController and presents + // that modally on the specified parent controller. + +@end + +@protocol OptionsControllerDelegate + +@required + +- (void)didSaveOptions:(OptionsController *)controller; +- (void)didCancelOptions:(OptionsController *)controller; + +@end diff --git a/ListAdder/OptionsController.m b/ListAdder/OptionsController.m new file mode 100644 index 0000000..3d6310e --- /dev/null +++ b/ListAdder/OptionsController.m @@ -0,0 +1,230 @@ +/* + File: OptionsController.m + + Contains: Controller to set various debugging options. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "OptionsController.h" + +#include + +@interface OptionsController () + +@property (nonatomic, retain, readonly ) NSMutableDictionary * currentState; +@end + +@implementation OptionsController + +static NSString * kOptionLabels[] = { @"Retain, Not Copy", @"Allow Stale", @"Use Threads Directly", @"Apply Results From Thread" }; +static NSString * kOptionKeys[] = { @"retainNotCopy", @"allowStale", @"useThreadsDirectly", @"applyResultsFromThread" }; + +enum { + kOptionCount = sizeof(kOptionLabels) / sizeof(*kOptionLabels) +}; +check_compile_time( kOptionCount == (sizeof(kOptionKeys) / sizeof(*kOptionKeys)) ); + +- (id)init +{ + self = [super initWithStyle:UITableViewStyleGrouped]; + if (self != nil) { + NSUserDefaults * defaults; + NSUInteger optionIndex; + + self->_currentState = [[NSMutableDictionary alloc] init]; + assert(self->_currentState != nil); + + defaults = [NSUserDefaults standardUserDefaults]; + assert(defaults != nil); + + for (optionIndex = 0; optionIndex < kOptionCount; optionIndex++) { + [self->_currentState setObject:[NSNumber numberWithBool:[defaults boolForKey:kOptionKeys[optionIndex]]] forKey:kOptionKeys[optionIndex]]; + } + + self.title = @"Options"; + } + return self; +} + +- (void)dealloc +{ + [self->_currentState release]; + [super dealloc]; +} + +@synthesize currentState = _currentState; +@synthesize delegate = _delegate; + +- (NSString *)tableView:(UITableView *)tv titleForFooterInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + assert(tv == self.tableView); + assert(section == 0); + return @ + "These options enable code that does not work properly. " + "If you enable any options, the application is likely to crash or misbehave. " + "The goal here is to illustrate TN2109's examples of how NOT to write threaded code; " + "these options let you see the resulting problems in action." + ; +} + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + assert(tv == self.tableView); + assert(section == 0); + + return kOptionCount; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + UITableViewCell * cell; + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < kOptionCount); + + cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"] autorelease]; + assert(cell != nil); + } + cell.textLabel.text = kOptionLabels[indexPath.row]; + cell.accessoryType = [[self.currentState objectForKey:kOptionKeys[indexPath.row]] boolValue] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; + + return cell; +} + +- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + UITableViewCell * cell; + NSString * key; + BOOL newValue; + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < kOptionCount); + + key = kOptionKeys[indexPath.row]; + newValue = ! [[self.currentState objectForKey:kOptionKeys[indexPath.row]] boolValue]; + [self.currentState setObject:[NSNumber numberWithBool:newValue] forKey:key]; + cell = [self.tableView cellForRowAtIndexPath:indexPath]; + if (cell != nil) { + cell.accessoryType = newValue ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; + } + + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +- (void)saveAction:(id)sender +{ + #pragma unused(sender) + NSUserDefaults * defaults; + + // Commit the options to the user defaults. + + defaults = [NSUserDefaults standardUserDefaults]; + assert(defaults != nil); + + for (NSString * key in self.currentState) { + [defaults setObject:[self.currentState objectForKey:key] forKey:key]; + } + + [defaults synchronize]; + + // Tell the delegate about the save. + + if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(didSaveOptions:)] ) { + [self.delegate didSaveOptions:self]; + } +} + +- (void)cancelAction:(id)sender +{ + #pragma unused(sender) + + // Tell the delegate about the cancellation. + + if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(didCancelOptions:)] ) { + [self.delegate didCancelOptions:self]; + } +} + +- (void)presentModallyOn:(UIViewController *)parent +{ + UINavigationController * nav; + + // Create a navigation controller with us as its root. + + nav = [[[UINavigationController alloc] initWithRootViewController:self] autorelease]; + assert(nav != nil); + + // Set up the Cancel button on the left of the navigation bar. + + self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction:)] autorelease]; + assert(self.navigationItem.leftBarButtonItem != nil); + self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveAction:)] autorelease]; + assert(self.navigationItem.rightBarButtonItem != nil); + + // Present the navigation controller on the specified parent + // view controller. + + [parent presentModalViewController:nav animated:YES]; +} + +@end diff --git a/ListAdder/Read Me About ListAdder.txt b/ListAdder/Read Me About ListAdder.txt new file mode 100644 index 0000000..6c9e1b2 --- /dev/null +++ b/ListAdder/Read Me About ListAdder.txt @@ -0,0 +1,64 @@ +Read Me About ListAdder +================= +1.0 + +This samples demonstrates the technique of thread confinement using NSOperation. It was written to support Technote TN2109 "Simple and Reliable Threading with NSOperation". + +ListAdder requires iPhone OS 3.1.3, although the underlying will work on all versions of iOS and on Mac OS X 10.5 and later. + +Packing List +------------ +The sample contains the following items: + +o Read Me About ListAdder.txt -- This file. + +o ListAdder.xcodeproj -- An Xcode project for the sample. + +o main.m, Info.plist, images, MainWindow.xib, and AppDelegate.[hm] -- Uninteresting boilerplate code. + +o ListAdderViewController.[hm] -- A view controller for the main view. + +o AdderOperation.[hm] -- The NSOperation subclass that does the asynchronous add. Together with ListAdderViewController this represents the interesting part of the code. + +o NumberPickerController.[hm] -- A view controller that lets the user choose a number to add to the list. + +o OptionsController.[hm] -- A view controller that lets the user change various debugging options. + +Building the Sample +------------------- +The sample was built using Xcode 3.2.3 on Mac OS X 10.6.4 with the iOS 4.0 SDK. You should be able to just open the project and choose Build from the Build menu. + +Using the Sample +---------------- +Upon running the sample you are presented with a list of numbers. You can tap the plus button to add a number to the list. You can tap one of the minus buttons to remove items from the list. Whenever you change the list the application kicks off an async operation to update the total being displayed. This operation is artifically slowed down to help test various edge cases. + +You can tap the Minimum button to set the list of items to a single entry or, if the list is already a single entry, tap the Defaults button to set it back to the default list. This is useful when testing various edge cases. You can also tap the Options button to enable various testing options: + +o "Retain, Not Copy" -- If you enable this option AdderOperation retains, rather than copying, the incoming list of numbers. If you do this and then tap the Defaults/Minimum button rapidly, the application will crash as the main thread mutates the list that's being operated on by the thread running the AdderOperation. + +o "Allow Stale" -- If you enable this option ListAdderViewController does not check whether a completed operation is still relevant, meaning that, if you make changes in rapid succession, you see stale results in the user interface. + +o "Use Threads Directly" -- If you enable this option ListAdderViewController will use a thread rather than an NSOperation to update the total. This allows us the code to demonstrate the various problems that crop up when using threads rather than operations. + +o "Apply Results From Thread" -- If you enable this option ListAdderViewController will commit the results directly from its secondary thread rather than bouncing back to the main thread. Needless to say, that generally ends badly. + +IMPORTANT: Because this sample was written to support Technote TN2109, it demonstrates various techniques that are incorrect. Such code is either never executed (and commented as such) or executed conditionally based on the debugging options listed above. If you enable these options, the code will do the wrong thing and, beyond that, it may crash. Specifically, in the Debug build it may trip an assert, while in the Release build it's likely to crash in more subtle ways. + +How it Works +------------ +This sample was created to support TN 2109 "Simple and Reliable Threading with NSOperation". You should read that technote to learn more about this code. + +Credits and Version History +--------------------------- +If you find any problems with this sample, please file a bug against it. + + + +1.0 (Aug 2010) was the first shipping version. + +Share and Enjoy + +Apple Developer Technical Support +Core OS/Hardware + +24 Aug 2010 diff --git a/ListAdder/images/Icon-72.png b/ListAdder/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/ListAdder/images/Icon-72.png differ diff --git a/ListAdder/images/Icon-Small-50.png b/ListAdder/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/ListAdder/images/Icon-Small-50.png differ diff --git a/ListAdder/images/Icon-Small.png b/ListAdder/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/ListAdder/images/Icon-Small.png differ diff --git a/ListAdder/images/Icon-Small@2x.png b/ListAdder/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/ListAdder/images/Icon-Small@2x.png differ diff --git a/ListAdder/images/Icon.png b/ListAdder/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/ListAdder/images/Icon.png differ diff --git a/ListAdder/images/Icon@2x.png b/ListAdder/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/ListAdder/images/Icon@2x.png differ diff --git a/ListAdder/images/iTunesArtwork b/ListAdder/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/ListAdder/images/iTunesArtwork differ diff --git a/ListAdder/main.m b/ListAdder/main.m new file mode 100644 index 0000000..50299bc --- /dev/null +++ b/ListAdder/main.m @@ -0,0 +1,69 @@ +/* + File: main.m + + Contains: Application main. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +int main(int argc, char **argv) +{ + int retVal; + NSAutoreleasePool * pool; + + pool = [[NSAutoreleasePool alloc] init]; + assert(pool != nil); + + retVal = UIApplicationMain(argc, argv, nil, nil); + + [pool drain]; + + return retVal; +} diff --git a/LocateMe.zip b/LocateMe.zip new file mode 100644 index 0000000..92a81fe Binary files /dev/null and b/LocateMe.zip differ diff --git a/LocateMe/Classes/AppDelegate.h b/LocateMe/Classes/AppDelegate.h new file mode 100644 index 0000000..41eb1fe --- /dev/null +++ b/LocateMe/Classes/AppDelegate.h @@ -0,0 +1,59 @@ +/* + File: AppDelegate.h + Abstract: The application delegate has a minimal role in this sample: in -applicationDidFinishLaunching: it adds the tab bar controller's view to the window. It also creates a CLLocationManager object to check the locationServicesEnabled property at launch time. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface AppDelegate : NSObject { + UIWindow *window; + UITabBarController *tabBarController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController; + +@end diff --git a/LocateMe/Classes/AppDelegate.m b/LocateMe/Classes/AppDelegate.m new file mode 100644 index 0000000..7708506 --- /dev/null +++ b/LocateMe/Classes/AppDelegate.m @@ -0,0 +1,78 @@ +/* + File: AppDelegate.m + Abstract: The application delegate has a minimal role in this sample: in -applicationDidFinishLaunching: it adds the tab bar controller's view to the window. It also creates a CLLocationManager object to check the locationServicesEnabled property at launch time. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import + +@implementation AppDelegate + +@synthesize window; +@synthesize tabBarController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + [window addSubview:tabBarController.view]; + // Create a location manager instance to determine if location services are enabled. This manager instance will be + // immediately released afterwards. + CLLocationManager *manager = [[CLLocationManager alloc] init]; + if (manager.locationServicesEnabled == NO) { + UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled" message:@"You currently have all location services for this device disabled. If you proceed, you will be asked to confirm whether location services should be reenabled." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [servicesDisabledAlert show]; + [servicesDisabledAlert release]; + } + [manager release]; +} + +- (void)dealloc { + [tabBarController release]; + [window release]; + [super dealloc]; +} + +@end + diff --git a/LocateMe/Classes/CLLocation (Strings).h b/LocateMe/Classes/CLLocation (Strings).h new file mode 100644 index 0000000..2d5b500 --- /dev/null +++ b/LocateMe/Classes/CLLocation (Strings).h @@ -0,0 +1,66 @@ +/* + File: CLLocation (Strings).h + Abstract: This is an Objective C category on the CLLocation class that extends the class by adding some convenience methods for presenting localized string representations of various properties. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface CLLocation (Strings) + +- (NSString *)localizedCoordinateString; + +- (NSString *)localizedAltitudeString; + +- (NSString *)localizedHorizontalAccuracyString; + +- (NSString *)localizedVerticalAccuracyString; + +- (NSString *)localizedCourseString; + +- (NSString *)localizedSpeedString; + +@end diff --git a/LocateMe/Classes/CLLocation (Strings).m b/LocateMe/Classes/CLLocation (Strings).m new file mode 100644 index 0000000..eb793d0 --- /dev/null +++ b/LocateMe/Classes/CLLocation (Strings).m @@ -0,0 +1,99 @@ +/* + File: CLLocation (Strings).m + Abstract: This is an Objective C category on the CLLocation class that extends the class by adding some convenience methods for presenting localized string representations of various properties. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "CLLocation (Strings).h" + + +@implementation CLLocation (Strings) + +- (NSString *)localizedCoordinateString { + if (self.horizontalAccuracy < 0) { + return NSLocalizedString(@"DataUnavailable", @"DataUnavailable"); + } + NSString *latString = (self.coordinate.latitude < 0) ? NSLocalizedString(@"South", @"South") : NSLocalizedString(@"North", @"North"); + NSString *lonString = (self.coordinate.longitude < 0) ? NSLocalizedString(@"West", @"West") : NSLocalizedString(@"East", @"East"); + return [NSString stringWithFormat:NSLocalizedString(@"LatLongFormat", @"LatLongFormat"), fabs(self.coordinate.latitude), latString, fabs(self.coordinate.longitude), lonString]; +} + +- (NSString *)localizedAltitudeString { + if (self.verticalAccuracy < 0) { + return NSLocalizedString(@"DataUnavailable", @"DataUnavailable"); + } + NSString *seaLevelString = (self.altitude < 0) ? NSLocalizedString(@"BelowSeaLevel", @"BelowSeaLevel") : NSLocalizedString(@"AboveSeaLevel", @"AboveSeaLevel"); + return [NSString stringWithFormat:NSLocalizedString(@"AltitudeFormat", @"AltitudeFormat"), fabs(self.altitude), seaLevelString]; +} + +- (NSString *)localizedHorizontalAccuracyString { + if (self.horizontalAccuracy < 0) { + return NSLocalizedString(@"DataUnavailable", @"DataUnavailable"); + } + return [NSString stringWithFormat:NSLocalizedString(@"AccuracyFormat", @"AccuracyFormat"), self.horizontalAccuracy]; +} + +- (NSString *)localizedVerticalAccuracyString { + if (self.verticalAccuracy < 0) { + return NSLocalizedString(@"DataUnavailable", @"DataUnavailable"); + } + return [NSString stringWithFormat:NSLocalizedString(@"AccuracyFormat", @"AccuracyFormat"), self.verticalAccuracy]; +} + +- (NSString *)localizedCourseString { + if (self.course < 0) { + return NSLocalizedString(@"DataUnavailable", @"DataUnavailable"); + } + return [NSString stringWithFormat:NSLocalizedString(@"CourseFormat", @"CourseFormat"), self.course]; +} + +- (NSString *)localizedSpeedString { + if (self.speed < 0) { + return NSLocalizedString(@"DataUnavailable", @"DataUnavailable"); + } + return [NSString stringWithFormat:NSLocalizedString(@"SpeedFormat", @"SpeedFormat"), self.speed]; +} + +@end diff --git a/LocateMe/Classes/GetLocationViewController.h b/LocateMe/Classes/GetLocationViewController.h new file mode 100644 index 0000000..099bb6c --- /dev/null +++ b/LocateMe/Classes/GetLocationViewController.h @@ -0,0 +1,85 @@ +/* + File: GetLocationViewController.h + Abstract: Attempts to acquire a location measurement with a specific level of accuracy. A timeout is used to avoid wasting power in the case where a sufficiently accurate measurement cannot be acquired. Presents a SetupViewController instance so the user can configure the desired accuracy and timeout. Uses a LocationDetailViewController instance to drill down into details for a given location measurement. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import "SetupViewController.h" + +@class LocationDetailViewController; + +@interface GetLocationViewController : UIViewController { + SetupViewController *setupViewController; + UIButton *startButton; + UILabel *descriptionLabel; + CLLocationManager *locationManager; + NSMutableArray *locationMeasurements; + CLLocation *bestEffortAtLocation; + UITableView *tableView; + NSDateFormatter *dateFormatter; + NSString *stateString; + LocationDetailViewController *locationDetailViewController; +} + +@property (nonatomic, retain, readonly) SetupViewController *setupViewController; +@property (nonatomic, retain) IBOutlet UIButton *startButton; +@property (nonatomic, retain) IBOutlet UILabel *descriptionLabel; +@property (nonatomic, retain) CLLocationManager *locationManager; +@property (nonatomic, retain) NSMutableArray *locationMeasurements; +@property (nonatomic, retain) CLLocation *bestEffortAtLocation; +@property (nonatomic, retain) IBOutlet UITableView *tableView; +@property (nonatomic, retain, readonly) NSDateFormatter *dateFormatter; +@property (nonatomic, retain) NSString *stateString; +@property (nonatomic, retain, readonly) LocationDetailViewController *locationDetailViewController; + +- (IBAction)start:(id)sender; + +- (void)setupViewController:(SetupViewController *)controller didFinishSetupWithInfo:(NSDictionary *)setupInfo; + +- (void)stopUpdatingLocation:(NSString *)state; + +@end diff --git a/LocateMe/Classes/GetLocationViewController.m b/LocateMe/Classes/GetLocationViewController.m new file mode 100644 index 0000000..0a94d4e --- /dev/null +++ b/LocateMe/Classes/GetLocationViewController.m @@ -0,0 +1,343 @@ +/* + File: GetLocationViewController.m + Abstract: Attempts to acquire a location measurement with a specific level of accuracy. A timeout is used to avoid wasting power in the case where a sufficiently accurate measurement cannot be acquired. Presents a SetupViewController instance so the user can configure the desired accuracy and timeout. Uses a LocationDetailViewController instance to drill down into details for a given location measurement. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "GetLocationViewController.h" +#import "LocationDetailViewController.h" +#import "CLLocation (Strings).h" + +@implementation GetLocationViewController + +@synthesize startButton; +@synthesize descriptionLabel; +@synthesize locationManager; +@synthesize locationMeasurements; +@synthesize bestEffortAtLocation; +@synthesize tableView; +@synthesize stateString; + +- (void)viewDidLoad { + self.locationMeasurements = [NSMutableArray array]; +} + +/* + * The view hierarchy for this controller has been torn down. This usually happens in response to low memory notifications. + * All IBOutlets should be released by setting their property to nil in order to free up as much memory as possible. + * This is also a good place to release other variables that can be recreated when needed. + */ +- (void)viewDidUnload { + self.startButton = nil; + self.descriptionLabel = nil; + self.stateString = nil; + self.tableView = nil; + // For the readonly properties, they must be released and set to nil directly. + [setupViewController release]; + setupViewController = nil; + [locationDetailViewController release]; + locationDetailViewController = nil; + [dateFormatter release]; + dateFormatter = nil; +} + +- (void)dealloc { + [setupViewController release]; + [startButton release]; + [descriptionLabel release]; + [locationManager release]; + [locationMeasurements release]; + [bestEffortAtLocation release]; + [stateString release]; + [dateFormatter release]; + [tableView release]; + [locationDetailViewController release]; + [setupViewController release]; + [super dealloc]; +} + +/* + * The lazy "getter" for the readonly property. + */ +- (SetupViewController *)setupViewController { + if (setupViewController == nil) { + setupViewController = [[SetupViewController alloc] initWithNibName:@"GetLocationSetupView" bundle:nil]; + setupViewController.delegate = self; + } + return setupViewController; +} + +/* + * The lazy "getter" for the readonly property. + */ +- (LocationDetailViewController *)locationDetailViewController { + if (locationDetailViewController == nil) { + locationDetailViewController = [[LocationDetailViewController alloc] initWithStyle:UITableViewStyleGrouped]; + } + return locationDetailViewController; +} + +/* + * The lazy "getter" for the readonly property. + */ +- (NSDateFormatter *)dateFormatter { + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterLongStyle]; + } + return dateFormatter; +} + +- (IBAction)start:(id)sender { + [self.navigationController presentModalViewController:self.setupViewController animated:YES]; +} + +/* + * The reset method allows the user to repeatedly test the location functionality. In addition to discarding all of + * the location measurements from the previous "run", it animates a transition in the user interface between the table + * which displays location data and the start button and description label presented at launch. + */ +- (void)reset { + self.bestEffortAtLocation = nil; + [self.locationMeasurements removeAllObjects]; + [UIView beginAnimations:@"Reset" context:nil]; + [UIView setAnimationDuration:0.6]; + startButton.alpha = 1.0; + descriptionLabel.alpha = 1.0; + tableView.alpha = 0.0; + [self.navigationItem setLeftBarButtonItem:nil animated:YES];; + [UIView commitAnimations]; +} + +#pragma mark Location Manager Interactions + +/* + * This method is invoked when the user hits "Done" in the setup view controller. The options chosen by the user are + * passed in as a dictionary. The keys for this dictionary are declared in SetupViewController.h. + */ +- (void)setupViewController:(SetupViewController *)controller didFinishSetupWithInfo:(NSDictionary *)setupInfo { + startButton.alpha = 0.0; + descriptionLabel.alpha = 0.0; + tableView.alpha = 1.0; + // Create the manager object + self.locationManager = [[[CLLocationManager alloc] init] autorelease]; + locationManager.delegate = self; + // This is the most important property to set for the manager. It ultimately determines how the manager will + // attempt to acquire location and thus, the amount of power that will be consumed. + locationManager.desiredAccuracy = [[setupInfo objectForKey:kSetupInfoKeyAccuracy] doubleValue]; + // Once configured, the location manager must be "started". + [locationManager startUpdatingLocation]; + [self performSelector:@selector(stopUpdatingLocation:) withObject:@"Timed Out" afterDelay:[[setupInfo objectForKey:kSetupInfoKeyTimeout] doubleValue]]; + self.stateString = NSLocalizedString(@"Updating", @"Updating"); + [self.tableView reloadData]; +} + +/* + * We want to get and store a location measurement that meets the desired accuracy. For this example, we are + * going to use horizontal accuracy as the deciding factor. In other cases, you may wish to use vertical + * accuracy, or both together. + */ +- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { + // store all of the measurements, just so we can see what kind of data we might receive + [locationMeasurements addObject:newLocation]; + // test the age of the location measurement to determine if the measurement is cached + // in most cases you will not want to rely on cached measurements + NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; + if (locationAge > 5.0) return; + // test that the horizontal accuracy does not indicate an invalid measurement + if (newLocation.horizontalAccuracy < 0) return; + // test the measurement to see if it is more accurate than the previous measurement + if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) { + // store the location as the "best effort" + self.bestEffortAtLocation = newLocation; + // test the measurement to see if it meets the desired accuracy + // + // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue + // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of + // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout. + // + if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) { + // we have a measurement that meets our requirements, so we can stop updating the location + // + // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible. + // + [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")]; + // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil]; + } + } + // update the display with the new location data + [self.tableView reloadData]; +} + +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { + // The location "unknown" error simply means the manager is currently unable to get the location. + // We can ignore this error for the scenario of getting a single location fix, because we already have a + // timeout that will stop the location manager to save power. + if ([error code] != kCLErrorLocationUnknown) { + [self stopUpdatingLocation:NSLocalizedString(@"Error", @"Error")]; + } +} + +- (void)stopUpdatingLocation:(NSString *)state { + self.stateString = state; + [self.tableView reloadData]; + [locationManager stopUpdatingLocation]; + locationManager.delegate = nil; + + UIBarButtonItem *resetItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Reset", @"Reset") style:UIBarButtonItemStyleBordered target:self action:@selector(reset)] autorelease]; + [self.navigationItem setLeftBarButtonItem:resetItem animated:YES];; +} + +#pragma mark Table View DataSource/Delegate + +// The table view has three sections. The first has 1 row which displays status information. The second has 1 row which displays the most accurate valid location measurement received. The third has a row for each valid location object received (including the one displayed in the second section) from the location manager. + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)table { + return (self.bestEffortAtLocation != nil) ? 3 : 1; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + switch (section) { + case 0: { + return NSLocalizedString(@"Status", @"Status"); + } break; + case 1: { + return NSLocalizedString(@"Best Measurement", @"Best Measurement"); + } break; + default: { + return NSLocalizedString(@"All Measurements", @"All Measurements"); + } break; + } +} + +- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section { + switch (section) { + case 0: { + return 1; + } break; + case 1: { + return 1; + } break; + default: { + return locationMeasurements.count; + } break; + } +} + +- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath { + switch (indexPath.section) { + case 0: { + // The cell for the status row uses the cell style "UITableViewCellStyleValue1", which has a label on the left side of the cell with left-aligned and black text; on the right side is a label that has smaller blue text and is right-aligned. An activity indicator has been added to the cell and is animated while the location manager is updating. The cell's text label displays the current state of the manager. + static NSString * const kStatusCellID = @"StatusCellID"; + static NSInteger const kStatusCellActivityIndicatorTag = 2; + UIActivityIndicatorView *activityIndicator = nil; + UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:kStatusCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kStatusCellID] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; + CGRect frame = activityIndicator.frame; + frame.origin = CGPointMake(290, 12); + activityIndicator.frame = frame; + activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + activityIndicator.tag = kStatusCellActivityIndicatorTag; + [cell.contentView addSubview:activityIndicator]; + } else { + activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:kStatusCellActivityIndicatorTag]; + } + cell.textLabel.text = stateString; + if ([stateString isEqualToString:NSLocalizedString(@"Updating", @"Updating")]) { + if (activityIndicator.isAnimating == NO) [activityIndicator startAnimating]; + } else { + if (activityIndicator.isAnimating) [activityIndicator stopAnimating]; + } + return cell; + } break; + case 1: { + // The cells for the location rows use the cell style "UITableViewCellStyleSubtitle", which has a left-aligned label across the top and a left-aligned label below it in smaller gray text. The text label shows the coordinates for the location and the detail text label shows its timestamp. + static NSString * const kBestMeasurementCellID = @"BestMeasurementCellID"; + UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:kBestMeasurementCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kBestMeasurementCellID] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + cell.textLabel.text = bestEffortAtLocation.localizedCoordinateString; + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:bestEffortAtLocation.timestamp]; + return cell; + } break; + default: { + // The cells for the location rows use the cell style "UITableViewCellStyleSubtitle", which has a left-aligned label across the top and a left-aligned label below it in smaller gray text. The text label shows the coordinates for the location and the detail text label shows its timestamp. + static NSString * const kOtherMeasurementsCellID = @"OtherMeasurementsCellID"; + UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:kOtherMeasurementsCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kOtherMeasurementsCellID] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + CLLocation *location = [locationMeasurements objectAtIndex:indexPath.row]; + cell.textLabel.text = location.localizedCoordinateString; + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:location.timestamp]; + return cell; + } break; + } +} + +// Delegate method invoked before the user selects a row. In this sample, we use it to prevent selection in the +// first section of the table view. +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + return (indexPath.section == 0) ? nil : indexPath; +} + +// Delegate method invoked after the user selects a row. Selecting a row containing a location object +// will navigate to a new view controller displaying details about that location. +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + CLLocation *location = [locationMeasurements objectAtIndex:indexPath.row]; + self.locationDetailViewController.location = location; + [self.navigationController pushViewController:locationDetailViewController animated:YES]; +} + +@end diff --git a/LocateMe/Classes/LocationDetailViewController.h b/LocateMe/Classes/LocationDetailViewController.h new file mode 100644 index 0000000..27c4532 --- /dev/null +++ b/LocateMe/Classes/LocationDetailViewController.h @@ -0,0 +1,60 @@ +/* + File: LocationDetailViewController.h + Abstract: Lists the values for all the properties of a single CLLocation object. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@interface LocationDetailViewController : UITableViewController { + CLLocation *location; + NSDateFormatter *dateFormatter; +} + +@property (nonatomic, retain) CLLocation *location; +@property (nonatomic, retain, readonly) NSDateFormatter *dateFormatter; + +@end diff --git a/LocateMe/Classes/LocationDetailViewController.m b/LocateMe/Classes/LocationDetailViewController.m new file mode 100644 index 0000000..6838f5d --- /dev/null +++ b/LocateMe/Classes/LocationDetailViewController.m @@ -0,0 +1,158 @@ +/* + File: LocationDetailViewController.m + Abstract: Lists the values for all the properties of a single CLLocation object. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "LocationDetailViewController.h" +#import "CLLocation (Strings).h" + +@implementation LocationDetailViewController + +@synthesize location; + +- (void)dealloc { + [dateFormatter release]; + [location release]; + [super dealloc]; +} + +- (void)viewDidUnload { + [dateFormatter release]; + dateFormatter = nil; + self.location = nil; +} + +- (NSDateFormatter *)dateFormatter { + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterLongStyle]; + } + return dateFormatter; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.tableView reloadData]; +} + +#pragma mark Table view methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)table { + return 3; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return (section == 0) ? 3: 2; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + switch (section) { + case 0: { + return NSLocalizedString(@"Attributes", @"Attributes"); + } break; + case 1: { + return NSLocalizedString(@"Accuracy", @"Accuracy"); + } break; + default: { + return NSLocalizedString(@"Course and Speed", @"Course and Speed"); + } break; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kLocationAttributeCellID = @"LocationAttributeCellID"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kLocationAttributeCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kLocationAttributeCellID] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + if (indexPath.section == 0) { + switch (indexPath.row) { + case 0: { + cell.textLabel.text = NSLocalizedString(@"timestamp", @"timestamp"); + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:location.timestamp]; + } break; + case 1: { + cell.textLabel.text = NSLocalizedString(@"coordinate", @"coordinate"); + if (location.horizontalAccuracy < 0) { + } else { + cell.detailTextLabel.text = location.localizedCoordinateString; + } + } break; + default: { + cell.textLabel.text = NSLocalizedString(@"altitude", @"altitude"); + cell.detailTextLabel.text = location.localizedAltitudeString; + } break; + } + } else if (indexPath.section == 1) { + switch (indexPath.row) { + case 0: { + cell.textLabel.text = NSLocalizedString(@"horizontal", @"horizontal"); + cell.detailTextLabel.text = location.localizedHorizontalAccuracyString; + } break; + default: { + cell.textLabel.text = NSLocalizedString(@"vertical", @"vertical"); + cell.detailTextLabel.text = location.localizedVerticalAccuracyString; + } break; + } + } else { + switch (indexPath.row) { + case 0: { + cell.textLabel.text = NSLocalizedString(@"course", @"course"); + cell.detailTextLabel.text = location.localizedCourseString; + } break; + default: { + cell.textLabel.text = NSLocalizedString(@"speed", @"speed"); + cell.detailTextLabel.text = location.localizedSpeedString; + } break; + } + } + return cell; +} + +@end + diff --git a/LocateMe/Classes/SetupViewController.h b/LocateMe/Classes/SetupViewController.h new file mode 100644 index 0000000..69975a2 --- /dev/null +++ b/LocateMe/Classes/SetupViewController.h @@ -0,0 +1,88 @@ +/* + File: SetupViewController.h + Abstract: Displayed by either a GetLocationViewController or a TrackLocationViewController, this view controller is presented modally and communicates back to the presenting controller using a simple delegate protocol. The protocol sends setupViewController:didFinishSetupWithInfo: to its delegate with a dictionary containing a desired accuracy and either a timeout or a distance filter value. A custom UIPickerView specifies the desired accuracy. A slider is shown for setting the timeout or distance filter. This view controller can be initialized using either of two nib files: GetLocationSetupView.xib or TrackLocationSetupView.xib. These nibs have nearly identical layouts, but differ in the labels and attributes for the slider. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +// Keys for the dictionary provided to the delegate. +extern NSString * const kSetupInfoKeyAccuracy; +extern NSString * const kSetupInfoKeyDistanceFilter; +extern NSString * const kSetupInfoKeyTimeout; + +@class SetupViewController; + +@protocol SetupViewControllerDelegate + +@optional + +- (void)setupViewController:(SetupViewController *)controller didFinishSetupWithInfo:(NSDictionary *)setupInfo; + +@end + + +@interface SetupViewController : UIViewController { + id delegate; + NSMutableDictionary *setupInfo; + NSArray *accuracyOptions; + BOOL configureForTracking; + + UIPickerView *accuracyPicker; + UISlider *slider; +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, retain) NSMutableDictionary *setupInfo; +@property (nonatomic, retain) NSArray *accuracyOptions; +@property (nonatomic, assign) BOOL configureForTracking; + +@property (nonatomic, retain) IBOutlet UIPickerView *accuracyPicker; +@property (nonatomic, retain) IBOutlet UISlider *slider; + +- (IBAction)done:(id)sender; +- (IBAction)sliderChangedValue:(id)sender; + +@end diff --git a/LocateMe/Classes/SetupViewController.m b/LocateMe/Classes/SetupViewController.m new file mode 100644 index 0000000..02cf3c5 --- /dev/null +++ b/LocateMe/Classes/SetupViewController.m @@ -0,0 +1,135 @@ +/* + File: SetupViewController.m + Abstract: Displayed by either a GetLocationViewController or a TrackLocationViewController, this view controller is presented modally and communicates back to the presenting controller using a simple delegate protocol. The protocol sends setupViewController:didFinishSetupWithInfo: to its delegate with a dictionary containing a desired accuracy and either a timeout or a distance filter value. A custom UIPickerView specifies the desired accuracy. A slider is shown for setting the timeout or distance filter. This view controller can be initialized using either of two nib files: GetLocationSetupView.xib or TrackLocationSetupView.xib. These nibs have nearly identical layouts, but differ in the labels and attributes for the slider. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SetupViewController.h" +#import + +NSString * const kSetupInfoKeyAccuracy = @"SetupInfoKeyAccuracy"; +NSString * const kSetupInfoKeyDistanceFilter = @"SetupInfoKeyDistanceFilter"; +NSString * const kSetupInfoKeyTimeout = @"SetupInfoKeyTimeout"; + +static NSString * const kAccuracyNameKey = @"AccuracyNameKey"; +static NSString * const kAccuracyValueKey = @"AccuracyValueKey"; + +@implementation SetupViewController + +@synthesize delegate; +@synthesize setupInfo; +@synthesize accuracyOptions; +@synthesize configureForTracking; +@synthesize accuracyPicker; +@synthesize slider; + +- (void)viewDidLoad { + NSMutableArray *options = [NSMutableArray array]; + [options addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"AccuracyBest", @"AccuracyBest"), kAccuracyNameKey, [NSNumber numberWithDouble:kCLLocationAccuracyBest], kAccuracyValueKey, nil]]; + [options addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Accuracy10", @"Accuracy10"), kAccuracyNameKey, [NSNumber numberWithDouble:kCLLocationAccuracyNearestTenMeters], kAccuracyValueKey, nil]]; + [options addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Accuracy100", @"Accuracy100"), kAccuracyNameKey, [NSNumber numberWithDouble:kCLLocationAccuracyHundredMeters], kAccuracyValueKey, nil]]; + [options addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Accuracy1000", @"Accuracy1000"), kAccuracyNameKey, [NSNumber numberWithDouble:kCLLocationAccuracyKilometer], kAccuracyValueKey, nil]]; + [options addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Accuracy3000", @"Accuracy3000"), kAccuracyNameKey, [NSNumber numberWithDouble:kCLLocationAccuracyThreeKilometers], kAccuracyValueKey, nil]]; + self.accuracyOptions = options; +} + +- (void)viewDidUnload { + self.accuracyPicker = nil; + self.slider = nil; +} + +- (void)dealloc { + [accuracyPicker release]; + [slider release]; + [setupInfo release]; + [super dealloc]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [accuracyPicker selectRow:2 inComponent:0 animated:NO]; + self.setupInfo = [NSMutableDictionary dictionary]; + [setupInfo setObject:[NSNumber numberWithDouble:100.0] forKey:kSetupInfoKeyDistanceFilter]; + [setupInfo setObject:[NSNumber numberWithDouble:30] forKey:kSetupInfoKeyTimeout]; + [setupInfo setObject:[NSNumber numberWithDouble:kCLLocationAccuracyHundredMeters] forKey:kSetupInfoKeyAccuracy]; +} + +- (IBAction)done:(id)sender { + [self dismissModalViewControllerAnimated:YES]; + if ([delegate respondsToSelector:@selector(setupViewController:didFinishSetupWithInfo:)]) { + [delegate setupViewController:self didFinishSetupWithInfo:setupInfo]; + } +} + +- (IBAction)sliderChangedValue:(id)sender { + if (configureForTracking) { + [setupInfo setObject:[NSNumber numberWithDouble:pow(10, [(UISlider *)sender value])] forKey:kSetupInfoKeyDistanceFilter]; + } else { + [setupInfo setObject:[NSNumber numberWithDouble:[(UISlider *)sender value]] forKey:kSetupInfoKeyTimeout]; + } +} + +#pragma mark Picker DataSource/Delegate + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { + return 5; +} + +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { + NSDictionary *optionForRow = [accuracyOptions objectAtIndex:row]; + return [optionForRow objectForKey:kAccuracyNameKey]; +} + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { + NSDictionary *optionForRow = [accuracyOptions objectAtIndex:row]; + [setupInfo setObject:[optionForRow objectForKey:kAccuracyValueKey] forKey:kSetupInfoKeyAccuracy]; +} + + +@end diff --git a/LocateMe/Classes/TrackLocationViewController.h b/LocateMe/Classes/TrackLocationViewController.h new file mode 100644 index 0000000..69c119d --- /dev/null +++ b/LocateMe/Classes/TrackLocationViewController.h @@ -0,0 +1,83 @@ +/* + File: TrackLocationViewController.h + Abstract: Attempts to track the user location with a specific level of accuracy. A "distance filter" indicates the smallest change in location that triggers an update from the location manager to its delegate. Presents a SetupViewController instance so the user can configure the desired accuracy and distance filter. Uses a LocationDetailViewController instance to drill down into details for a given location measurement. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import "SetupViewController.h" + +@class LocationDetailViewController; + +@interface TrackLocationViewController : UIViewController { + SetupViewController *setupViewController; + UIButton *startButton; + UILabel *descriptionLabel; + CLLocationManager *locationManager; + NSMutableArray *locationMeasurements; + UITableView *tableView; + NSDateFormatter *dateFormatter; + NSString *stateString; + LocationDetailViewController *locationDetailViewController; +} + +@property (nonatomic, retain, readonly) SetupViewController *setupViewController; +@property (nonatomic, retain) IBOutlet UIButton *startButton; +@property (nonatomic, retain) IBOutlet UILabel *descriptionLabel; +@property (nonatomic, retain) CLLocationManager *locationManager; +@property (nonatomic, retain) NSMutableArray *locationMeasurements; +@property (nonatomic, retain) IBOutlet UITableView *tableView; +@property (nonatomic, retain, readonly) NSDateFormatter *dateFormatter; +@property (nonatomic, retain) NSString *stateString; +@property (nonatomic, retain, readonly) LocationDetailViewController *locationDetailViewController; + +- (IBAction)start:(id)sender; + +- (void)setupViewController:(SetupViewController *)controller didFinishSetupWithInfo:(NSDictionary *)setupInfo; + +- (void)stopUpdatingLocation:(NSString *)state; + +@end diff --git a/LocateMe/Classes/TrackLocationViewController.m b/LocateMe/Classes/TrackLocationViewController.m new file mode 100644 index 0000000..f3c50a9 --- /dev/null +++ b/LocateMe/Classes/TrackLocationViewController.m @@ -0,0 +1,298 @@ +/* + File: TrackLocationViewController.m + Abstract: Attempts to track the user location with a specific level of accuracy. A "distance filter" indicates the smallest change in location that triggers an update from the location manager to its delegate. Presents a SetupViewController instance so the user can configure the desired accuracy and distance filter. Uses a LocationDetailViewController instance to drill down into details for a given location measurement. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TrackLocationViewController.h" +#import "LocationDetailViewController.h" +#import "CLLocation (Strings).h" + +@implementation TrackLocationViewController + +@synthesize startButton; +@synthesize descriptionLabel; +@synthesize locationManager; +@synthesize locationMeasurements; +@synthesize tableView; +@synthesize stateString; + +- (void)viewDidLoad { + self.locationMeasurements = [NSMutableArray array]; +} + +/* + * The view hierarchy for this controller has been torn down. This usually happens in response to low memory notifications. + * All IBOutlets should be released by setting their property to nil in order to free up as much memory as possible. + * This is also a good place to release other variables that can be recreated when needed. + */ +- (void)viewDidUnload { + self.startButton = nil; + self.descriptionLabel = nil; + self.stateString = nil; + self.tableView = nil; + // For the readonly properties, they must be released and set to nil directly. + [setupViewController release]; + setupViewController = nil; + [dateFormatter release]; + dateFormatter = nil; +} + +- (void)dealloc { + [stateString release]; + [descriptionLabel release]; + [dateFormatter release]; + [locationManager release]; + [startButton release]; + [setupViewController release]; + [locationMeasurements release]; + [tableView release]; + [locationDetailViewController release]; + [super dealloc]; +} + +/* + * The lazy "getter" for the readonly property. + */ +- (SetupViewController *)setupViewController { + if (setupViewController == nil) { + setupViewController = [[SetupViewController alloc] initWithNibName:@"TrackLocationSetupView" bundle:nil]; + setupViewController.delegate = self; + } + return setupViewController; +} + +/* + * The lazy "getter" for the readonly property. + */ +- (LocationDetailViewController *)locationDetailViewController { + if (locationDetailViewController == nil) { + locationDetailViewController = [[LocationDetailViewController alloc] initWithStyle:UITableViewStyleGrouped]; + } + return locationDetailViewController; +} + +/* + * The lazy "getter" for the readonly property. + */ +- (NSDateFormatter *)dateFormatter { + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterLongStyle]; + } + return dateFormatter; +} + +- (IBAction)start:(id)sender { + [self.navigationController presentModalViewController:self.setupViewController animated:YES]; +} + +/* + * The reset method allows the user to repeatedly test the location functionality. In addition to discarding all of + * the location measurements from the previous "run", it animates a transition in the user interface between the table + * which displays location data and the start button and description label presented at launch. + */ +- (void)reset { + [self.locationMeasurements removeAllObjects]; + [UIView beginAnimations:@"Reset" context:nil]; + [UIView setAnimationDuration:0.6]; + startButton.alpha = 1.0; + descriptionLabel.alpha = 1.0; + tableView.alpha = 0.0; + [self.navigationItem setLeftBarButtonItem:nil animated:YES];; + [UIView commitAnimations]; +} + +#pragma mark Location Manager Interactions + +/* + * This method is invoked when the user hits "Done" in the setup view controller. The options chosen by the user are + * passed in as a dictionary. The keys for this dictionary are declared in SetupViewController.h. + */ +- (void)setupViewController:(SetupViewController *)controller didFinishSetupWithInfo:(NSDictionary *)setupInfo { + startButton.alpha = 0.0; + descriptionLabel.alpha = 0.0; + tableView.alpha = 1.0; + // Create the manager object + self.locationManager = [[[CLLocationManager alloc] init] autorelease]; + locationManager.delegate = self; + // This is the most important property to set for the manager. It ultimately determines how the manager will + // attempt to acquire location and thus, the amount of power that will be consumed. + locationManager.desiredAccuracy = [[setupInfo objectForKey:kSetupInfoKeyAccuracy] doubleValue]; + // When "tracking" the user, the distance filter can be used to control the frequency with which location measurements + // are delivered by the manager. If the change in distance is less than the filter, a location will not be delivered. + locationManager.distanceFilter = [[setupInfo objectForKey:kSetupInfoKeyDistanceFilter] doubleValue]; + // Once configured, the location manager must be "started". + [locationManager startUpdatingLocation]; + self.stateString = NSLocalizedString(@"Tracking", @"Tracking"); + [self.tableView reloadData]; + UIBarButtonItem *resetItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Reset", @"Reset") style:UIBarButtonItemStyleBordered target:self action:@selector(reset)] autorelease]; + [self.navigationItem setLeftBarButtonItem:resetItem animated:YES];; +} + +/* + * We want to get and store a location measurement that meets the desired accuracy. For this example, we are + * going to use horizontal accuracy as the deciding factor. In other cases, you may wish to use vertical + * accuracy, or both together. + */ +- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { + // test that the horizontal accuracy does not indicate an invalid measurement + if (newLocation.horizontalAccuracy < 0) return; + // test the age of the location measurement to determine if the measurement is cached + // in most cases you will not want to rely on cached measurements + NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; + if (locationAge > 5.0) return; + // store all of the measurements, just so we can see what kind of data we might receive + [locationMeasurements addObject:newLocation]; + // update the display with the new location data + [self.tableView reloadData]; +} + +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { + // The location "unknown" error simply means the manager is currently unable to get the location. + if ([error code] != kCLErrorLocationUnknown) { + [self stopUpdatingLocation:NSLocalizedString(@"Error", @"Error")]; + } +} + +- (void)stopUpdatingLocation:(NSString *)state { + self.stateString = state; + [self.tableView reloadData]; + [locationManager stopUpdatingLocation]; + locationManager.delegate = nil; +} + +#pragma mark Table View DataSource/Delegate + +// The table view has two sections. The first has 1 row which displays status information. The second has a row for each valid location object received from the location manager. + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)table { + return (self.locationMeasurements.count > 0) ? 2 : 1; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + switch (section) { + case 0: { + return NSLocalizedString(@"Status", @"Status"); + } break; + default: { + return NSLocalizedString(@"All Measurements", @"All Measurements"); + } break; + } +} + +- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section { + switch (section) { + case 0: { + return 1; + } break; + default: { + return locationMeasurements.count; + } break; + } +} + +- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath { + switch (indexPath.section) { + case 0: { + // The cell for the status row uses the cell style "UITableViewCellStyleValue1", which has a label on the left side of the cell with left-aligned and black text; on the right side is a label that has smaller blue text and is right-aligned. An activity indicator has been added to the cell and is animated while the location manager is updating. The cell's text label displays the current state of the manager. + static NSString * const kStatusCellID = @"StatusCellID"; + static NSInteger const kStatusCellActivityIndicatorTag = 2; + UIActivityIndicatorView *activityIndicator = nil; + UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:kStatusCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kStatusCellID] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; + CGRect frame = activityIndicator.frame; + frame.origin = CGPointMake(290, 12); + activityIndicator.frame = frame; + activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + activityIndicator.tag = kStatusCellActivityIndicatorTag; + [cell.contentView addSubview:activityIndicator]; + } else { + activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:kStatusCellActivityIndicatorTag]; + } + cell.textLabel.text = stateString; + if ([stateString isEqualToString:NSLocalizedString(@"Tracking", @"Tracking")]) { + if (activityIndicator.isAnimating == NO) [activityIndicator startAnimating]; + } else { + if (activityIndicator.isAnimating) [activityIndicator stopAnimating]; + } + return cell; + } break; + default: { + // The cells for the location rows use the cell style "UITableViewCellStyleSubtitle", which has a left-aligned label across the top and a left-aligned label below it in smaller gray text. The text label shows the coordinates for the location and the detail text label shows its timestamp. + static NSString * const kOtherMeasurementsCellID = @"OtherMeasurementsCellID"; + UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:kOtherMeasurementsCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kOtherMeasurementsCellID] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + CLLocation *location = [locationMeasurements objectAtIndex:indexPath.row]; + cell.textLabel.text = location.localizedCoordinateString; + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:location.timestamp]; + return cell; + } break; + } +} + +// Delegate method invoked before the user selects a row. In this sample, we use it to prevent selection in the +// first section of the table view. +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + return (indexPath.section == 0) ? nil : indexPath; +} + +// Delegate method invoked after the user selects a row. Selecting a row containing a location object +// will navigate to a new view controller displaying details about that location. +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + CLLocation *location = [locationMeasurements objectAtIndex:indexPath.row]; + self.locationDetailViewController.location = location; + [self.navigationController pushViewController:locationDetailViewController animated:YES]; +} + +@end diff --git a/LocateMe/Info.plist b/LocateMe/Info.plist new file mode 100644 index 0000000..f61b29c --- /dev/null +++ b/LocateMe/Info.plist @@ -0,0 +1,39 @@ + + + + + UIStatusBarStyle + UIStatusBarStyleOpaqueBlack + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon-72.png + Icon@2x.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/LocateMe/LocateMe.xcodeproj/project.pbxproj b/LocateMe/LocateMe.xcodeproj/project.pbxproj new file mode 100644 index 0000000..cc07bb0 --- /dev/null +++ b/LocateMe/LocateMe.xcodeproj/project.pbxproj @@ -0,0 +1,406 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28216C970DB411BC00E5133A /* GetLocationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28216C960DB411BC00E5133A /* GetLocationViewController.m */; }; + 288765080DF74369002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765070DF74369002DB57D /* CoreGraphics.framework */; }; + 308C9F970FB0DF430082C99D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 308C9F950FB0DF430082C99D /* Localizable.strings */; }; + 308C9FD50FB0E2B40082C99D /* TrackLocationView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 308C9FCB0FB0E2B40082C99D /* TrackLocationView.xib */; }; + 308C9FD60FB0E2B40082C99D /* TrackLocationSetupView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 308C9FCD0FB0E2B40082C99D /* TrackLocationSetupView.xib */; }; + 308C9FD70FB0E2B40082C99D /* GetLocationSetupView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 308C9FCF0FB0E2B40082C99D /* GetLocationSetupView.xib */; }; + 308C9FD80FB0E2B40082C99D /* GetLocationView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 308C9FD10FB0E2B40082C99D /* GetLocationView.xib */; }; + 308C9FD90FB0E2B40082C99D /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 308C9FD30FB0E2B40082C99D /* MainWindow.xib */; }; + 308CA1F80FB2504E0082C99D /* LocationDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 308CA1F70FB2504E0082C99D /* LocationDetailViewController.m */; }; + 308CA2990FB25A390082C99D /* CLLocation (Strings).m in Sources */ = {isa = PBXBuildFile; fileRef = 308CA2980FB25A390082C99D /* CLLocation (Strings).m */; }; + 30AE77890FB091FC000B9BFA /* TrackLocationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30AE77880FB091FC000B9BFA /* TrackLocationViewController.m */; }; + 30AE778D0FB0924C000B9BFA /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30AE778C0FB0924C000B9BFA /* CoreLocation.framework */; }; + 30AE77B20FB093C9000B9BFA /* SetupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30AE77B10FB093C9000B9BFA /* SetupViewController.m */; }; + 30E6E8FA0FB4B4B600B1F677 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 30E6E8F90FB4B4B600B1F677 /* ReadMe.txt */; }; + CB6C7D5911D5492C00AC7FA8 /* bullseye.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5011D5492C00AC7FA8 /* bullseye.png */; }; + CB6C7D5A11D5492C00AC7FA8 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5111D5492C00AC7FA8 /* Default.png */; }; + CB6C7D5B11D5492C00AC7FA8 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5211D5492C00AC7FA8 /* Icon-72.png */; }; + CB6C7D5C11D5492C00AC7FA8 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5311D5492C00AC7FA8 /* Icon-Small-50.png */; }; + CB6C7D5D11D5492C00AC7FA8 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5411D5492C00AC7FA8 /* Icon-Small.png */; }; + CB6C7D5E11D5492C00AC7FA8 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5511D5492C00AC7FA8 /* Icon-Small@2x.png */; }; + CB6C7D5F11D5492C00AC7FA8 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5611D5492C00AC7FA8 /* Icon.png */; }; + CB6C7D6011D5492C00AC7FA8 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5711D5492C00AC7FA8 /* Icon@2x.png */; }; + CB6C7D6111D5492C00AC7FA8 /* pin.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D5811D5492C00AC7FA8 /* pin.png */; }; + CB6C7D6311D5493400AC7FA8 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D6211D5493400AC7FA8 /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* LocateMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LocateMe.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28216C950DB411BC00E5133A /* GetLocationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetLocationViewController.h; sourceTree = ""; }; + 28216C960DB411BC00E5133A /* GetLocationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GetLocationViewController.m; sourceTree = ""; }; + 288765070DF74369002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AB4B0D9B1048005BE974 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 308C9F960FB0DF430082C99D /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 308C9FCC0FB0E2B40082C99D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TrackLocationView.xib; sourceTree = ""; }; + 308C9FCE0FB0E2B40082C99D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TrackLocationSetupView.xib; sourceTree = ""; }; + 308C9FD00FB0E2B40082C99D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/GetLocationSetupView.xib; sourceTree = ""; }; + 308C9FD20FB0E2B40082C99D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/GetLocationView.xib; sourceTree = ""; }; + 308C9FD40FB0E2B40082C99D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 308CA1F60FB2504E0082C99D /* LocationDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocationDetailViewController.h; sourceTree = ""; }; + 308CA1F70FB2504E0082C99D /* LocationDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocationDetailViewController.m; sourceTree = ""; }; + 308CA2970FB25A390082C99D /* CLLocation (Strings).h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CLLocation (Strings).h"; sourceTree = ""; }; + 308CA2980FB25A390082C99D /* CLLocation (Strings).m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CLLocation (Strings).m"; sourceTree = ""; }; + 30AE77870FB091FC000B9BFA /* TrackLocationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackLocationViewController.h; sourceTree = ""; }; + 30AE77880FB091FC000B9BFA /* TrackLocationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TrackLocationViewController.m; sourceTree = ""; }; + 30AE778C0FB0924C000B9BFA /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 30AE77B00FB093C9000B9BFA /* SetupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetupViewController.h; sourceTree = ""; }; + 30AE77B10FB093C9000B9BFA /* SetupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SetupViewController.m; sourceTree = ""; }; + 30E6E8F90FB4B4B600B1F677 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + CB6C7D5011D5492C00AC7FA8 /* bullseye.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bullseye.png; sourceTree = ""; }; + CB6C7D5111D5492C00AC7FA8 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + CB6C7D5211D5492C00AC7FA8 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + CB6C7D5311D5492C00AC7FA8 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + CB6C7D5411D5492C00AC7FA8 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + CB6C7D5511D5492C00AC7FA8 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + CB6C7D5611D5492C00AC7FA8 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + CB6C7D5711D5492C00AC7FA8 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + CB6C7D5811D5492C00AC7FA8 /* pin.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pin.png; sourceTree = ""; }; + CB6C7D6211D5493400AC7FA8 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765080DF74369002DB57D /* CoreGraphics.framework in Frameworks */, + 30AE778D0FB0924C000B9BFA /* CoreLocation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 28216C950DB411BC00E5133A /* GetLocationViewController.h */, + 28216C960DB411BC00E5133A /* GetLocationViewController.m */, + 30AE77870FB091FC000B9BFA /* TrackLocationViewController.h */, + 30AE77880FB091FC000B9BFA /* TrackLocationViewController.m */, + 30AE77B00FB093C9000B9BFA /* SetupViewController.h */, + 30AE77B10FB093C9000B9BFA /* SetupViewController.m */, + 308CA1F60FB2504E0082C99D /* LocationDetailViewController.h */, + 308CA1F70FB2504E0082C99D /* LocationDetailViewController.m */, + 308CA2970FB25A390082C99D /* CLLocation (Strings).h */, + 308CA2980FB25A390082C99D /* CLLocation (Strings).m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* LocateMe.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* LocateMe */ = { + isa = PBXGroup; + children = ( + 30E6E8F90FB4B4B600B1F677 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = LocateMe; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AB4B0D9B1048005BE974 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + CB6C7D4F11D5492C00AC7FA8 /* images */, + 8D1107310486CEB800E47090 /* Info.plist */, + 308C9F950FB0DF430082C99D /* Localizable.strings */, + 308C9FD30FB0E2B40082C99D /* MainWindow.xib */, + 308C9FD10FB0E2B40082C99D /* GetLocationView.xib */, + 308C9FCF0FB0E2B40082C99D /* GetLocationSetupView.xib */, + 308C9FCB0FB0E2B40082C99D /* TrackLocationView.xib */, + 308C9FCD0FB0E2B40082C99D /* TrackLocationSetupView.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765070DF74369002DB57D /* CoreGraphics.framework */, + 30AE778C0FB0924C000B9BFA /* CoreLocation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CB6C7D4F11D5492C00AC7FA8 /* images */ = { + isa = PBXGroup; + children = ( + CB6C7D6211D5493400AC7FA8 /* iTunesArtwork */, + CB6C7D5011D5492C00AC7FA8 /* bullseye.png */, + CB6C7D5111D5492C00AC7FA8 /* Default.png */, + CB6C7D5211D5492C00AC7FA8 /* Icon-72.png */, + CB6C7D5311D5492C00AC7FA8 /* Icon-Small-50.png */, + CB6C7D5411D5492C00AC7FA8 /* Icon-Small.png */, + CB6C7D5511D5492C00AC7FA8 /* Icon-Small@2x.png */, + CB6C7D5611D5492C00AC7FA8 /* Icon.png */, + CB6C7D5711D5492C00AC7FA8 /* Icon@2x.png */, + CB6C7D5811D5492C00AC7FA8 /* pin.png */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* LocateMe */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "LocateMe" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LocateMe; + productName = LocateMe; + productReference = 1D6058910D05DD3D006BFB54 /* LocateMe.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "LocateMe" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* LocateMe */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* LocateMe */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 308C9F970FB0DF430082C99D /* Localizable.strings in Resources */, + 308C9FD50FB0E2B40082C99D /* TrackLocationView.xib in Resources */, + 308C9FD60FB0E2B40082C99D /* TrackLocationSetupView.xib in Resources */, + 308C9FD70FB0E2B40082C99D /* GetLocationSetupView.xib in Resources */, + 308C9FD80FB0E2B40082C99D /* GetLocationView.xib in Resources */, + 308C9FD90FB0E2B40082C99D /* MainWindow.xib in Resources */, + 30E6E8FA0FB4B4B600B1F677 /* ReadMe.txt in Resources */, + CB6C7D5911D5492C00AC7FA8 /* bullseye.png in Resources */, + CB6C7D5A11D5492C00AC7FA8 /* Default.png in Resources */, + CB6C7D5B11D5492C00AC7FA8 /* Icon-72.png in Resources */, + CB6C7D5C11D5492C00AC7FA8 /* Icon-Small-50.png in Resources */, + CB6C7D5D11D5492C00AC7FA8 /* Icon-Small.png in Resources */, + CB6C7D5E11D5492C00AC7FA8 /* Icon-Small@2x.png in Resources */, + CB6C7D5F11D5492C00AC7FA8 /* Icon.png in Resources */, + CB6C7D6011D5492C00AC7FA8 /* Icon@2x.png in Resources */, + CB6C7D6111D5492C00AC7FA8 /* pin.png in Resources */, + CB6C7D6311D5493400AC7FA8 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 28216C970DB411BC00E5133A /* GetLocationViewController.m in Sources */, + 30AE77890FB091FC000B9BFA /* TrackLocationViewController.m in Sources */, + 30AE77B20FB093C9000B9BFA /* SetupViewController.m in Sources */, + 308CA1F80FB2504E0082C99D /* LocationDetailViewController.m in Sources */, + 308CA2990FB25A390082C99D /* CLLocation (Strings).m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 308C9F950FB0DF430082C99D /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 308C9F960FB0DF430082C99D /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 308C9FCB0FB0E2B40082C99D /* TrackLocationView.xib */ = { + isa = PBXVariantGroup; + children = ( + 308C9FCC0FB0E2B40082C99D /* en */, + ); + name = TrackLocationView.xib; + sourceTree = ""; + }; + 308C9FCD0FB0E2B40082C99D /* TrackLocationSetupView.xib */ = { + isa = PBXVariantGroup; + children = ( + 308C9FCE0FB0E2B40082C99D /* en */, + ); + name = TrackLocationSetupView.xib; + sourceTree = ""; + }; + 308C9FCF0FB0E2B40082C99D /* GetLocationSetupView.xib */ = { + isa = PBXVariantGroup; + children = ( + 308C9FD00FB0E2B40082C99D /* en */, + ); + name = GetLocationSetupView.xib; + sourceTree = ""; + }; + 308C9FD10FB0E2B40082C99D /* GetLocationView.xib */ = { + isa = PBXVariantGroup; + children = ( + 308C9FD20FB0E2B40082C99D /* en */, + ); + name = GetLocationView.xib; + sourceTree = ""; + }; + 308C9FD30FB0E2B40082C99D /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 308C9FD40FB0E2B40082C99D /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = LocateMe; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = LocateMe; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "LocateMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "LocateMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/LocateMe/Prefix.pch b/LocateMe/Prefix.pch new file mode 100644 index 0000000..bfbc300 --- /dev/null +++ b/LocateMe/Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'LocateMe' target in the 'LocateMe' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/LocateMe/ReadMe.txt b/LocateMe/ReadMe.txt new file mode 100644 index 0000000..115c378 --- /dev/null +++ b/LocateMe/ReadMe.txt @@ -0,0 +1,68 @@ +LocateMe + +================================================================================ +ABSTRACT: + +This demonstrates the two primary use cases for the Core Location Framework: getting the user's location and tracking changes to the user's location. Developers should read the class reference documentation for CLLocationManager, CLLocationManagerDelegate, and CLLocation for detailed information about the Core Location framework. In addition, the iPhone Application Programming Guide has a section under "Device Support", titled "Getting the User's Current Location", which discusses best practices for using this framework. + +Important Considerations: + +• Core Location does not guarantee that a measurement matching the desiredAccuracy will be delivered. Rather, a best effort is made, and may be constrained both by the capabilities of the device and the location and environment from which it is used. For example, a first generation iPod touch may only be able to provide location via WiFi triangulation, which in turn might give better than 100-meter accuracy. However, used in a location which lacks WiFi hotspots, no location at all could be acquired. Similarly, a GPS equiped device will often provide better than 10-meter accuracy, but not underground. Your code should be prepared to handle any of these possibilities. In particular, a timeout should be used to stop updating the location manager even if a measurement meeting the desired is not received. A reasonable timeout is around 30 seconds. + +• Core Location caches location data, so it is typical that the first measurement the location manager's delegate receives is "stale". You should always check the timestamp on measurement objects to determine if they are likely to be out-of-date. + +• When tracking changes to the user's location, the distanceFilter property can be used to filter out update messages from the location manager to it's delegate. However, such messages may still be delivered if more accurate measurements are acquired. Also, the distanceFilter does not impact the hardware's activity - i.e., there is no savings of power by setting a larger distanceFilter because the hardware continues to acquire measurements. This simply affects whether those measurements are passed on to the location manager's delegate. Power can only be saved by turning off the location manager. + +What to Look For in this Project: + +The most important location handling code is in the GetLocationViewController and TrackLocationViewController. "#pragma mark Location Manager Interactions" is used to demarcate the specific sections that create, configure, start, and stop the manager, and where its delegate methods are implemented. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 or later + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +AppDelegate +The application delegate has a minimal role in this sample: in -applicationDidFinishLaunching: it adds the tab bar controller's view to the window. It also creates a CLLocationManager object to check the locationServicesEnabled property at launch time. + +GetLocationViewController +Attempts to acquire a location measurement with a specific level of accuracy. A timeout is used to avoid wasting power in the case where a sufficiently accurate measurement cannot be acquired. Presents a SetupViewController instance so the user can configure the desired accuracy and timeout. Uses a LocationDetailViewController instance to drill down into details for a given location measurement. + +TrackLocationViewController +Attempts to track the user location with a specific level of accuracy. A "distance filter" indicates the smallest change in location that triggers an update from the location manager to its delegate. Presents a SetupViewController instance so the user can configure the desired accuracy and distance filter. Uses a LocationDetailViewController instance to drill down into details for a given location measurement. + +SetupViewController +Displayed by either a GetLocationViewController or a TrackLocationViewController, this view controller is presented modally and communicates back to the presenting controller using a simple delegate protocol. The protocol sends setupViewController:didFinishSetupWithInfo: to its delegate with a dictionary containing a desired accuracy and either a timeout or a distance filter value. A custom UIPickerView specifies the desired accuracy. A slider is shown for setting the timeout or distance filter. This view controller can be initialized using either of two nib files: GetLocationSetupView.xib or TrackLocationSetupView.xib. These nibs have nearly identical layouts, but differ in the labels and attributes for the slider. + +LocationDetailViewController +Shows all of the properties of a CLLocation object in a table view. Uses the CLLocation (Strings) category to present the information as localized strings. + +CLLocation (Strings) +This is an Objective C category on the CLLocation class that extends the class by adding some convenience methods for presenting localized string representations of various properties. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 2.2 +- Updated for iOS 4.0. + +Version 2.0 +- Complete rewrite to focus separately on two primary use cases - getting a single location and tracking location changes. + +Version 1.1 +- Updated for and tested with iPhone OS 2.0. First public release. +- Fixed date error. + +Version 1.0 +- First version. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/LocateMe/en.lproj/GetLocationSetupView.xib b/LocateMe/en.lproj/GetLocationSetupView.xib new file mode 100644 index 0000000..31a6f61 --- /dev/null +++ b/LocateMe/en.lproj/GetLocationSetupView.xib @@ -0,0 +1,486 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 290 + {320, 44} + + NO + NO + 1 + + YES + + + Configure + + 1 + 0 + + + + + + + 292 + {{0, 79}, {320, 216}} + + NO + YES + YES + YES + + + + 292 + {{20, 50}, {151, 21}} + + + 1 + MCAwIDAAA + + NO + YES + NO + Desired Accuracy: + + Helvetica-Bold + 1.700000e+01 + 16 + + + 1 + MSAxIDEAA + + + 1 + 1.000000e+01 + + + + 292 + {{20, 328}, {158, 21}} + + + NO + YES + NO + Timeout (seconds): + + + + 1 + 1.000000e+01 + + + + 292 + {{18, 370}, {284, 23}} + + NO + YES + YES + 0 + 0 + 4.500000e+01 + 1.500000e+01 + 6.000000e+01 + + + + 292 + {{284, 400}, {16, 18}} + + NO + YES + NO + 60 + + Helvetica + 1.400000e+01 + 16 + + + 1 + MSAxIDEAA + + 1 + + + + 1 + 1.000000e+01 + + + + 292 + {{196, 400}, {16, 18}} + + NO + YES + NO + 45 + + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{108, 400}, {16, 18}} + + NO + YES + NO + 30 + + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{20, 400}, {16, 18}} + + NO + YES + NO + 15 + + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + {320, 460} + + + + + + + + YES + + + view + + + + 7 + + + + done: + + + + 8 + + + + accuracyPicker + + + + 19 + + + + dataSource + + + + 20 + + + + delegate + + + + 21 + + + + slider + + + + 22 + + + + sliderChangedValue: + + + 13 + + 23 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 3 + + + YES + + + + + + 4 + + + YES + + + + + + 5 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 3.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + + + YES + SetupViewController + UIResponder + {{174, 412}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 23 + + + + YES + + SetupViewController + UIViewController + + YES + + YES + done: + sliderChangedValue: + + + YES + id + id + + + + YES + + YES + accuracyPicker + delegate + slider + + + YES + UIPickerView + id + UISlider + + + + IBProjectSource + Classes/SetupViewController.h + + + + + 0 + ../LocateMe.xcodeproj + 3 + 3.0 + + diff --git a/LocateMe/en.lproj/GetLocationView.xib b/LocateMe/en.lproj/GetLocationView.xib new file mode 100644 index 0000000..004a1e3 --- /dev/null +++ b/LocateMe/en.lproj/GetLocationView.xib @@ -0,0 +1,406 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 460} + + NO + YES + NO + 0.000000e+00 + NO + 1 + 1 + 0 + YES + 4.400000e+01 + 1.000000e+01 + 1.000000e+01 + + + + 290 + {{7, 30}, {306, 150}} + + NO + YES + NO + This approach attempts to acquire a location measurement that meets a minimum accuracy. A timeout is specified to avoid unnecessarily wasting power, in case a sufficiently accurate measurement cannot be acquired. + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + 19 + 1 + + + + 293 + {{124, 195}, {72, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + Start + + 3 + MQA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MC41AA + + + + {320, 460} + + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADgEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAACBgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAYYAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAIAAAFTAAMAAAAEAAACDodzAAcAAA/IAAACFgAAAAAACAAIAAgACAABAAEAAQABAAAPyGFw +cGwCAAAAbW50clJHQiBYWVogB9kAAgAXAA8AGAALYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAPbWAAEAAAAA0y1hcHBsaphmZhHvpWo5EzFmkmxXQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA +AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAYSbmRpbgAA +B+wAAAY+ZGVzYwAADiwAAABfZHNjbQAADowAAADwbW1vZAAAD3wAAAAoY3BydAAAD6QAAAAkWFlaIAAA +AAAAAHWbAAA+zQAAAhxYWVogAAAAAAAAWoMAAKx/AAAULFhZWiAAAAAAAAAmuAAAFM4AALzdWFlaIAAA +AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 +cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD +AQAAAgAAAUwCNgMWBCkFagbECDsJxQtdDQgOrhBgEhETvhViFw0YpRo1G7MdJh5lH5ogzSIAIzokeSWz +Ju8oMSlvKqsr5y0jLlovjTC6MegzDzQzNVY2bjeTOL857jsYPEM9Zz6HP6VAv0HWQutD+kUIRhBHFUga +SR1KHEsdTBhNF04XTyhQP1FSUmRTd1SHVZRWoVesWLdZwVrMW9dc413vXv1gDWEdYi1jQGRSZVVmUGdM +aEVpQGo/azxsOG03bjdvOHA7cT5yRnNQdFp1ZnZ4d4l4mXmoeq57qnyifZ1+mH+cgJuBnoKig6eEq4Wu +hq2HrYiviamKpYucjJCNg45yj2aQa5FuknOTdpR3lXSWbpdpmF+ZU5pGmzicJ50Tnf6e6Z/ToLmhn6KI +o3OkcKVvpm6nbqhrqWeqYqtbrFOtTK5Frz6wN7EwsimzJLQftRy2G7cauBG4+LnPuqC7dLxHvRm97L6/ +v5TAbMFEwh3C+cPWxLXFlMZ2x1nIP8knyg3K68u/zJDNY845zxHP6tDG0Z/SfdNb1DjVFdXw1srXo9h6 +2VDaJNr128Pcl9113lbfN+AW4PTh0OKo43/kVeUq5fvmyueX6GPpLun46sPri+xU7Rzt5e7C76HwgPFd +8jnzFvPw9Mf1nvZ090n4Hfju+cL6lvto/Dz9Ev3n/rz/Z///AAABHAHfAq4DrwTaBiEHjQkICpwMOA3n +D5QRQRLtFJYWNRfKGU4awRwlHVwehx+vIN0iDiNCJHAloibXKAwpPypvK54szC30LxcwPjFaMnMzijSe +Nbc21zf6ORc6NztQPGU9eT6HP5RAn0GmQqlDqUSnRaNGn0eZSJJJiEqAS3pMhk2WTqNPr1C7UcRSy1PQ +VNVV2FbbV95Y4FnkWudb7Fz0XfxfA2ANYRNiC2L6Y+hk1mXFZrZnp2iXaYlqfWtzbGltYG5cb1lwVnFW +cltzYHRjdWZ2YndReEF5Mnonex98GH0SfhB/D4ANgQqCBYMBg/yE9IXrht+H0Ii/iayKmougjJ+Noo6h +j6CQm5GSkouTfpRwlWGWUJc+mCqZE5n9muebzZyznZ2ehp+EoIKhgKJ/o3ukd6VxpmmnYKhYqU+qR6s+ +rDWtLa4lrx6wGLEUsg+zBbPstMW1mLZvt0W4G7jxuci6ort+vFu9Or4bvv+/48DIwbTCnMOIxHjFZsZK +xybIAMjZybrKmst8zGDNRM4rzxPP+tDj0cjSrtOS1HXVV9Y21xTX79jM2cDastum3Jbdht5031/gSOEx +4hji++Pe5L3lneZ751noN+kU6e/qzeuu7KHtnO6W747whvF98nLzZPRW9Uf2Nvck+BD4/vns+tj7xfy1 +/aX+lP9a//8AAACDAXgCegOiBOgGQwe4CT4KzwxlDf8PmRErEroUPxWuFyEYdxnCGv8cOh1oHpYfySD8 +IjAjXiSKJbcm4igKKTAqTStoLHwtiy6WL54woTGgMp4znDSdNZ82oDedOJk5kjqIO3s8bD1ZPkU/LUAT +QPVB10K6Q51EfkVcRj9HIEgNSP1J7ErbS8pMt02kTpBPelBlUU9SOlMkVBBU/VXsVt1XzVi+WbBanluD +XF1dOF4SXu5fzWCtYY9icmNYZEBlK2YYZwdn+mjuaeVq3mvYbNJtzG7Eb7pwrnGlcp5zm3SZdZt2nnei +eKd5qXqqe6p8q32ofqR/nICPgYOCcYNihFuFUYZJhz6IMYkhig+K+ovjjMqNro6Qj3CQTJEokgKS3JOz +lIqVY5ZBlyWYDpj4meGayZuvnJadeZ5dn0GgJaEJoe6i06O6pKCliaZzp16oSakvqg6q5au2rI2tYa42 +rwyv5LC+sZyyerNctEG1J7YPtvm357jUucO6uLuqvI69ab5Bvxu/9sDTwbHCkcNwxFHFMcYSxvHH0Mir +yYXKXcs0zAjM282qzoPPZ9BQ0TrSJNMN0/TU2NW61p3Xfthc2TnaFdrw28ncod163lLfKeAB4NnhyuK9 +463kluV/5mjnVOhD6TfqNOs+7Fftge688A/xlfNC9Sj3a/of/XH//wAAbmRpbgAAAAAAAAY2AACjZwAA +WDEAAEyRAACdDgAAJkwAABMcAABQDQAAVDkAAi4UAAIMzAABzMwAAwEAAAIAAAABAAgAFQAjADEAQQBR +AGIAcwCGAJkArQDBANcA7QEEARwBNQFPAWoBhwGkAcIB4gIEAicCTAJ0Ap0CzgMCAzkDcQOrA+UEHwRd +BJsE2wUbBV0FoQXnBi4GdwbCBw8HYAeyCAYIXgi4CRMJdQnUCjMKkQrxC1ULuQwhDIwM+Q1pDd0OUg7L +D0gPxxBLENIRWxHnEncTCBOfFDQUyxVYFeYWeBcMF6EYORjVGXIaEhq1G1kb/xynHU8d+R6lH1Ef/SCr +IVsiCiK8I3skQSUIJdMmnidoKDYpBinVKqUrdixILRst6y68L48wYTExMgMy1zOtNIo1dDZkN1M4RDku +Oh87DTv8POw93j7TP81AyUHDQshDzETXRehG/EgWSSxKLks5TEFNT05fT3ZQklGuUtNT+1UnVlZXi1jH +WgRbQ1yLXdVfHGBiYY5iwGPxZSRmXWeXaNZqGWtdbKJt6m8ycH1xyXMVdGJ1r3b7eEd5l3r/fI5+LX/H +gWiDCoSthk6H7YmNiyqMxY5fj/uRkJMplLyWTZfxmbCbdp05nvWgs6JspCul4qeeqVyrIKzprriwi7Jm +tEm2ObgaueK7q71+v1HBLcMVxQHG8cjtyvHM/s8Q0SrTQ9Vm14rZsduk3ZbfjeGK44jljued6bDrx+3l +8AvyLfRT9n74ovrK/PT//wAAAAIADAAbACoAOgBLAFwAbgCBAJQAqAC9ANIA6AD/ARcBMAFKAWUBgQGe +Ab0B3QH/AiMCSQJyAp0CzwMFAz4DeAOzA+8ELARsBK0E7wUyBXcFvgYHBlIGngbtBz8HlAfpCEMIoAj+ +CWEJxAonCokK7QtVC70MKQyZDQoNgA34DnMO8Q9zD/kQghEOEZ0SLhLCE1sT9BSQFSIVsxZHFt4XdhgR +GLAZURn1GpsbRBvvHJsdSh35HqsfXCAOIMIheCItIukjtCSFJVkmLicDJ9ootCmOKmgrQywfLPwt1y6y +L5AwbDFGMiIzATPiNMw1xDa9N7U4rDmhOpg7jjyDPXo+cz9wQHBBb0J0Q35EikWdRrRH0EjvSfNLAUwL +TRxOLk9GUGVRg1KrU9RVA1Y0V2lYplnlWyNca121XvtgRGFxYqNj1mUJZkNnfmi9agFrR2yNbddvIXBu +cb1zDHRcdax2/HhNeaF7C3yYfjF/xYFfgvuEloYvh8WJW4rujH+ODo+gkSaStpQ+lcKXUJj3mqucY54N +n7mhZKMOpLamXagGqa+rX60SrsmwhLJGtA214LeuuVK6/byjvljACcHFw4nFTccXyOvKw8ykzoXQb9JY +1ETWOdgq2hLb0N2L30rhEOLV5J/mcOhG6h/r/e3e78jxrvOV9YT3b/lW+0P9MP//AAAABgAQAB0AKgA5 +AEkAWQBrAH0AkACkALkAzwDmAP4BFwEyAU4BawGKAawBzwHzAhsCRgJzAqQC1gMMA0QDfQO3A/MEMARw +BLIE9gU7BYMFzQYZBmkGuwcRB2oHxwgnCIoI8glcCckKNwqmCxcLjAwEDH8M/g2BDgcOkg8gD7MQShDm +EYQSJBLIE3EUGRTFFWgWDha2F2EYDhi/GXIaKRriG54cWx0bHdsenR9fICIg6CGuIngjTCQvJRQl/Cbj +J8oosimbKoIraixRLTcuHS8CL+cwzDGwMpYzfjRpNVk2TDdAODM5IzoVOwU79TzlPdc+zD/FQMBBu0K9 +Q8FEy0XcRu9ICkkkSjVLTUxkTYFOok/KUPZSKFNfVJtV31cmWHZZylsgXH9d4F8/YJdh5mMyZIFl1Gcr +aIVp5WtGbKpuD291cN1yRHOudRZ2fXfleVB6yHxUffF/h4Ekgr+EWoXzh4aJGYqnjDONvY9HkMqSUZPV +lVOW1ph1mimb4p2Wn0mg/KKtpGGmFKfKqYOrQa0IrtSwprKAtGG2Tbghud27lb1RvxDA1MKgxHLGRMgf +ygHL6c3Uz8fRvdO01bDXrtmt23fdQN8U4Pbi2uS75pjocOo46+7tj+8c8Jbx//NW9If1qfa697T4pfl5 ++kb6/vun/FD82/1i/en+iP9E//8AAGRlc2MAAAAAAAAABWlNYWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1s +dWMAAAAAAAAAEgAAAAxuYk5PAAAACAAAAOhwdFBUAAAACAAAAOhzdlNFAAAACAAAAOhmaUZJAAAACAAA +AOhkYURLAAAACAAAAOh6aENOAAAACAAAAOhmckZSAAAACAAAAOhqYUpQAAAACAAAAOhlblVTAAAACAAA +AOhwbFBMAAAACAAAAOhwdEJSAAAACAAAAOhlc0VTAAAACAAAAOh6aFRXAAAACAAAAOhydVJVAAAACAAA +AOhrb0tSAAAACAAAAOhkZURFAAAACAAAAOhubE5MAAAACAAAAOhpdElUAAAACAAAAOgAaQBNAGEAY21t +b2QAAAAAAAAGEAAAnGwAAAAAwbTFAAAAAAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBs +ZSwgSW5jLiwgMjAwOQA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + + + + + YES + + + start: + + + 7 + + 9 + + + + startButton + + + + 10 + + + + tableView + + + + 12 + + + + dataSource + + + + 13 + + + + delegate + + + + 14 + + + + descriptionLabel + + + + 20 + + + + view + + + + 22 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 21 + + + YES + + + + + + + + 11 + + + + + 19 + + + + + 8 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 19.IBEditorWindowLastContentRect + 19.IBPluginDependency + 21.IBEditorWindowLastContentRect + 21.IBPluginDependency + 8.IBPluginDependency + + + YES + GetLocationViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{14, 995}, {300, 150}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{14, 685}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 22 + + + + YES + + GetLocationViewController + UIViewController + + start: + id + + + YES + + YES + descriptionLabel + startButton + tableView + + + YES + UILabel + UIButton + UITableView + + + + IBProjectSource + Classes/GetLocationViewController.h + + + + + 0 + ../LocateMe.xcodeproj + 3 + 3.0 + + diff --git a/LocateMe/en.lproj/Localizable.strings b/LocateMe/en.lproj/Localizable.strings new file mode 100644 index 0000000..d4dcd0f Binary files /dev/null and b/LocateMe/en.lproj/Localizable.strings differ diff --git a/LocateMe/en.lproj/MainWindow.xib b/LocateMe/en.lproj/MainWindow.xib new file mode 100644 index 0000000..b3c7883 --- /dev/null +++ b/LocateMe/en.lproj/MainWindow.xib @@ -0,0 +1,460 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + YES + + + + + + + Track Location + + NSImage + bullseye.png + + + + + + + + + 256 + {0, 0} + NO + YES + YES + 1 + + + YES + + + + Track Location + + + TrackLocationView + + + + + YES + + + Get Location + + NSImage + pin.png + + + + + + + + + 256 + {0, 0} + NO + YES + YES + 1 + + + YES + + + Get Location + + + GetLocationView + + + + + + + + 266 + {{129, 330}, {163, 49}} + + 3 + MCAwAA + + NO + + + + + + YES + + + window + + + + 9 + + + + delegate + + + + 99 + + + + tabBarController + + + + 113 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + 106 + + + YES + + + + + + + + 107 + + + + + -2 + + + + + 124 + + + YES + + + + + + + + 126 + + + + + 108 + + + YES + + + + + + 129 + + + + + 135 + + + YES + + + + + + + + 137 + + + + + 109 + + + YES + + + + + + 140 + + + + + 111 + + + + + 110 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 106.IBEditorWindowLastContentRect + 106.IBPluginDependency + 107.IBPluginDependency + 108.CustomClassName + 108.IBPluginDependency + 109.CustomClassName + 109.IBPluginDependency + 110.IBPluginDependency + 111.IBPluginDependency + 124.IBPluginDependency + 126.IBPluginDependency + 135.IBPluginDependency + 137.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + {{831, 331}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GetLocationViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TrackLocationViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{229, 373}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 140 + + + + YES + + AppDelegate + NSObject + + YES + + YES + tabBarController + window + + + YES + UITabBarController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + AppDelegate + NSObject + + IBUserSource + + + + + GetLocationViewController + UIViewController + + start: + id + + + YES + + YES + startButton + tableView + + + YES + UIButton + UITableView + + + + IBProjectSource + Classes/GetLocationViewController.h + + + + GetLocationViewController + UIViewController + + IBUserSource + + + + + TrackLocationViewController + UIViewController + + start: + id + + + YES + + YES + startButton + tableView + + + YES + UIButton + UITableView + + + + IBProjectSource + Classes/TrackLocationViewController.h + + + + + 0 + ../LocateMe.xcodeproj + 3 + 3.0 + + diff --git a/LocateMe/en.lproj/TrackLocationSetupView.xib b/LocateMe/en.lproj/TrackLocationSetupView.xib new file mode 100644 index 0000000..990d857 --- /dev/null +++ b/LocateMe/en.lproj/TrackLocationSetupView.xib @@ -0,0 +1,485 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 290 + {320, 44} + + NO + NO + 1 + + YES + + + Configure + + 1 + 0 + + + + + + + 292 + {{0, 79}, {320, 216}} + + NO + YES + YES + YES + + + + 292 + {{20, 50}, {151, 21}} + + + 1 + MCAwIDAAA + + NO + YES + NO + Desired Accuracy: + + Helvetica-Bold + 1.700000e+01 + 16 + + + 1 + MSAxIDEAA + + + 1 + 1.000000e+01 + + + + 292 + {{20, 328}, {196, 21}} + + + NO + YES + NO + Distance Filter (meters): + + + + 1 + 1.000000e+01 + + + + 292 + {{18, 370}, {284, 23}} + + NO + YES + YES + 0 + 0 + 2.000000e+00 + 3.000000e+00 + + + + 292 + {{274, 400}, {32, 18}} + + NO + YES + NO + 1000 + + Helvetica + 1.400000e+01 + 16 + + + 1 + MSAxIDEAA + + 1 + + + + 1 + 1.000000e+01 + + + + 292 + {{191, 400}, {24, 18}} + + NO + YES + NO + 100 + + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{108, 400}, {16, 18}} + + NO + YES + NO + 10 + + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{25, 400}, {8, 18}} + + NO + YES + NO + 1 + + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + {320, 460} + + + + + + + + YES + + + view + + + + 7 + + + + done: + + + + 8 + + + + accuracyPicker + + + + 19 + + + + dataSource + + + + 20 + + + + delegate + + + + 21 + + + + slider + + + + 22 + + + + sliderChangedValue: + + + 13 + + 23 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 3 + + + YES + + + + + + 4 + + + YES + + + + + + 5 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 3.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + + + YES + SetupViewController + UIResponder + {{174, 412}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 23 + + + + YES + + SetupViewController + UIViewController + + YES + + YES + done: + sliderChangedValue: + + + YES + id + id + + + + YES + + YES + accuracyPicker + delegate + slider + + + YES + UIPickerView + id + UISlider + + + + IBProjectSource + Classes/SetupViewController.h + + + + + 0 + ../LocateMe.xcodeproj + 3 + 3.0 + + diff --git a/LocateMe/en.lproj/TrackLocationView.xib b/LocateMe/en.lproj/TrackLocationView.xib new file mode 100644 index 0000000..42c3599 --- /dev/null +++ b/LocateMe/en.lproj/TrackLocationView.xib @@ -0,0 +1,406 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 460} + + NO + YES + NO + 0.000000e+00 + NO + 1 + 1 + 0 + YES + 4.400000e+01 + 1.000000e+01 + 1.000000e+01 + + + + 290 + {{10, 75}, {300, 90}} + + NO + YES + NO + This approach attempts to track changes to the location. The distance filter indicates the desired granularity of updates. + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + 19 + 1 + + + + 293 + {{124, 195}, {72, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + Start + + 3 + MQA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MC41AA + + + + {320, 460} + + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADgEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAACBgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAYYAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAIAAAFTAAMAAAAEAAACDodzAAcAAA/IAAACFgAAAAAACAAIAAgACAABAAEAAQABAAAPyGFw +cGwCAAAAbW50clJHQiBYWVogB9kAAgAXAA8AGAALYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAPbWAAEAAAAA0y1hcHBsaphmZhHvpWo5EzFmkmxXQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA +AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAYSbmRpbgAA +B+wAAAY+ZGVzYwAADiwAAABfZHNjbQAADowAAADwbW1vZAAAD3wAAAAoY3BydAAAD6QAAAAkWFlaIAAA +AAAAAHWbAAA+zQAAAhxYWVogAAAAAAAAWoMAAKx/AAAULFhZWiAAAAAAAAAmuAAAFM4AALzdWFlaIAAA +AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 +cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD +AQAAAgAAAUwCNgMWBCkFagbECDsJxQtdDQgOrhBgEhETvhViFw0YpRo1G7MdJh5lH5ogzSIAIzokeSWz +Ju8oMSlvKqsr5y0jLlovjTC6MegzDzQzNVY2bjeTOL857jsYPEM9Zz6HP6VAv0HWQutD+kUIRhBHFUga +SR1KHEsdTBhNF04XTyhQP1FSUmRTd1SHVZRWoVesWLdZwVrMW9dc413vXv1gDWEdYi1jQGRSZVVmUGdM +aEVpQGo/azxsOG03bjdvOHA7cT5yRnNQdFp1ZnZ4d4l4mXmoeq57qnyifZ1+mH+cgJuBnoKig6eEq4Wu +hq2HrYiviamKpYucjJCNg45yj2aQa5FuknOTdpR3lXSWbpdpmF+ZU5pGmzicJ50Tnf6e6Z/ToLmhn6KI +o3OkcKVvpm6nbqhrqWeqYqtbrFOtTK5Frz6wN7EwsimzJLQftRy2G7cauBG4+LnPuqC7dLxHvRm97L6/ +v5TAbMFEwh3C+cPWxLXFlMZ2x1nIP8knyg3K68u/zJDNY845zxHP6tDG0Z/SfdNb1DjVFdXw1srXo9h6 +2VDaJNr128Pcl9113lbfN+AW4PTh0OKo43/kVeUq5fvmyueX6GPpLun46sPri+xU7Rzt5e7C76HwgPFd +8jnzFvPw9Mf1nvZ090n4Hfju+cL6lvto/Dz9Ev3n/rz/Z///AAABHAHfAq4DrwTaBiEHjQkICpwMOA3n +D5QRQRLtFJYWNRfKGU4awRwlHVwehx+vIN0iDiNCJHAloibXKAwpPypvK54szC30LxcwPjFaMnMzijSe +Nbc21zf6ORc6NztQPGU9eT6HP5RAn0GmQqlDqUSnRaNGn0eZSJJJiEqAS3pMhk2WTqNPr1C7UcRSy1PQ +VNVV2FbbV95Y4FnkWudb7Fz0XfxfA2ANYRNiC2L6Y+hk1mXFZrZnp2iXaYlqfWtzbGltYG5cb1lwVnFW +cltzYHRjdWZ2YndReEF5Mnonex98GH0SfhB/D4ANgQqCBYMBg/yE9IXrht+H0Ii/iayKmougjJ+Noo6h +j6CQm5GSkouTfpRwlWGWUJc+mCqZE5n9muebzZyznZ2ehp+EoIKhgKJ/o3ukd6VxpmmnYKhYqU+qR6s+ +rDWtLa4lrx6wGLEUsg+zBbPstMW1mLZvt0W4G7jxuci6ort+vFu9Or4bvv+/48DIwbTCnMOIxHjFZsZK +xybIAMjZybrKmst8zGDNRM4rzxPP+tDj0cjSrtOS1HXVV9Y21xTX79jM2cDastum3Jbdht5031/gSOEx +4hji++Pe5L3lneZ751noN+kU6e/qzeuu7KHtnO6W747whvF98nLzZPRW9Uf2Nvck+BD4/vns+tj7xfy1 +/aX+lP9a//8AAACDAXgCegOiBOgGQwe4CT4KzwxlDf8PmRErEroUPxWuFyEYdxnCGv8cOh1oHpYfySD8 +IjAjXiSKJbcm4igKKTAqTStoLHwtiy6WL54woTGgMp4znDSdNZ82oDedOJk5kjqIO3s8bD1ZPkU/LUAT +QPVB10K6Q51EfkVcRj9HIEgNSP1J7ErbS8pMt02kTpBPelBlUU9SOlMkVBBU/VXsVt1XzVi+WbBanluD +XF1dOF4SXu5fzWCtYY9icmNYZEBlK2YYZwdn+mjuaeVq3mvYbNJtzG7Eb7pwrnGlcp5zm3SZdZt2nnei +eKd5qXqqe6p8q32ofqR/nICPgYOCcYNihFuFUYZJhz6IMYkhig+K+ovjjMqNro6Qj3CQTJEokgKS3JOz +lIqVY5ZBlyWYDpj4meGayZuvnJadeZ5dn0GgJaEJoe6i06O6pKCliaZzp16oSakvqg6q5au2rI2tYa42 +rwyv5LC+sZyyerNctEG1J7YPtvm357jUucO6uLuqvI69ab5Bvxu/9sDTwbHCkcNwxFHFMcYSxvHH0Mir +yYXKXcs0zAjM282qzoPPZ9BQ0TrSJNMN0/TU2NW61p3Xfthc2TnaFdrw28ncod163lLfKeAB4NnhyuK9 +463kluV/5mjnVOhD6TfqNOs+7Fftge688A/xlfNC9Sj3a/of/XH//wAAbmRpbgAAAAAAAAY2AACjZwAA +WDEAAEyRAACdDgAAJkwAABMcAABQDQAAVDkAAi4UAAIMzAABzMwAAwEAAAIAAAABAAgAFQAjADEAQQBR +AGIAcwCGAJkArQDBANcA7QEEARwBNQFPAWoBhwGkAcIB4gIEAicCTAJ0Ap0CzgMCAzkDcQOrA+UEHwRd +BJsE2wUbBV0FoQXnBi4GdwbCBw8HYAeyCAYIXgi4CRMJdQnUCjMKkQrxC1ULuQwhDIwM+Q1pDd0OUg7L +D0gPxxBLENIRWxHnEncTCBOfFDQUyxVYFeYWeBcMF6EYORjVGXIaEhq1G1kb/xynHU8d+R6lH1Ef/SCr +IVsiCiK8I3skQSUIJdMmnidoKDYpBinVKqUrdixILRst6y68L48wYTExMgMy1zOtNIo1dDZkN1M4RDku +Oh87DTv8POw93j7TP81AyUHDQshDzETXRehG/EgWSSxKLks5TEFNT05fT3ZQklGuUtNT+1UnVlZXi1jH +WgRbQ1yLXdVfHGBiYY5iwGPxZSRmXWeXaNZqGWtdbKJt6m8ycH1xyXMVdGJ1r3b7eEd5l3r/fI5+LX/H +gWiDCoSthk6H7YmNiyqMxY5fj/uRkJMplLyWTZfxmbCbdp05nvWgs6JspCul4qeeqVyrIKzprriwi7Jm +tEm2ObgaueK7q71+v1HBLcMVxQHG8cjtyvHM/s8Q0SrTQ9Vm14rZsduk3ZbfjeGK44jljued6bDrx+3l +8AvyLfRT9n74ovrK/PT//wAAAAIADAAbACoAOgBLAFwAbgCBAJQAqAC9ANIA6AD/ARcBMAFKAWUBgQGe +Ab0B3QH/AiMCSQJyAp0CzwMFAz4DeAOzA+8ELARsBK0E7wUyBXcFvgYHBlIGngbtBz8HlAfpCEMIoAj+ +CWEJxAonCokK7QtVC70MKQyZDQoNgA34DnMO8Q9zD/kQghEOEZ0SLhLCE1sT9BSQFSIVsxZHFt4XdhgR +GLAZURn1GpsbRBvvHJsdSh35HqsfXCAOIMIheCItIukjtCSFJVkmLicDJ9ootCmOKmgrQywfLPwt1y6y +L5AwbDFGMiIzATPiNMw1xDa9N7U4rDmhOpg7jjyDPXo+cz9wQHBBb0J0Q35EikWdRrRH0EjvSfNLAUwL +TRxOLk9GUGVRg1KrU9RVA1Y0V2lYplnlWyNca121XvtgRGFxYqNj1mUJZkNnfmi9agFrR2yNbddvIXBu +cb1zDHRcdax2/HhNeaF7C3yYfjF/xYFfgvuEloYvh8WJW4rujH+ODo+gkSaStpQ+lcKXUJj3mqucY54N +n7mhZKMOpLamXagGqa+rX60SrsmwhLJGtA214LeuuVK6/byjvljACcHFw4nFTccXyOvKw8ykzoXQb9JY +1ETWOdgq2hLb0N2L30rhEOLV5J/mcOhG6h/r/e3e78jxrvOV9YT3b/lW+0P9MP//AAAABgAQAB0AKgA5 +AEkAWQBrAH0AkACkALkAzwDmAP4BFwEyAU4BawGKAawBzwHzAhsCRgJzAqQC1gMMA0QDfQO3A/MEMARw +BLIE9gU7BYMFzQYZBmkGuwcRB2oHxwgnCIoI8glcCckKNwqmCxcLjAwEDH8M/g2BDgcOkg8gD7MQShDm +EYQSJBLIE3EUGRTFFWgWDha2F2EYDhi/GXIaKRriG54cWx0bHdsenR9fICIg6CGuIngjTCQvJRQl/Cbj +J8oosimbKoIraixRLTcuHS8CL+cwzDGwMpYzfjRpNVk2TDdAODM5IzoVOwU79TzlPdc+zD/FQMBBu0K9 +Q8FEy0XcRu9ICkkkSjVLTUxkTYFOok/KUPZSKFNfVJtV31cmWHZZylsgXH9d4F8/YJdh5mMyZIFl1Gcr +aIVp5WtGbKpuD291cN1yRHOudRZ2fXfleVB6yHxUffF/h4Ekgr+EWoXzh4aJGYqnjDONvY9HkMqSUZPV +lVOW1ph1mimb4p2Wn0mg/KKtpGGmFKfKqYOrQa0IrtSwprKAtGG2Tbghud27lb1RvxDA1MKgxHLGRMgf +ygHL6c3Uz8fRvdO01bDXrtmt23fdQN8U4Pbi2uS75pjocOo46+7tj+8c8Jbx//NW9If1qfa697T4pfl5 ++kb6/vun/FD82/1i/en+iP9E//8AAGRlc2MAAAAAAAAABWlNYWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1s +dWMAAAAAAAAAEgAAAAxuYk5PAAAACAAAAOhwdFBUAAAACAAAAOhzdlNFAAAACAAAAOhmaUZJAAAACAAA +AOhkYURLAAAACAAAAOh6aENOAAAACAAAAOhmckZSAAAACAAAAOhqYUpQAAAACAAAAOhlblVTAAAACAAA +AOhwbFBMAAAACAAAAOhwdEJSAAAACAAAAOhlc0VTAAAACAAAAOh6aFRXAAAACAAAAOhydVJVAAAACAAA +AOhrb0tSAAAACAAAAOhkZURFAAAACAAAAOhubE5MAAAACAAAAOhpdElUAAAACAAAAOgAaQBNAGEAY21t +b2QAAAAAAAAGEAAAnGwAAAAAwbTFAAAAAAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBs +ZSwgSW5jLiwgMjAwOQA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + + + + + + YES + + + startButton + + + + 6 + + + + view + + + + 7 + + + + tableView + + + + 8 + + + + dataSource + + + + 9 + + + + delegate + + + + 10 + + + + start: + + + 7 + + 11 + + + + descriptionLabel + + + + 13 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 4 + + + + + 5 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + + + YES + TrackLocationViewController + UIResponder + {{121, 92}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{14, 995}, {300, 150}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 13 + + + + YES + + TrackLocationViewController + UIViewController + + start: + id + + + YES + + YES + descriptionLabel + startButton + tableView + + + YES + UILabel + UIButton + UITableView + + + + IBProjectSource + Classes/TrackLocationViewController.h + + + + + 0 + ../LocateMe.xcodeproj + 3 + 3.0 + + diff --git a/LocateMe/iTunesArtwork b/LocateMe/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/LocateMe/iTunesArtwork differ diff --git a/LocateMe/images/Default.png b/LocateMe/images/Default.png new file mode 100644 index 0000000..ad8a9dc Binary files /dev/null and b/LocateMe/images/Default.png differ diff --git a/LocateMe/images/Icon-72.png b/LocateMe/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/LocateMe/images/Icon-72.png differ diff --git a/LocateMe/images/Icon-Small-50.png b/LocateMe/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/LocateMe/images/Icon-Small-50.png differ diff --git a/LocateMe/images/Icon-Small.png b/LocateMe/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/LocateMe/images/Icon-Small.png differ diff --git a/LocateMe/images/Icon-Small@2x.png b/LocateMe/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/LocateMe/images/Icon-Small@2x.png differ diff --git a/LocateMe/images/Icon.png b/LocateMe/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/LocateMe/images/Icon.png differ diff --git a/LocateMe/images/Icon@2x.png b/LocateMe/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/LocateMe/images/Icon@2x.png differ diff --git a/LocateMe/images/bullseye.png b/LocateMe/images/bullseye.png new file mode 100644 index 0000000..9bcd9f4 Binary files /dev/null and b/LocateMe/images/bullseye.png differ diff --git a/LocateMe/images/pin.png b/LocateMe/images/pin.png new file mode 100644 index 0000000..c6c84d5 Binary files /dev/null and b/LocateMe/images/pin.png differ diff --git a/LocateMe/main.m b/LocateMe/main.m new file mode 100644 index 0000000..d83d292 --- /dev/null +++ b/LocateMe/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: Main source file for this sample. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} + diff --git a/MVCNetworking.zip b/MVCNetworking.zip new file mode 100644 index 0000000..2c0c3e1 Binary files /dev/null and b/MVCNetworking.zip differ diff --git a/MVCNetworking/AppDelegate.h b/MVCNetworking/AppDelegate.h new file mode 100644 index 0000000..ae76b73 --- /dev/null +++ b/MVCNetworking/AppDelegate.h @@ -0,0 +1,72 @@ +/* + File: AppDelegate.h + + Contains: Main app controller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@class PhotoGallery; +@class PhotoGalleryViewController; + +@interface AppDelegate : NSObject +{ + UIWindow * _window; + UINavigationController * _navController; + + NSString * _galleryURLString; + PhotoGallery * _photoGallery; + PhotoGalleryViewController * _photoGalleryViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow * window; +@property (nonatomic, retain) IBOutlet UINavigationController * navController; + +@end diff --git a/MVCNetworking/AppDelegate.m b/MVCNetworking/AppDelegate.m new file mode 100644 index 0000000..9969c9c --- /dev/null +++ b/MVCNetworking/AppDelegate.m @@ -0,0 +1,274 @@ +/* + File: AppDelegate.m + + Contains: Main app controller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "AppDelegate.h" + +#import "PhotoGallery.h" + +#import "PhotoGalleryViewController.h" + +#import "SetupViewController.h" + +#import "NetworkManager.h" + +#import "Logging.h" + +@interface AppDelegate () + +// private properties + +@property (nonatomic, copy, readwrite) NSString * galleryURLString; +@property (nonatomic, retain, readwrite) PhotoGallery * photoGallery; +@property (nonatomic, retain, readwrite) PhotoGalleryViewController * photoGalleryViewController; + +// forward declarations + +- (void)presentSetupViewControllerAnimated:(BOOL)animated; + +@end + +@implementation AppDelegate + +@synthesize window = _window; +@synthesize navController = _navController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + #pragma unused(application) + NSUserDefaults * userDefaults; + + assert(self.window != nil); + assert(self.navController != nil); + + [[QLog log] logWithFormat:@"application start"]; + + // Tell the PhotoGallery class about application startup, which gives it the + // opportunity to do some on-disk garbage collection. + + [PhotoGallery applicationStartup]; + + // Add an observer to the network manager's networkInUse property so that we can + // update the application's networkActivityIndicatorVisible property. This has + // the side effect of starting up the NetworkManager singleton. + + [[NetworkManager sharedManager] addObserver:self forKeyPath:@"networkInUse" options:NSKeyValueObservingOptionInitial context:NULL]; + + // If the "applicationClearSetup" user default is set, clear our preferences. + // This provides an easy way to get back to the initial state while debugging. + + userDefaults = [NSUserDefaults standardUserDefaults]; + if ( [userDefaults boolForKey:@"applicationClearSetup"] ) { + [userDefaults removeObjectForKey:@"applicationClearSetup"]; + [userDefaults removeObjectForKey:@"galleryURLString"]; + [SetupViewController resetChoices]; + } + + // Get the current gallery URL and, if it's not nil, create a gallery object for it. + + self.galleryURLString = [userDefaults stringForKey:@"galleryURLString"]; + if ( (self.galleryURLString != nil) && ([NSURL URLWithString:self.galleryURLString] == nil) ) { + // nil is just fine, but a value that doesn't parse as a URL is not. + self.galleryURLString = nil; + } + if (self.galleryURLString != nil) { + self.photoGallery = [[[PhotoGallery alloc] initWithGalleryURLString:self.galleryURLString] autorelease]; + assert(self.photoGallery != nil); + + [self.photoGallery start]; + } + + // Set up the main view to display the gallery (if any). We add our Setup button to the + // view controller's navigation items, which seems like a bit of a layer break but it + // makes some sort of sense because we want the actions directed to us. + + self.photoGalleryViewController = [[[PhotoGalleryViewController alloc] initWithPhotoGallery:self.photoGallery] autorelease]; + assert(self.photoGalleryViewController != nil); + + self.photoGalleryViewController.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Setup" style:UIBarButtonItemStyleBordered target:self action:@selector(setupAction:)] autorelease]; + assert(self.photoGalleryViewController.navigationItem.rightBarButtonItem != nil); + + [self.navController pushViewController:self.photoGalleryViewController animated:NO]; + + [self.window addSubview:self.navController.view]; + [self.window makeKeyAndVisible]; + + // If the user hasn't configured the app, push the setup view controller. + + if (self.galleryURLString == nil) { + [self presentSetupViewControllerAnimated:NO]; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context + // When the network manager's networkInUse property changes, update the + // application's networkActivityIndicatorVisible property accordingly. +{ + if ([keyPath isEqual:@"networkInUse"]) { + assert(object == [NetworkManager sharedManager]); + #pragma unused(change) + assert(context == NULL); + assert( [NSThread isMainThread] ); + [UIApplication sharedApplication].networkActivityIndicatorVisible = [NetworkManager sharedManager].networkInUse; + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (void)applicationDidEnterBackground:(UIApplication *)application + // When we enter the background make sure to push all of our state + // out to disk. +{ + #pragma unused(application) + [[QLog log] logWithFormat:@"application entered background"]; + if (self.photoGallery != nil) { + [self.photoGallery save]; + } + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (void)applicationWillTerminate:(UIApplication *)application + // Likewise, on iOS 3, and in exceptional circumstances on iOS 4, + // save our state when we are being terminated. +{ + #pragma unused(application) + [[QLog log] logWithFormat:@"application will terminate"]; + if (self.photoGallery != nil) { + [self.photoGallery stop]; + } + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@synthesize galleryURLString = _galleryURLString; +@synthesize photoGallery = _photoGallery; +@synthesize photoGalleryViewController = _photoGalleryViewController; + +- (IBAction)setupAction:(id)sender + // Called when the user taps the Setup button. It just calls through + // to -presentSetupViewControllerAnimated:. +{ + #pragma unused(sender) + [self presentSetupViewControllerAnimated:YES]; +} + +- (void)presentSetupViewControllerAnimated:(BOOL)animated + // Presents the setup view controller. +{ + SetupViewController * vc; + + vc = [[[SetupViewController alloc] initWithGalleryURLString:self.galleryURLString] autorelease]; + assert(vc != nil); + + vc.delegate = self; + + [vc presentModallyOn:self.navController animated:animated]; +} + +- (void)setupViewController:(SetupViewController *)controller didChooseString:(NSString *)string + // A setup view controller delegate callback, called when the user chooses + // a gallery URL string. We respond by reconfiguring the app to display that + // gallery. +{ + assert(controller != nil); + #pragma unused(controller) + assert(string != nil); + + // Disconnect the view controller from the current gallery. + + self.photoGalleryViewController.photoGallery = nil; + + // Shut down and dispose of the current gallery. + + if (self.photoGallery != nil) { + [self.photoGallery stop]; + self.photoGallery = nil; + } + + // Apply the change. + + if ( [string length] == 0 ) { + string = nil; + } + self.galleryURLString = string; + if (self.galleryURLString != nil) { + + // Create a new gallery for the specified URL. + + self.photoGallery = [[[PhotoGallery alloc] initWithGalleryURLString:self.galleryURLString] autorelease]; + assert(self.photoGallery != nil); + + [self.photoGallery start]; + + // Point the main view controller at the new gallery. + + self.photoGalleryViewController.photoGallery = self.photoGallery; + + // Save the user's choice. + + [[NSUserDefaults standardUserDefaults] setObject:self.galleryURLString forKey:@"galleryURLString"]; + } else { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"galleryURLString"]; + } + + [self.navController dismissModalViewControllerAnimated:YES]; +} + +- (void)setupViewControllerDidCancel:(SetupViewController *)controller + // A setup view controller delegate callback, called when the user cancels. + // We just dismiss the view controller. +{ + assert(controller != nil); + #pragma unused(controller) + [self.navController dismissModalViewControllerAnimated:YES]; +} + +@end diff --git a/MVCNetworking/Images/Icon-72.png b/MVCNetworking/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/MVCNetworking/Images/Icon-72.png differ diff --git a/MVCNetworking/Images/Icon-Small-50.png b/MVCNetworking/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/MVCNetworking/Images/Icon-Small-50.png differ diff --git a/MVCNetworking/Images/Icon-Small.png b/MVCNetworking/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/MVCNetworking/Images/Icon-Small.png differ diff --git a/MVCNetworking/Images/Icon-Small@2x.png b/MVCNetworking/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/MVCNetworking/Images/Icon-Small@2x.png differ diff --git a/MVCNetworking/Images/Icon.png b/MVCNetworking/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/MVCNetworking/Images/Icon.png differ diff --git a/MVCNetworking/Images/Icon@2x.png b/MVCNetworking/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/MVCNetworking/Images/Icon@2x.png differ diff --git a/MVCNetworking/Images/Placeholder-Bad.png b/MVCNetworking/Images/Placeholder-Bad.png new file mode 100644 index 0000000..c380bab Binary files /dev/null and b/MVCNetworking/Images/Placeholder-Bad.png differ diff --git a/MVCNetworking/Images/Placeholder-Deferred.png b/MVCNetworking/Images/Placeholder-Deferred.png new file mode 100644 index 0000000..0d87869 Binary files /dev/null and b/MVCNetworking/Images/Placeholder-Deferred.png differ diff --git a/MVCNetworking/Images/Placeholder.png b/MVCNetworking/Images/Placeholder.png new file mode 100644 index 0000000..8c5846d Binary files /dev/null and b/MVCNetworking/Images/Placeholder.png differ diff --git a/MVCNetworking/Images/iTunesArtwork b/MVCNetworking/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/MVCNetworking/Images/iTunesArtwork differ diff --git a/MVCNetworking/Info.plist b/MVCNetworking/Info.plist new file mode 100644 index 0000000..e739686 --- /dev/null +++ b/MVCNetworking/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + MVCNetwork + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small@2x.png + Icon-Small-50.png + + CFBundleIdentifier + com.apple.dts.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainWindow + UIRequiresPersistentWiFi + + + diff --git a/MVCNetworking/Logging/Logging.h b/MVCNetworking/Logging/Logging.h new file mode 100644 index 0000000..661ce64 --- /dev/null +++ b/MVCNetworking/Logging/Logging.h @@ -0,0 +1,61 @@ +/* + File: Logging.h + + Contains: Application-specific logging additions. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QLog.h" + +enum { + kLogOptionNetworkData = 0, + kLogOptionSyncDetails = 1, + kLogOptionXMLParseDetails = 2, + kLogOptionNetworkDetails = 3 +}; diff --git a/MVCNetworking/Logging/QLog.h b/MVCNetworking/Logging/QLog.h new file mode 100644 index 0000000..906a7ea --- /dev/null +++ b/MVCNetworking/Logging/QLog.h @@ -0,0 +1,127 @@ +/* + File: QLog.h + + Contains: A simplistic logging package. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@interface QLog : NSObject +{ + BOOL _enabled; // main thread write, any thread read + int _logFile; // main thread write, any thread read + off_t _logFileLength; // main thread only, only valid if _logFile != -1 + BOOL _loggingToStdErr; // main thread write, any thread read + NSUInteger _optionsMask; // main thread write, any thread read + BOOL _showViewer; // main thread only + NSMutableArray * _logEntries; // main thread only + NSMutableArray * _pendingEntries; // any thread, protected by @synchronize (self) +} + ++ (QLog *)log; // any thread + // Returns the singleton logging object. + +- (void)flush; // main thread only + // Flushes any pending log entries to the logEntries array and also, if + // appropriate, to the log file or stderr. + +- (void)clear; // main thread only + // Empties the logEntries array and, if appropriate, the log file. Not + // much we can do about stderr (-: + +// Preferences + +@property (assign, readonly, getter=isEnabled) BOOL enabled; // any thread, observable, always changed by main thread +@property (assign, readonly, getter=isLoggingToFile) BOOL loggingToFile; // any thread, observable, always changed by main thread +@property (assign, readonly, getter=isLoggingToStdErr) BOOL loggingToStdErr; // any thread, observable, always changed by main thread +@property (assign, readonly) NSUInteger optionsMask; // any thread, observable, always changed by main thread + +@property (assign, readonly) BOOL showViewer; // main thread, observable, always changed by main thread + +// User Default Property +// ------------ -------- +// qlogEnabled enabled +// qlogLoggingToFile loggingToFile +// qlogLoggingToStdErr loggingToStdErr +// qlogOption0..31 optionsMask + +// Log entry generation + +// Some things to note: +// +// o The -logOptions:xxx methods only log if the specified bit is set in +// optionsMask (that is, (optionsMask & (1 << option)) is not zero). +// +// o The format string is as implemented by +[NSString stringWithFormat:]. + +- (void)logWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2); // any thread +- (void)logWithFormat:(NSString *)format arguments:(va_list)argList; // any thread +- (void)logOption:(NSUInteger)option withFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3); // any thread +- (void)logOption:(NSUInteger)option withFormat:(NSString *)format arguments:(va_list)argList; // any thread + +// In memory log entries + +// New entries are added to the end of this array and, as there's an upper limit +// number of entries that will be held in memory, ald entries are removed from +// the beginning. + +@property (retain, readonly) NSMutableArray * logEntries; // observable, always changed by main thread + +// In file log entries + +- (NSInputStream *)streamForLogValidToLength:(off_t *)lengthPtr; // main thread only + // Returns an un-opened stream. If lengthPtr is not NULL then, on return + // *lengthPtr contains the number of bytes in that stream that are + // guaranteed to be valid. + // + // This can only be called on the main thread but the resulting stream + // can be passed to any thread for processing. + +@end diff --git a/MVCNetworking/Logging/QLog.m b/MVCNetworking/Logging/QLog.m new file mode 100644 index 0000000..898f067 --- /dev/null +++ b/MVCNetworking/Logging/QLog.m @@ -0,0 +1,597 @@ +/* + File: QLog.m + + Contains: A simplistic logging package. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QLog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Enable QLOG_ADD_SEQUENCE_NUMBERS to add sequences numbers to the front of each +// log entry. This is a useful tool for debugging various problems. For example, +// sequence numbers make it easy to see if the log viewer is messing up its table +// view updates. + +#if ! defined(QLOG_ADD_SEQUENCE_NUMBERS) + #define QLOG_ADD_SEQUENCE_NUMBERS 0 +#endif + +@interface QLog () + +// private properties + +@property (copy, readonly) NSString * pathToLogFile; + +// forward declarations + +- (void)setupFromPreferences; + +@end + +@implementation QLog + ++ (QLog *)log + // See comment in header. +{ + static QLog * sLog; + + // Note that, because we can be called by any thread, we run this code synchronised. + // However, to avoid synchronised each time, we do a preflight check of sLog. + // This is safe because sLog can never transition from not-nil to nil. + + if (sLog == nil) { + @synchronized ([QLog class]) { + if (sLog == nil) { + sLog = [[QLog alloc] init]; + assert(sLog != nil); + } + } + } + return sLog; +} + +- (id)init +{ + self = [super init]; + if (self != nil) { + self->_logEntries = [[NSMutableArray alloc] init]; + assert(self->_logEntries != nil); + + self->_pendingEntries = [[NSMutableArray alloc] init]; + assert(self->_pendingEntries != nil); + + self->_enabled = NO; + self->_logFile = -1; + self->_logFileLength = -1; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferencesChanged:) name:NSUserDefaultsDidChangeNotification object:nil]; + [self setupFromPreferences]; + } + return self; +} + +- (void)dealloc +{ + // This object lives for the entire life of the application. Getting it to support being deallocated + // would be quite tricky. + assert(NO); + [super dealloc]; +} + +- (NSString *)pathToLogFile + // Returns the path to the log file. Because iOS doesn't support a Logs directory, + // we put the log file into the Caches directory. That's a reasonable place for it. + // We don't want the OS deleting it willynilly (like it might for the temporary directory), + // but neither do we want it being backed up. +{ + NSString * logDirPath; + + logDirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; + assert(logDirPath != nil); + + return [logDirPath stringByAppendingPathComponent:@"QLog.log"]; +} + +- (void)setupFromPreferences + // Sets up the object based on the current user defaults. +{ + NSUserDefaults * userDefaults; + BOOL shouldBeEnabled; + BOOL shouldLogToFile; + int junk; + struct stat sb; + NSUInteger newOptionsMask; + + // This is always called either on the main thread or before initialisation is + // complete and, as such, does not need to be synchronised. + + userDefaults = [NSUserDefaults standardUserDefaults]; + assert(userDefaults != nil); + + // Master enabled property + + shouldBeEnabled = [userDefaults boolForKey:@"qlogEnabled"]; + if (shouldBeEnabled != self->_enabled) { + [self willChangeValueForKey:@"enabled"]; + self->_enabled = shouldBeEnabled; + [self didChangeValueForKey:@"enabled"]; + } + + // loggingToFile property + + shouldLogToFile = [userDefaults boolForKey:@"qlogLoggingToFile"]; + if ( ! self->_enabled ) { + shouldLogToFile = NO; + } + if ( shouldLogToFile != (self->_logFile != -1) ) { + off_t newLength; + + // shouldLogToFile is different from the current logging to file setup, + // so we have to change things. + + [self willChangeValueForKey:@"loggingToFile"]; + newLength = self->_logFileLength; + if (shouldLogToFile) { + + // We should be logging to a file but are not. Open the log file and + // get its length from newLength. Note that the only other code that looks + // at _logFile is also running on the main thread, so we don't have to worry + // about synchronisation here. + + assert(self->_logFile == -1); + self->_logFile = open([self.pathToLogFile fileSystemRepresentation], O_RDWR | O_CREAT | O_APPEND, DEFFILEMODE); + assert(self->_logFile != -1); + + if (self->_logFile != -1) { + junk = fstat(self->_logFile, &sb); + assert(junk == 0); + + newLength = sb.st_size; + assert(newLength >= 0); + } + } else { + + // We are logging to a file and shouldn't be. Close down the log file. + + assert(self->_logFile != -1); + junk = close(self->_logFile); + assert(junk == -1); + self->_logFile = -1; + + newLength = -1; + } + + // Update the newLength property. + + if (newLength != self->_logFileLength) { + [self willChangeValueForKey:@"logFileLength"]; + self->_logFileLength = newLength; + [self didChangeValueForKey:@"logFileLength"]; + } + + // Finally, trigger KVO observers. + + [self didChangeValueForKey:@"loggingToFile"]; + } + + // loggingToStdErr property + + shouldBeEnabled = [userDefaults boolForKey:@"qlogLoggingToStdErr"]; + if ( ! self->_enabled ) { + shouldBeEnabled = NO; + } + if (shouldBeEnabled != self->_loggingToStdErr) { + [self willChangeValueForKey:@"loggingToStdErr"]; + self->_loggingToStdErr = shouldBeEnabled; + [self didChangeValueForKey:@"loggingToStdErr"]; + } + + // optionsMask property + + newOptionsMask = 0; + for (int i = 0; i < 32; i++) { + newOptionsMask |= [userDefaults boolForKey:[NSString stringWithFormat:@"qlogOption%d", i]] << i; + } + if (newOptionsMask != self->_optionsMask) { + [self willChangeValueForKey:@"optionsMask"]; + self->_optionsMask = newOptionsMask; + [self didChangeValueForKey:@"optionsMask"]; + } + + // showViewer property + + shouldBeEnabled = [userDefaults boolForKey:@"qlogShowViewer"]; + if (shouldBeEnabled != self->_showViewer) { + [self willChangeValueForKey:@"showViewer"]; + self->_showViewer = shouldBeEnabled; + [self didChangeValueForKey:@"showViewer"]; + } +} + +- (void)preferencesChanged:(NSNotification *)note + // Called in response to the NSUserDefaultsDidChangeNotification notification. + // This simply calls -setupFromPreferences to re-read our preferences. +{ + #pragma unused(note) + assert([NSThread isMainThread]); + [self setupFromPreferences]; +} + +@synthesize enabled = _enabled; + +- (BOOL)isLoggingToFile + // See comment in header. + // + // Note that this is for public consumption only. Internally we just look at + // _logFile. +{ + return (self->_logFile != -1); +} + +@synthesize loggingToStdErr = _loggingToStdErr; + +@synthesize optionsMask = _optionsMask; + +@synthesize showViewer = _showViewer; + +- (void)logWithFormat:(NSString *)format arguments:(va_list)argList + // See comment in header. +{ + NSString * formattedArgs; + NSString * newEntry; + + // Can be called on any thread. + + if (self->_enabled) { + BOOL success; + struct timeval now; + struct tm localNow; + char sequenceNumberStr[32]; + char dateTimeStr[32]; + + // Create the log entry. Note that the log entry header is formatted to look like the + // result of NSLog. + + formattedArgs = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease]; + assert(formattedArgs != nil); + + success = gettimeofday(&now, NULL) == 0; + if (success) { + success = localtime_r(&now.tv_sec, &localNow) != NULL; + } + if (success) { + success = strftime_l(dateTimeStr, sizeof(dateTimeStr), "%Y-%m-%d %H:%M:%S", &localNow, NULL) != 0; + } + if ( ! success ) { + strlcpy(dateTimeStr, "?", sizeof(dateTimeStr)); + } + + #if QLOG_ADD_SEQUENCE_NUMBERS + static uint64_t sLastSequenceNumber; + snprintf(sequenceNumberStr, sizeof(sequenceNumberStr), "%llu ", (unsigned long long) OSAtomicAdd64(1, (int64_t *) &sLastSequenceNumber)); + #else + sequenceNumberStr[0] = 0; + #endif + + newEntry = [NSString stringWithFormat:@"%s%s.%03d %s[%d:%x] %@", sequenceNumberStr, dateTimeStr, (int) (now.tv_usec / 1000), getprogname(), (int) getpid(), (unsigned int) mach_thread_self(), formattedArgs]; + assert(newEntry != nil); + + // Add the log entry to the list of new entries and, if this is the first + // element in the list, tell the main thread about it. + + @synchronized (self) { + [self->_pendingEntries addObject:newEntry]; + if ([self->_pendingEntries count] == 1) { + [self performSelectorOnMainThread:@selector(flush) withObject:nil waitUntilDone:NO]; + } + } + + if (self.isLoggingToStdErr) { + fprintf(stderr, "%s\n", [newEntry UTF8String]); + } + } +} + +- (void)logWithFormat:(NSString *)format, ... + // See comment in header. +{ + va_list argList; + + // Can be called on any thread. + + if (self->_enabled) { + va_start(argList, format); + [self logWithFormat:format arguments:argList]; + va_end(argList); + } +} + +- (void)logOption:(NSUInteger)option withFormat:(NSString *)format arguments:(va_list)argList + // See comment in header. +{ + if ( self->_enabled && (self->_optionsMask & (1 << option)) ) { + [self logWithFormat:format arguments:argList]; + } +} + +- (void)logOption:(NSUInteger)option withFormat:(NSString *)format, ... + // See comment in header. +{ + va_list argList; + + if ( self->_enabled && (self->_optionsMask & (1 << option)) ) { + va_start(argList, format); + [self logWithFormat:format arguments:argList]; + va_end(argList); + } +} + +@synthesize logEntries = _logEntries; + +- (NSData *)dataForLogEntries:(NSArray *)entries + // Flattens the supplied array of log entries to a data object containing + // LF terminated UTF-8 strings. +{ + NSMutableData * result; + + result = [NSMutableData dataWithCapacity:[entries count] * 80]; + assert(result != nil); + + for (NSString * entry in entries) { + NSData * entryData; + + assert([entry isKindOfClass:[NSString class]]); + + entryData = [entry dataUsingEncoding:NSUTF8StringEncoding]; + assert(entryData != nil); + + [result appendData:entryData]; + [result appendBytes:"\n" length:1]; + } + return result; +} + +- (void)flush + // See comment in header. +{ + NSArray * entriesToAdd; + NSIndexSet * indexSet; + int junk; + struct stat sb; + + assert([NSThread isMainThread]); + + // Steal the entries from the _pendingEntries array. + + @synchronized (self) { + entriesToAdd = [[self->_pendingEntries copy] autorelease]; + [self->_pendingEntries removeAllObjects]; + } + + // We might have no pending log entries (because of someone calling us directly, + // rather than the logging code calling us via -performSelectorOnMainThread:xxx), + // so we only do the rest of this code if we actually got some log entries. + + if ([entriesToAdd count] != 0) { + + // Add the entries to the in-memory log. + + indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange([self->_logEntries count], [entriesToAdd count])]; + assert(indexSet != nil); + + [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:@"logEntries"]; + [self->_logEntries addObjectsFromArray:entriesToAdd]; + [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:@"logEntries"]; + + // If we've hit the limit of the in-memory log, prune it now. We do this after adding + // the new entries so that if there are more than 100 new entries we still clip correctly. + + if ([self->_logEntries count] > 100) { + indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self->_logEntries count] - 100)]; + assert(indexSet != nil); + + [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:@"logEntries"]; + [self->_logEntries removeObjectsAtIndexes:indexSet]; + [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:@"logEntries"]; + } + + // If we're logging to a file, add the entries to the on-disk log. + + if (self->_logFile != -1) { + int err; + NSData * dataToWrite; + NSUInteger bytesToWrite; + NSUInteger bytesWrittenSoFar; + const char * buf; + + err = 0; + + // Flatten the array of strings into a single blob of UTF-8 data. + + dataToWrite = [self dataForLogEntries:entriesToAdd]; + assert(dataToWrite != nil); + + // Write that data to the file. + + bytesToWrite = [dataToWrite length]; + bytesWrittenSoFar = 0; + buf = [dataToWrite bytes]; + do { + ssize_t bytesWritten; + + if (bytesWrittenSoFar == bytesToWrite) { + break; + } + bytesWritten = write(self->_logFile, &buf[bytesWrittenSoFar], bytesToWrite - bytesWrittenSoFar); + if (bytesWritten > 0) { + bytesWrittenSoFar += bytesWritten; + } else { + assert(bytesWritten != 0); + err = errno; + + if (err == EINTR) { + err = 0; + } else { + break; + } + } + } while (YES); + + // I have no idea what to do with an error at this point. Right now, I'm just + // going to ignore it in production code. + + assert(err == 0); + + // Once we've written out the entire buffer, update the log file length. + // We do this at the end to ensure that the client sees only complete + // log records. Also, we get the length from the file rather than keeping + // track of it ourself so that things can't possibly get too far out of + // sync. + + junk = fstat(self->_logFile, &sb); + assert(junk == 0); + + self->_logFileLength = sb.st_size; + assert(self->_logFileLength >= 0); + } + } +} + +- (void)clear + // See comment in header. +{ + assert([NSThread isMainThread]); + + // First truncate the log file (if any). + + if (self->_logFile != -1) { + int junk; + + junk = ftruncate(self->_logFile, 0); + assert(junk == 0); + + self->_logFileLength = 0; + } + + // Next nix any in-memory log entries. + + if ([self->_logEntries count] != 0) { + NSIndexSet * indexSet; + + indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self->_logEntries count])]; + assert(indexSet != 0); + + [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:@"logEntries"]; + [self->_logEntries removeAllObjects]; + [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:@"logEntries"]; + } +} + +- (NSInputStream *)streamForLogValidToLength:(off_t *)lengthPtr + // See comment in header. +{ + NSInputStream * result; + NSString * path; + + // It's important that this be called on the main thread so that it's coordinated + // with the the preferences re-read code that might be closing or opening the log + // file. + + assert([NSThread isMainThread]); + + // Flush the log to ensure that any in-memory entries are pushed to disk before + // we get the log file length. + + [self flush]; + + if (self->_logFile == -1) { + NSData * logData; + + // There is no log file. Just return a memory-based stream containing our + // in-memory log entries. + + logData = [self dataForLogEntries:self.logEntries]; + assert(logData != nil); + + result = [NSInputStream inputStreamWithData:logData]; + if (result != nil) { + if (lengthPtr != NULL) { + *lengthPtr = [logData length]; + } + } + } else { + // There is a log file, so return a file stream for that. + + path = self.pathToLogFile; + assert(path != nil); + + result = [NSInputStream inputStreamWithFileAtPath:path]; + + if (result != nil) { + if (lengthPtr != NULL) { + assert(self->_logFileLength >= 0); + *lengthPtr = self->_logFileLength; + } + } + } + + return result; +} + +@end diff --git a/MVCNetworking/Logging/QLogViewer.h b/MVCNetworking/Logging/QLogViewer.h new file mode 100644 index 0000000..f18e599 --- /dev/null +++ b/MVCNetworking/Logging/QLogViewer.h @@ -0,0 +1,66 @@ +/* + File: QLogViewer.h + + Contains: Displays in-memory QLog entries, with options to copy and mail the log. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@interface QLogViewer : UITableViewController +{ + int _logEntriesDummy; + UIActionSheet * _actionSheet; + UIAlertView * _alertView; +} + +- (void)presentModallyOn:(UIViewController *)controller animated:(BOOL)animated; + // Present the view controller modally on the specified view controller. + +@end diff --git a/MVCNetworking/Logging/QLogViewer.m b/MVCNetworking/Logging/QLogViewer.m new file mode 100644 index 0000000..df03c69 --- /dev/null +++ b/MVCNetworking/Logging/QLogViewer.m @@ -0,0 +1,588 @@ +/* + File: QLogViewer.m + + Contains: Displays in-memory QLog entries, with options to copy and mail the log. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QLogViewer.h" + +#import "QLog.h" + +#import + +#include "zlib.h" + +@interface QLogViewer () + +// private properties + +@property (nonatomic, retain, readwrite) UIActionSheet * actionSheet; +@property (nonatomic, retain, readwrite) UIAlertView * alertView; + +// forward declarations + +- (void)dismissActionsAndAlerts; + +@end + +@implementation QLogViewer + +- (id)init +{ + self = [super initWithStyle:UITableViewStylePlain]; + if (self != nil) { + [[QLog log] addObserver:self forKeyPath:@"logEntries" options:0 context:&self->_logEntriesDummy]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActive:) name:UIApplicationWillResignActiveNotification object:nil]; + } + // You can enable the following to test how the QLog subsystem responds to entries being added; + // this is useful in situations where no entries are being added by other code. + if (NO) { + [NSTimer scheduledTimerWithTimeInterval:5.1 target:self selector:@selector(debugAddLogEntry) userInfo:nil repeats:YES]; + } + return self; +} + +- (void)dealloc +{ + [[QLog log] removeObserver:self forKeyPath:@"logEntries"]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil]; + assert(self->_actionSheet == nil); // should be gone at this point + assert(self->_alertView == nil); // should be gone at this point + [super dealloc]; +} + +#pragma mark * General view controller stuff + +- (void)willResignActive:(NSNotification *)note + // Called in response to the UIApplicationWillResignActiveNotification. + // If an action sheet is up, dismiss it per the HI guidelines. +{ + #pragma unused(note) + [self dismissActionsAndAlerts]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Configure the table view. + + self.tableView.allowsSelection = NO; + self.tableView.rowHeight = 60.0f; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; +} + +#pragma mark * Updating + +- (NSArray *)indexPathsForSection:(NSUInteger)section rowIndexSet:(NSIndexSet *)indexSet + // Returns an array containing index path objects for each item in the + // index set, where the section of the index path is as specified by the + // parameter and the row of the index path is the index from the index set. +{ + NSMutableArray * indexPaths; + NSUInteger currentIndex; + + assert(indexSet != nil); + + indexPaths = [NSMutableArray array]; + assert(indexPaths != nil); + currentIndex = [indexSet firstIndex]; + while (currentIndex != NSNotFound) { + [indexPaths addObject:[NSIndexPath indexPathForRow:currentIndex inSection:section]]; + currentIndex = [indexSet indexGreaterThanIndex:currentIndex]; + } + return indexPaths; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == &self->_logEntriesDummy) { + + // Respond to changes in the logEntries property of the QLog. + + assert([keyPath isEqual:@"logEntries"]); + assert(object = [QLog log]); + assert(change != nil); + + if (self.isViewLoaded) { + NSIndexSet * indexes; + + indexes = [change objectForKey:NSKeyValueChangeIndexesKey]; + assert( (indexes == nil) || [indexes isKindOfClass:[NSIndexSet class]] ); + + assert([change objectForKey:NSKeyValueChangeKindKey] != nil); + switch ( [[change objectForKey:NSKeyValueChangeKindKey] intValue] ) { + default: + assert(NO); + case NSKeyValueChangeSetting: { + [self.tableView reloadData]; + } break; + case NSKeyValueChangeInsertion: { + assert(indexes != nil); + [self.tableView insertRowsAtIndexPaths:[self indexPathsForSection:0 rowIndexSet:indexes] withRowAnimation:UITableViewRowAnimationNone]; + [self.tableView flashScrollIndicators]; + } break; + case NSKeyValueChangeRemoval: { + assert(indexes != nil); + [self.tableView deleteRowsAtIndexPaths:[self indexPathsForSection:0 rowIndexSet:indexes] withRowAnimation:UITableViewRowAnimationNone]; + [self.tableView flashScrollIndicators]; + } break; + case NSKeyValueChangeReplacement: { + assert(indexes != nil); + [self.tableView reloadRowsAtIndexPaths:[self indexPathsForSection:0 rowIndexSet:indexes] withRowAnimation:UITableViewRowAnimationNone]; + } break; + } + } + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark * Table view callbacks + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + assert(tv == self.tableView); + assert(section == 0); + + return [[QLog log].logEntries count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + UITableViewCell * cell; + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < [[QLog log].logEntries count]); + + cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"] autorelease]; + assert(cell != nil); + + cell.textLabel.font = [UIFont systemFontOfSize:12.0f]; + cell.textLabel.numberOfLines = 3; + cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; + + // In the long term I'd like to have another view that lets you see a complete + // log entry. But right now I've skipped that to save time. + // + // cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + cell.textLabel.text = [[QLog log].logEntries objectAtIndex:indexPath.row]; + + return cell; +} + +#pragma mark * Presentation + +- (void)presentModallyOn:(UIViewController *)controller animated:(BOOL)animated + // See comment in header. +{ + UINavigationController * navController; + + navController = [[[UINavigationController alloc] initWithRootViewController:self] autorelease]; + assert(navController != nil); + + self.navigationItem.title = @"Log"; + self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(actionAction:)] autorelease]; + self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneAction:) ] autorelease]; + + [controller presentModalViewController:navController animated:animated]; +} + +#pragma mark * Log Wrangling + +static BOOL gzwrite_all(gzFile file, const uint8_t * buffer, size_t bytesToWrite) + // A wrapper around gzwrite that handles short writes. +{ + size_t bytesWritten; + int byteWrittenThisTime; + + bytesWritten = 0; + while (bytesWritten != bytesToWrite) { + byteWrittenThisTime = gzwrite(file, &buffer[bytesWritten], bytesToWrite - bytesWritten); + if (byteWrittenThisTime <= 0) { + break; + } else { + bytesWritten += byteWrittenThisTime; + } + } + + return (bytesWritten == bytesToWrite); +} + +- (NSData *)dataWithCompressedLog + // Returns a data object that holds the gz compressed contents of the log. The resulting + // data object is memory mapped to minimise the memory impact. +{ + NSData * result; + NSInputStream * logStream; + off_t logStreamLength; + BOOL success; + int err; + NSString * compressedLogPath; + gzFile compressedLogFile; + off_t bytesRemaining; + + result = nil; + + // Create the compressed file and get the uncompressed stream. + + compressedLogPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"CompressedLog.gz"]; + assert(compressedLogPath != NULL); + + logStream = [[QLog log] streamForLogValidToLength:&logStreamLength]; + success = (logStream != nil); + + if (success) { + compressedLogFile = gzopen([compressedLogPath UTF8String], "wb"); + success = (compressedLogFile != NULL); + } + + // Copy data from one to the other. + + if (success) { + [logStream open]; + + bytesRemaining = logStreamLength; + while (bytesRemaining != 0) { + uint8_t buffer[32768]; + size_t bytesToReadThisTime; + NSInteger bytesReadThisTime; + + if (bytesRemaining < sizeof(buffer)) { + bytesToReadThisTime = (size_t) bytesRemaining; + } else { + bytesToReadThisTime = sizeof(buffer); + } + bytesReadThisTime = [logStream read:buffer maxLength:bytesToReadThisTime]; + if (bytesReadThisTime <= 0) { + success = NO; + break; + } + bytesRemaining -= bytesReadThisTime; + + success = gzwrite_all(compressedLogFile, buffer, bytesReadThisTime); + if ( ! success ) { + break; + } + } + + // Clean up. + + err = gzclose(compressedLogFile); + success = success && (err == 0); + + [logStream close]; + } + + // Map the resulting file. Once we've mapped the file we can remove it from the file system + // namespace; this avoids use having to give it a unique name. + + if (success) { + result = [NSData dataWithContentsOfMappedFile:compressedLogPath]; + + (void) [[NSFileManager defaultManager] removeItemAtPath:compressedLogPath error:NULL]; + } + + return result; +} + +- (void)printLog + // Prints the log to stderr. +{ + BOOL success; + NSInputStream * logStream; + off_t logStreamLength; + off_t bytesRemaining; + + // Get a stream to the log data. + + logStream = [[QLog log] streamForLogValidToLength:&logStreamLength]; + success = (logStream != nil); + + // Read the stream and write it to stderr. + + if (success) { + [logStream open]; + + bytesRemaining = logStreamLength; + while (bytesRemaining != 0) { + uint8_t buffer[32768]; + size_t bytesToReadThisTime; + NSInteger bytesReadThisTime; + + if (bytesRemaining < sizeof(buffer)) { + bytesToReadThisTime = (size_t) bytesRemaining; + } else { + bytesToReadThisTime = sizeof(buffer); + } + bytesReadThisTime = [logStream read:buffer maxLength:bytesToReadThisTime]; + if (bytesReadThisTime <= 0) { + success = NO; + break; + } + bytesRemaining -= bytesReadThisTime; + + // We ignore any errors from fwrite. + + (void) fwrite(buffer, bytesReadThisTime, 1, stderr); + } + assert(success); + + [logStream close]; + } +} + +#pragma mark * Actions + +@synthesize actionSheet = _actionSheet; +@synthesize alertView = _alertView; + +- (void)dismissActionsAndAlerts + // Cancel any visible action sheet or alert view. Note that we only cancel an alert view + // if it has more than one button; a single button alert is informational and the user + // probably wants to see that info eventually. OTOH, for alert views that have more than one + // button, we take the safe pass and choose the Cancel button. +{ + if (self.actionSheet != nil) { + [self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:NO]; + assert(self.actionSheet == nil); + } + if ( (self.alertView != nil) && (self.alertView.numberOfButtons != 1) ) { + [self.alertView dismissWithClickedButtonIndex:self.alertView.cancelButtonIndex animated:NO]; + assert(self.alertView == nil); + } +} + +- (void)showErrorMessage:(NSString *)message + // Shows an alert view containing the specified error message. +{ + assert(self.alertView == nil); + self.alertView = [[[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Drat!", nil] autorelease]; + assert(self.alertView != nil); + + self.alertView.cancelButtonIndex = 0; + self.alertView.delegate = self; + + [self.alertView show]; +} + +enum { + kActionSheetButtonIndexClear = 0, + kActionSheetButtonIndexCopy = 1, + kActionSheetButtonIndexPrint = 2, + kActionSheetButtonIndexMail = 3, + kActionSheetButtonIndexCancel = 4, +}; + +- (IBAction)actionAction:(id)sender + // Called in response to the user tapping the Action button. This puts up an + // alert sheet that lets the user choose what they'd like to do. +{ + #pragma unused(sender) + NSString * mailTitle; + + // Only include a "Mail Compressed Log" button if the device has Mail configured. + + if ([MFMailComposeViewController canSendMail]) { + mailTitle = @"Mail Compressed Log"; + } else { + mailTitle = nil; + } + assert(self.actionSheet == nil); + self.actionSheet = [[[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Clear" otherButtonTitles:@"Copy", @"Print to StdErr", mailTitle, nil] autorelease]; + assert(self.actionSheet != nil); + + [self.actionSheet showInView:self.view]; +} + +- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex + // Called when the action sheet goes away, where buttonIndex denotes the option + // chosen by the user. +{ + #pragma unused(actionSheet) + assert(actionSheet == self.actionSheet); + + switch (buttonIndex) { + case kActionSheetButtonIndexClear: { + + // The user tapped Clear; put up an alert view to confirm that. + + assert(self.alertView == nil); + self.alertView = [[[UIAlertView alloc] initWithTitle:@"Clear Log?" message:@"Are you sure you want to clear the log completely?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Clear", nil] autorelease]; + assert(self.alertView != nil); + + self.alertView.delegate = self; + + [self.alertView show]; + } break; + case kActionSheetButtonIndexCopy: { + NSString * logString; + + // The user tapped Copy; serialise the log to the pasteboard. + + logString = [[QLog log].logEntries componentsJoinedByString:@"\n"]; + assert(logString != nil); + + [UIPasteboard generalPasteboard].string = logString; + } break; + case kActionSheetButtonIndexPrint: { + + // The user tapped Print; print the log to stderr. + + [self printLog]; + } break; + case kActionSheetButtonIndexMail: { // actually equivalent to kActionSheetButtonIndexCancel if +canSendMail is NO + + // The user tapped Mail or, if mail is not availble, Cancel. In the + // former case, put up the mail composer view. In the latter case + // do nothing. + + if ([MFMailComposeViewController canSendMail]) { + NSData * logData; + + logData = [self dataWithCompressedLog]; + if (logData == nil) { + [self showErrorMessage:@"Could not create compressed log."]; + } else { + MFMailComposeViewController * vc; + + vc = [[[MFMailComposeViewController alloc] init] autorelease]; + assert(vc != nil); + + vc.mailComposeDelegate = self; + [vc setSubject:[NSString stringWithFormat:@"%@ Log", [[NSProcessInfo processInfo] processName]]]; + [vc addAttachmentData:logData mimeType:@"application/x-gzip" fileName:[NSString stringWithFormat:@"%s.log.gz", getprogname()]]; + + [self presentModalViewController:vc animated:YES]; + } + } + } break; + default: + assert(NO); + case kActionSheetButtonIndexCancel: { + + // The user tapped Cancel; do nothing. + } break; + } + + self.actionSheet = nil; +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex + // Called when an alert view is dismissed. We have to handle one special case, described + // below. +{ + assert(alertView == self.alertView); + #pragma unused(alertView) + + // There are two possible alert views, one that displays error messages and one + // that confirms the Clear action. The former only has a Cancel button, so if we're + // dismissed with a button that's not the cancel button we clear the log. Kinda + // yicky, but I'll live. + + if (buttonIndex != self.alertView.cancelButtonIndex) { + [[QLog log] clear]; + } + + self.alertView = nil; +} + +- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error + // Called by the mail composer view when its done. We report any errors and + // then dismiss the mail composer view. +{ + #pragma unused(controller) + #pragma unused(error) + + switch (result) { + default: + assert(NO); + // fall through + case MFMailComposeResultCancelled: + case MFMailComposeResultSaved: + case MFMailComposeResultSent: { + // do nothing + } break; + case MFMailComposeResultFailed: { + [self showErrorMessage:@"Could not send mail."]; + } break; + } + [self dismissModalViewControllerAnimated:YES]; +} + +- (IBAction)doneAction:(id)sender + // Called when the user taps Done in our navigation bar. We just dismiss ourselves. +{ + #pragma unused(sender) + [self.parentViewController dismissModalViewControllerAnimated:YES]; +} + +- (void)debugAddLogEntry +{ + static int sLogNumber; + + sLogNumber += 1; + [[QLog log] logWithFormat:@"debugAddLogEntry blah blah blah %d", sLogNumber]; +} + +@end diff --git a/MVCNetworking/Logging/Settings.bundle/DebugOptions.plist b/MVCNetworking/Logging/Settings.bundle/DebugOptions.plist new file mode 100644 index 0000000..b029dfd --- /dev/null +++ b/MVCNetworking/Logging/Settings.bundle/DebugOptions.plist @@ -0,0 +1,101 @@ + + + + + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Photos + + + Type + PSToggleSwitchSpecifier + Title + Clear Setup + Key + applicationClearSetup + DefaultValue + + + + Type + PSToggleSwitchSpecifier + Title + Clear Cache + Key + galleryClearCache + DefaultValue + + + + Type + PSToggleSwitchSpecifier + Title + Sync on Activate + Key + gallerySyncOnActivate + DefaultValue + + + + Type + PSGroupSpecifier + Title + Operation Delay + + + Type + PSSliderSpecifier + Title + Operation Delay + Key + operationDelay + DefaultValue + 0 + MinimumValue + 0 + MaximumValue + 11 + MinimumValueImage + Zero.png + MaximumValueImage + Eleven.png + + + Type + PSGroupSpecifier + Title + Network Errors + + + Type + PSMultiValueSpecifier + Title + Force Errors + Key + networkErrorRate + DefaultValue + 0 + Values + + 0 + 1 + 2 + 3 + 10 + + Titles + + Never + Every request + Every other request + Every third request + Every ten requests + + + + + diff --git a/MVCNetworking/Logging/Settings.bundle/Eleven.png b/MVCNetworking/Logging/Settings.bundle/Eleven.png new file mode 100644 index 0000000..291180e Binary files /dev/null and b/MVCNetworking/Logging/Settings.bundle/Eleven.png differ diff --git a/MVCNetworking/Logging/Settings.bundle/LoggingOptions.plist b/MVCNetworking/Logging/Settings.bundle/LoggingOptions.plist new file mode 100644 index 0000000..d0d39c3 --- /dev/null +++ b/MVCNetworking/Logging/Settings.bundle/LoggingOptions.plist @@ -0,0 +1,75 @@ + + + + + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Logging + + + Type + PSToggleSwitchSpecifier + Title + Log to File + Key + qlogLoggingToFile + DefaultValue + NO + + + Type + PSToggleSwitchSpecifier + Title + Log to stderr + Key + qlogLoggingToStdErr + DefaultValue + NO + + + Type + PSToggleSwitchSpecifier + Title + Log Network Data + Key + qlogOption0 + DefaultValue + NO + + + Type + PSToggleSwitchSpecifier + Title + Log Sync Details + Key + qlogOption1 + DefaultValue + NO + + + Type + PSToggleSwitchSpecifier + Title + Log XML Parsing + Key + qlogOption2 + DefaultValue + NO + + + Type + PSToggleSwitchSpecifier + Title + Log Network Details + Key + qlogOption3 + DefaultValue + NO + + + + diff --git a/MVCNetworking/Logging/Settings.bundle/Root.plist b/MVCNetworking/Logging/Settings.bundle/Root.plist new file mode 100644 index 0000000..cd7aefa --- /dev/null +++ b/MVCNetworking/Logging/Settings.bundle/Root.plist @@ -0,0 +1,57 @@ + + + + + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Logging + + + Type + PSToggleSwitchSpecifier + Title + Enabled + Key + qlogEnabled + DefaultValue + + + + Type + PSToggleSwitchSpecifier + Title + Show Viewer + Key + qlogShowViewer + DefaultValue + + + + Type + PSChildPaneSpecifier + Title + Logging Options + File + LoggingOptions + + + Type + PSGroupSpecifier + Title + Debug + + + Type + PSChildPaneSpecifier + Title + Debug Options + File + DebugOptions + + + + diff --git a/MVCNetworking/Logging/Settings.bundle/Zero.png b/MVCNetworking/Logging/Settings.bundle/Zero.png new file mode 100644 index 0000000..a7e87dc Binary files /dev/null and b/MVCNetworking/Logging/Settings.bundle/Zero.png differ diff --git a/MVCNetworking/MVCNetworking.xcodeproj/project.pbxproj b/MVCNetworking/MVCNetworking.xcodeproj/project.pbxproj new file mode 100755 index 0000000..2a751d5 --- /dev/null +++ b/MVCNetworking/MVCNetworking.xcodeproj/project.pbxproj @@ -0,0 +1,483 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + E40B47D6121C1A2600FD846C /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = E40B47CF121C1A2600FD846C /* Icon-72.png */; }; + E40B47D7121C1A2600FD846C /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = E40B47D0121C1A2600FD846C /* Icon-Small-50.png */; }; + E40B47D8121C1A2600FD846C /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = E40B47D1121C1A2600FD846C /* Icon-Small.png */; }; + E40B47D9121C1A2600FD846C /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E40B47D2121C1A2600FD846C /* Icon-Small@2x.png */; }; + E40B47DA121C1A2600FD846C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = E40B47D3121C1A2600FD846C /* Icon.png */; }; + E40B47DB121C1A2600FD846C /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E40B47D4121C1A2600FD846C /* Icon@2x.png */; }; + E40B47DC121C1A2600FD846C /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = E40B47D5121C1A2600FD846C /* iTunesArtwork */; }; + E40E870A123A91D500C17F85 /* Placeholder-Deferred.png in Resources */ = {isa = PBXBuildFile; fileRef = E40E8709123A91D500C17F85 /* Placeholder-Deferred.png */; }; + E438FC2F121487EB00FF6CEA /* Photo.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC1C121487EA00FF6CEA /* Photo.m */; }; + E438FC30121487EB00FF6CEA /* PhotoGallery.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC1E121487EA00FF6CEA /* PhotoGallery.m */; }; + E438FC31121487EB00FF6CEA /* Photos.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = E438FC1F121487EA00FF6CEA /* Photos.xcdatamodel */; }; + E438FC32121487EB00FF6CEA /* Thumbnail.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC21121487EA00FF6CEA /* Thumbnail.m */; }; + E438FC33121487EB00FF6CEA /* QHTTPOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC24121487EA00FF6CEA /* QHTTPOperation.m */; }; + E438FC34121487EB00FF6CEA /* QRunLoopOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC26121487EA00FF6CEA /* QRunLoopOperation.m */; }; + E438FC38121487EB00FF6CEA /* PhotoGalleryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC2E121487EB00FF6CEA /* PhotoGalleryViewController.m */; }; + E438FC3B1214890600FF6CEA /* GalleryParserOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E438FC3A1214890600FF6CEA /* GalleryParserOperation.m */; }; + E456B7951215B84600317CE6 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E456B7941215B84600317CE6 /* libz.dylib */; }; + E456B7981215B85500317CE6 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E456B7971215B85500317CE6 /* MessageUI.framework */; }; + E45D9E660DAFDA3E00649782 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E45D9E650DAFDA3E00649782 /* AppDelegate.m */; }; + E45EFC71121EBA68004CE911 /* MakeThumbnailOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E45EFC70121EBA68004CE911 /* MakeThumbnailOperation.m */; }; + E4644C3712314D3F00B87652 /* PhotoGalleryContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E4644C3612314D3F00B87652 /* PhotoGalleryContext.m */; }; + E464FDEE1218858300170C0E /* SetupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E464FDED1218858300170C0E /* SetupViewController.m */; }; + E46C04AE123E1A4300C22427 /* QImageScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = E46C04AD123E1A4300C22427 /* QImageScrollView.m */; }; + E46C04E9123E44C200C22427 /* RetryingHTTPOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E46C04E8123E44C200C22427 /* RetryingHTTPOperation.m */; }; + E49F0244121437AC00C7DFB3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49F0243121437AC00C7DFB3 /* UIKit.framework */; }; + E49F0246121437B400C7DFB3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49F0245121437B400C7DFB3 /* Foundation.framework */; }; + E49F0248121437BD00C7DFB3 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49F0247121437BD00C7DFB3 /* CoreData.framework */; }; + E4A524981219EAF9004C3B19 /* RecursiveDeleteOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E4A524971219EAF9004C3B19 /* RecursiveDeleteOperation.m */; }; + E4A5E32F123EDB2B0067D908 /* QReachabilityOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E4A5E32E123EDB2B0067D908 /* QReachabilityOperation.m */; }; + E4A5E331123EDD3C0067D908 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4A5E330123EDD3C0067D908 /* SystemConfiguration.framework */; }; + E4CE7D6F121604AF00630951 /* Placeholder.png in Resources */ = {isa = PBXBuildFile; fileRef = E4CE7D6E121604AF00630951 /* Placeholder.png */; }; + E4CE7D771216069E00630951 /* PhotoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E4CE7D761216069E00630951 /* PhotoCell.m */; }; + E4CE7D7F12160A8800630951 /* Placeholder-Bad.png in Resources */ = {isa = PBXBuildFile; fileRef = E4CE7D7E12160A8800630951 /* Placeholder-Bad.png */; }; + E4CE7D981216C0EB00630951 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4CE7D971216C0EB00630951 /* CoreGraphics.framework */; }; + E4CE7DAC1216EAA400630951 /* PhotoDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E4CE7DAB1216EAA400630951 /* PhotoDetailViewController.m */; }; + E4CE7DAE1216EC3B00630951 /* PhotoDetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E4CE7DAD1216EC3B00630951 /* PhotoDetailViewController.xib */; }; + E4ED96A31215A7FC00FCCD77 /* NetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E4ED96A21215A7FC00FCCD77 /* NetworkManager.m */; }; + E4ED96B11215AB7F00FCCD77 /* QLog.m in Sources */ = {isa = PBXBuildFile; fileRef = E4ED96AD1215AB7F00FCCD77 /* QLog.m */; }; + E4ED96B21215AB7F00FCCD77 /* QLogViewer.m in Sources */ = {isa = PBXBuildFile; fileRef = E4ED96AF1215AB7F00FCCD77 /* QLogViewer.m */; }; + E4ED96B31215AB7F00FCCD77 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E4ED96B01215AB7F00FCCD77 /* Settings.bundle */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D6058910D05DD3D006BFB54 /* MVCNetworking.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MVCNetworking.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E40B47CF121C1A2600FD846C /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + E40B47D0121C1A2600FD846C /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + E40B47D1121C1A2600FD846C /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + E40B47D2121C1A2600FD846C /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + E40B47D3121C1A2600FD846C /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + E40B47D4121C1A2600FD846C /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + E40B47D5121C1A2600FD846C /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + E40E8709123A91D500C17F85 /* Placeholder-Deferred.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Placeholder-Deferred.png"; sourceTree = ""; }; + E438FC1B121487EA00FF6CEA /* Photo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Photo.h; sourceTree = ""; }; + E438FC1C121487EA00FF6CEA /* Photo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Photo.m; sourceTree = ""; }; + E438FC1D121487EA00FF6CEA /* PhotoGallery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoGallery.h; sourceTree = ""; }; + E438FC1E121487EA00FF6CEA /* PhotoGallery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PhotoGallery.m; sourceTree = ""; }; + E438FC1F121487EA00FF6CEA /* Photos.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Photos.xcdatamodel; sourceTree = ""; }; + E438FC20121487EA00FF6CEA /* Thumbnail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Thumbnail.h; sourceTree = ""; }; + E438FC21121487EA00FF6CEA /* Thumbnail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Thumbnail.m; sourceTree = ""; }; + E438FC23121487EA00FF6CEA /* QHTTPOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QHTTPOperation.h; sourceTree = ""; }; + E438FC24121487EA00FF6CEA /* QHTTPOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = QHTTPOperation.m; sourceTree = ""; }; + E438FC25121487EA00FF6CEA /* QRunLoopOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRunLoopOperation.h; sourceTree = ""; }; + E438FC26121487EA00FF6CEA /* QRunLoopOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRunLoopOperation.m; sourceTree = ""; }; + E438FC2D121487EB00FF6CEA /* PhotoGalleryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoGalleryViewController.h; sourceTree = ""; }; + E438FC2E121487EB00FF6CEA /* PhotoGalleryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PhotoGalleryViewController.m; sourceTree = ""; }; + E438FC391214890600FF6CEA /* GalleryParserOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GalleryParserOperation.h; sourceTree = ""; }; + E438FC3A1214890600FF6CEA /* GalleryParserOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = GalleryParserOperation.m; sourceTree = ""; }; + E456B7941215B84600317CE6 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + E456B7971215B85500317CE6 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; + E45D9E640DAFDA3E00649782 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + E45D9E650DAFDA3E00649782 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + E45EFC6F121EBA68004CE911 /* MakeThumbnailOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MakeThumbnailOperation.h; sourceTree = ""; }; + E45EFC70121EBA68004CE911 /* MakeThumbnailOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MakeThumbnailOperation.m; sourceTree = ""; }; + E4644C3512314D3F00B87652 /* PhotoGalleryContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoGalleryContext.h; sourceTree = ""; }; + E4644C3612314D3F00B87652 /* PhotoGalleryContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoGalleryContext.m; sourceTree = ""; }; + E464FDEC1218858300170C0E /* SetupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetupViewController.h; sourceTree = ""; }; + E464FDED1218858300170C0E /* SetupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SetupViewController.m; sourceTree = ""; }; + E46C04AC123E1A4300C22427 /* QImageScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QImageScrollView.h; sourceTree = ""; }; + E46C04AD123E1A4300C22427 /* QImageScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QImageScrollView.m; sourceTree = ""; }; + E46C04E7123E44C200C22427 /* RetryingHTTPOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetryingHTTPOperation.h; sourceTree = ""; }; + E46C04E8123E44C200C22427 /* RetryingHTTPOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetryingHTTPOperation.m; sourceTree = ""; }; + E49F0243121437AC00C7DFB3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + E49F0245121437B400C7DFB3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + E49F0247121437BD00C7DFB3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + E4A524961219EAF9004C3B19 /* RecursiveDeleteOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursiveDeleteOperation.h; sourceTree = ""; }; + E4A524971219EAF9004C3B19 /* RecursiveDeleteOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecursiveDeleteOperation.m; sourceTree = ""; }; + E4A5E32D123EDB2B0067D908 /* QReachabilityOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QReachabilityOperation.h; sourceTree = ""; }; + E4A5E32E123EDB2B0067D908 /* QReachabilityOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QReachabilityOperation.m; sourceTree = ""; }; + E4A5E330123EDD3C0067D908 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + E4CB1858121985D500FBA724 /* Read Me About MVCNetworking.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Read Me About MVCNetworking.txt"; sourceTree = ""; wrapsLines = 1; }; + E4CE7D6E121604AF00630951 /* Placeholder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Placeholder.png; sourceTree = ""; }; + E4CE7D751216069E00630951 /* PhotoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoCell.h; sourceTree = ""; }; + E4CE7D761216069E00630951 /* PhotoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PhotoCell.m; sourceTree = ""; }; + E4CE7D7E12160A8800630951 /* Placeholder-Bad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Placeholder-Bad.png"; sourceTree = ""; }; + E4CE7D971216C0EB00630951 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + E4CE7DAA1216EAA400630951 /* PhotoDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoDetailViewController.h; sourceTree = ""; }; + E4CE7DAB1216EAA400630951 /* PhotoDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PhotoDetailViewController.m; sourceTree = ""; }; + E4CE7DAD1216EC3B00630951 /* PhotoDetailViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PhotoDetailViewController.xib; sourceTree = ""; }; + E4ED96A11215A7FC00FCCD77 /* NetworkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkManager.h; sourceTree = ""; }; + E4ED96A21215A7FC00FCCD77 /* NetworkManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = NetworkManager.m; sourceTree = ""; }; + E4ED96AB1215AB7F00FCCD77 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = ""; }; + E4ED96AC1215AB7F00FCCD77 /* QLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLog.h; sourceTree = ""; }; + E4ED96AD1215AB7F00FCCD77 /* QLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLog.m; sourceTree = ""; }; + E4ED96AE1215AB7F00FCCD77 /* QLogViewer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLogViewer.h; sourceTree = ""; }; + E4ED96AF1215AB7F00FCCD77 /* QLogViewer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLogViewer.m; sourceTree = ""; }; + E4ED96B01215AB7F00FCCD77 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E49F0244121437AC00C7DFB3 /* UIKit.framework in Frameworks */, + E456B7981215B85500317CE6 /* MessageUI.framework in Frameworks */, + E49F0248121437BD00C7DFB3 /* CoreData.framework in Frameworks */, + E49F0246121437B400C7DFB3 /* Foundation.framework in Frameworks */, + E4CE7D981216C0EB00630951 /* CoreGraphics.framework in Frameworks */, + E4A5E331123EDD3C0067D908 /* SystemConfiguration.framework in Frameworks */, + E456B7951215B84600317CE6 /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + E4CB1858121985D500FBA724 /* Read Me About MVCNetworking.txt */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 8D1107310486CEB800E47090 /* Info.plist */, + E45D9E640DAFDA3E00649782 /* AppDelegate.h */, + E45D9E650DAFDA3E00649782 /* AppDelegate.m */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + E4CE7D6D121604AF00630951 /* Images */, + E438FC29121487EA00FF6CEA /* View Controllers */, + E438FC1A121487EA00FF6CEA /* Model */, + E438FC22121487EA00FF6CEA /* Networking */, + E4ED96AA1215AB7F00FCCD77 /* Logging */, + E49F0249121437C400C7DFB3 /* Frameworks */, + 1D6058910D05DD3D006BFB54 /* MVCNetworking.app */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + E438FC1A121487EA00FF6CEA /* Model */ = { + isa = PBXGroup; + children = ( + E438FC1D121487EA00FF6CEA /* PhotoGallery.h */, + E438FC1E121487EA00FF6CEA /* PhotoGallery.m */, + E438FC1F121487EA00FF6CEA /* Photos.xcdatamodel */, + E438FC1B121487EA00FF6CEA /* Photo.h */, + E438FC1C121487EA00FF6CEA /* Photo.m */, + E438FC20121487EA00FF6CEA /* Thumbnail.h */, + E438FC21121487EA00FF6CEA /* Thumbnail.m */, + E4644C3512314D3F00B87652 /* PhotoGalleryContext.h */, + E4644C3612314D3F00B87652 /* PhotoGalleryContext.m */, + E45EFC6F121EBA68004CE911 /* MakeThumbnailOperation.h */, + E45EFC70121EBA68004CE911 /* MakeThumbnailOperation.m */, + E4A524961219EAF9004C3B19 /* RecursiveDeleteOperation.h */, + E4A524971219EAF9004C3B19 /* RecursiveDeleteOperation.m */, + ); + path = Model; + sourceTree = ""; + }; + E438FC22121487EA00FF6CEA /* Networking */ = { + isa = PBXGroup; + children = ( + E46C04E7123E44C200C22427 /* RetryingHTTPOperation.h */, + E46C04E8123E44C200C22427 /* RetryingHTTPOperation.m */, + E4ED96A11215A7FC00FCCD77 /* NetworkManager.h */, + E4ED96A21215A7FC00FCCD77 /* NetworkManager.m */, + E438FC391214890600FF6CEA /* GalleryParserOperation.h */, + E438FC3A1214890600FF6CEA /* GalleryParserOperation.m */, + E4A5E32D123EDB2B0067D908 /* QReachabilityOperation.h */, + E4A5E32E123EDB2B0067D908 /* QReachabilityOperation.m */, + E438FC23121487EA00FF6CEA /* QHTTPOperation.h */, + E438FC24121487EA00FF6CEA /* QHTTPOperation.m */, + E438FC25121487EA00FF6CEA /* QRunLoopOperation.h */, + E438FC26121487EA00FF6CEA /* QRunLoopOperation.m */, + ); + path = Networking; + sourceTree = ""; + }; + E438FC29121487EA00FF6CEA /* View Controllers */ = { + isa = PBXGroup; + children = ( + E438FC2D121487EB00FF6CEA /* PhotoGalleryViewController.h */, + E438FC2E121487EB00FF6CEA /* PhotoGalleryViewController.m */, + E4CE7D751216069E00630951 /* PhotoCell.h */, + E4CE7D761216069E00630951 /* PhotoCell.m */, + E4CE7DAA1216EAA400630951 /* PhotoDetailViewController.h */, + E4CE7DAB1216EAA400630951 /* PhotoDetailViewController.m */, + E4CE7DAD1216EC3B00630951 /* PhotoDetailViewController.xib */, + E46C04AC123E1A4300C22427 /* QImageScrollView.h */, + E46C04AD123E1A4300C22427 /* QImageScrollView.m */, + E464FDEC1218858300170C0E /* SetupViewController.h */, + E464FDED1218858300170C0E /* SetupViewController.m */, + ); + path = "View Controllers"; + sourceTree = ""; + }; + E49F0249121437C400C7DFB3 /* Frameworks */ = { + isa = PBXGroup; + children = ( + E49F0243121437AC00C7DFB3 /* UIKit.framework */, + E456B7971215B85500317CE6 /* MessageUI.framework */, + E49F0247121437BD00C7DFB3 /* CoreData.framework */, + E49F0245121437B400C7DFB3 /* Foundation.framework */, + E4CE7D971216C0EB00630951 /* CoreGraphics.framework */, + E4A5E330123EDD3C0067D908 /* SystemConfiguration.framework */, + E456B7941215B84600317CE6 /* libz.dylib */, + ); + name = Frameworks; + sourceTree = ""; + }; + E4CE7D6D121604AF00630951 /* Images */ = { + isa = PBXGroup; + children = ( + E40B47CF121C1A2600FD846C /* Icon-72.png */, + E40B47D0121C1A2600FD846C /* Icon-Small-50.png */, + E40B47D1121C1A2600FD846C /* Icon-Small.png */, + E40B47D2121C1A2600FD846C /* Icon-Small@2x.png */, + E40B47D3121C1A2600FD846C /* Icon.png */, + E40B47D4121C1A2600FD846C /* Icon@2x.png */, + E40B47D5121C1A2600FD846C /* iTunesArtwork */, + E4CE7D6E121604AF00630951 /* Placeholder.png */, + E4CE7D7E12160A8800630951 /* Placeholder-Bad.png */, + E40E8709123A91D500C17F85 /* Placeholder-Deferred.png */, + ); + path = Images; + sourceTree = ""; + }; + E4ED96AA1215AB7F00FCCD77 /* Logging */ = { + isa = PBXGroup; + children = ( + E4ED96AB1215AB7F00FCCD77 /* Logging.h */, + E4ED96AC1215AB7F00FCCD77 /* QLog.h */, + E4ED96AD1215AB7F00FCCD77 /* QLog.m */, + E4ED96AE1215AB7F00FCCD77 /* QLogViewer.h */, + E4ED96AF1215AB7F00FCCD77 /* QLogViewer.m */, + E4ED96B01215AB7F00FCCD77 /* Settings.bundle */, + ); + path = Logging; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MVCNetworking */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MVCNetworking" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MVCNetworking; + productName = MVCNetworking; + productReference = 1D6058910D05DD3D006BFB54 /* MVCNetworking.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MVCNetworking" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MVCNetworking */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + E4ED96B31215AB7F00FCCD77 /* Settings.bundle in Resources */, + E4CE7D6F121604AF00630951 /* Placeholder.png in Resources */, + E4CE7D7F12160A8800630951 /* Placeholder-Bad.png in Resources */, + E4CE7DAE1216EC3B00630951 /* PhotoDetailViewController.xib in Resources */, + E40B47D6121C1A2600FD846C /* Icon-72.png in Resources */, + E40B47D7121C1A2600FD846C /* Icon-Small-50.png in Resources */, + E40B47D8121C1A2600FD846C /* Icon-Small.png in Resources */, + E40B47D9121C1A2600FD846C /* Icon-Small@2x.png in Resources */, + E40B47DA121C1A2600FD846C /* Icon.png in Resources */, + E40B47DB121C1A2600FD846C /* Icon@2x.png in Resources */, + E40B47DC121C1A2600FD846C /* iTunesArtwork in Resources */, + E40E870A123A91D500C17F85 /* Placeholder-Deferred.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + E45D9E660DAFDA3E00649782 /* AppDelegate.m in Sources */, + E438FC2F121487EB00FF6CEA /* Photo.m in Sources */, + E438FC30121487EB00FF6CEA /* PhotoGallery.m in Sources */, + E438FC31121487EB00FF6CEA /* Photos.xcdatamodel in Sources */, + E438FC32121487EB00FF6CEA /* Thumbnail.m in Sources */, + E438FC33121487EB00FF6CEA /* QHTTPOperation.m in Sources */, + E438FC34121487EB00FF6CEA /* QRunLoopOperation.m in Sources */, + E438FC38121487EB00FF6CEA /* PhotoGalleryViewController.m in Sources */, + E438FC3B1214890600FF6CEA /* GalleryParserOperation.m in Sources */, + E4ED96A31215A7FC00FCCD77 /* NetworkManager.m in Sources */, + E4ED96B11215AB7F00FCCD77 /* QLog.m in Sources */, + E4ED96B21215AB7F00FCCD77 /* QLogViewer.m in Sources */, + E4CE7D771216069E00630951 /* PhotoCell.m in Sources */, + E4CE7DAC1216EAA400630951 /* PhotoDetailViewController.m in Sources */, + E464FDEE1218858300170C0E /* SetupViewController.m in Sources */, + E4A524981219EAF9004C3B19 /* RecursiveDeleteOperation.m in Sources */, + E45EFC71121EBA68004CE911 /* MakeThumbnailOperation.m in Sources */, + E4644C3712314D3F00B87652 /* PhotoGalleryContext.m in Sources */, + E46C04AE123E1A4300C22427 /* QImageScrollView.m in Sources */, + E46C04E9123E44C200C22427 /* RetryingHTTPOperation.m in Sources */, + E4A5E32F123EDB2B0067D908 /* QReachabilityOperation.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = MVCNetworking; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = MVCNetworking; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_POSTPROCESSING = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ""; + "GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator4.1][arch=*]" = ( + "$(GCC_PREPROCESSOR_DEFINITIONS)", + "__IPHONE_OS_VERSION_MIN_REQUIRED=30103", + ); + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + WARNING_CFLAGS = ( + "-Wall", + "-Wextra", + "-Wfloat-equal", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wold-style-definition", + ); + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + "GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator4.1][arch=*]" = ( + "$(GCC_PREPROCESSOR_DEFINITIONS)", + "__IPHONE_OS_VERSION_MIN_REQUIRED=30103", + ); + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + WARNING_CFLAGS = ( + "-Wall", + "-Wextra", + "-Wfloat-equal", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wold-style-definition", + ); + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MVCNetworking" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MVCNetworking" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MVCNetworking/MVCNetworking.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/MVCNetworking/MVCNetworking.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..872c231 --- /dev/null +++ b/MVCNetworking/MVCNetworking.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,6 @@ + + + + + diff --git a/MVCNetworking/MainWindow.xib b/MVCNetworking/MainWindow.xib new file mode 100644 index 0000000..5a685c7 --- /dev/null +++ b/MVCNetworking/MainWindow.xib @@ -0,0 +1,260 @@ + + + + 512 + 10F569 + 1179 + 1038.29 + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + 1292 + + {320, 480} + + + + 1 + MSAxIDEAA + + NO + NO + IBCocoaTouchFramework + + + + + + 1 + 1 + + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + NO + YES + YES + IBCocoaTouchFramework + + + + 256 + {{0, 436}, {320, 44}} + + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + YES + + NO + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navController + + + + 20 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + 16 + + + YES + + + + + + + 17 + + + + + 21 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{333, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 21 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navController + window + + + YES + id + id + + + + IBProjectSource + ./classes-xjh84/AppDelegate.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + MVCNetworking.xcodeproj + 3 + 106 + + diff --git a/MVCNetworking/Model/MakeThumbnailOperation.h b/MVCNetworking/Model/MakeThumbnailOperation.h new file mode 100644 index 0000000..19e2a5b --- /dev/null +++ b/MVCNetworking/Model/MakeThumbnailOperation.h @@ -0,0 +1,86 @@ +/* + File: MakeThumbnailOperation.h + + Contains: An NSOperation subclass that creates a thumbnail from image data. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import +#import + +@interface MakeThumbnailOperation : NSOperation +{ + NSData * _imageData; + NSString * _MIMEType; + CGFloat _thumbnailSize; + CGImageRef _thumbnail; +} + +- (id)initWithImageData:(NSData *)imageData MIMEType:(NSString *)MIMEType; + // Configures the operation to create a thumbnail based on the specified data, + // which must be of type "image/jpeg" or "image/png". + +// properties specified at init time + +@property (copy, readonly ) NSData * imageData; +@property (copy, readonly ) NSString * MIMEType; + +// properties that can be changed before starting the operation + +@property (assign, readwrite) CGFloat thumbnailSize; // defaults to 32.0f + +// properties that are valid after the operation is finished + +// thumbnail must be a CGImage rather than a UIImage because I want the code to run on +// iOS 3, and UIKit is completely thread unsafe on iOS 3 (as opposed to mostly thread +// unsafe on iOS 4). + +@property (assign, readonly ) CGImageRef thumbnail; + +@end diff --git a/MVCNetworking/Model/MakeThumbnailOperation.m b/MVCNetworking/Model/MakeThumbnailOperation.m new file mode 100644 index 0000000..907bba6 --- /dev/null +++ b/MVCNetworking/Model/MakeThumbnailOperation.m @@ -0,0 +1,178 @@ +/* + File: MakeThumbnailOperation.m + + Contains: An NSOperation subclass that creates a thumbnail from image data. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "MakeThumbnailOperation.h" + +@implementation MakeThumbnailOperation + +- (id)initWithImageData:(NSData *)imageData MIMEType:(NSString *)MIMEType + // See comment in header. +{ + assert(imageData != nil); + assert(MIMEType != nil); + self = [super init]; + if (self != nil) { + self->_imageData = [imageData copy]; + self->_MIMEType = [MIMEType copy]; + self->_thumbnailSize = 32.0f; + } + return self; +} + +- (void)dealloc +{ + CGImageRelease(self->_thumbnail); + [self->_MIMEType release]; + [self->_imageData release]; + [super dealloc]; +} + +@synthesize imageData = _imageData; +@synthesize MIMEType = _MIMEType; + +@synthesize thumbnailSize = _thumbnailSize; + +@synthesize thumbnail = _thumbnail; + +- (void)main +{ + CGDataProviderRef provider; + CGImageRef sourceImage; + CGFloat thumbnailSize; + + // Latch thumbnailSize for performance, and also to prevent it changing out from underneath us. + + thumbnailSize = self.thumbnailSize; + + assert(self.imageData != nil); + assert(self.MIMEType != nil); + + // Set up the source CGImage. + + provider = CGDataProviderCreateWithCFData( (CFDataRef) self.imageData); + assert(provider != NULL); + + if ( [self.MIMEType isEqual:@"image/jpeg"] ) { + sourceImage = CGImageCreateWithJPEGDataProvider(provider, NULL, true, kCGRenderingIntentDefault); + } else if ( [self.MIMEType isEqual:@"image/png"] ) { + sourceImage = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault); + } else { + sourceImage = NULL; + } + + // Render it to a bitmap context and then create an image from that context. + + if (sourceImage != NULL) { + static const CGFloat kWhite[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + CGColorRef white; + CGContextRef context; + CGColorSpaceRef space; + + space = CGColorSpaceCreateDeviceRGB(); + assert(space != NULL); + + white = CGColorCreate(space, kWhite); + assert(white != NULL); + + // Create the context that's thumbnailSize x thumbnailSize. + + context = CGBitmapContextCreate(NULL, thumbnailSize, thumbnailSize, 8, 0, space, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); + if (context != NULL) { + CGRect r; + + // Make sure anything we don't cover comes out white. While the next + // steps ensures that we cover the entire image, there's a possibility + // that we're dealing with a transparent PNG. + + CGContextSetFillColorWithColor(context, white); + CGContextFillRect(context, CGRectMake(0.0f, 0.0f, thumbnailSize, thumbnailSize)); + + // Calculate the drawing rectangle so that the image fills the entire + // thumbnail. That is, for a tall image, we scale it so that the + // width matches thumbnailSize and the it's centred vertically. + // Similarly for a wide image. + + r = CGRectZero; + r.size.width = CGImageGetWidth(sourceImage); + r.size.height = CGImageGetWidth(sourceImage); + if (r.size.height > r.size.width) { + // tall image + r.size.height = (r.size.height / r.size.width) * thumbnailSize; + r.size.width = thumbnailSize; + r.origin.y = - ((r.size.height - thumbnailSize) / 2); + } else { + // wide image + r.size.width = (r.size.width / r.size.height) * thumbnailSize; + r.size.height = thumbnailSize; + r.origin.x = - ((r.size.width - thumbnailSize) / 2); + } + + // Draw the source image and get then create the thumbnail from the + // context. + + CGContextDrawImage(context, r, sourceImage); + + self->_thumbnail = CGBitmapContextCreateImage(context); + assert(self->_thumbnail != NULL); + } + + CGContextRelease(context); + CGColorSpaceRelease(space); + CGColorRelease(white); + } + + CGImageRelease(sourceImage); + CGDataProviderRelease(provider); +} + +@end diff --git a/MVCNetworking/Model/Photo.h b/MVCNetworking/Model/Photo.h new file mode 100644 index 0000000..9505814 --- /dev/null +++ b/MVCNetworking/Model/Photo.h @@ -0,0 +1,125 @@ +/* + File: Photo.h + + Contains: Model object for a photo. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +#import + +// When trying to figure out Core Data issues, it's useful to know what photo ID a +// particular Photo object corresponds to, even if Core Data has forgetten that +// information (for example, after the object has been deleted, and hence turned +// into a fault). So, if you set MVCNETWORKING_KEEP_PHOTO_ID_BACKUP each Photo keeps +// its own record of the photoID, outside of the scope of Core Data. + +#if ! defined(MVCNETWORKING_KEEP_PHOTO_ID_BACKUP) + #define MVCNETWORKING_KEEP_PHOTO_ID_BACKUP 0 +#endif + +extern const CGFloat kThumbnailSize; + +@class Thumbnail; +@class RetryingHTTPOperation; +@class MakeThumbnailOperation; + +@interface Photo : NSManagedObject +{ +#if MVCNETWORKING_KEEP_PHOTO_ID_BACKUP + NSString * _photoIDBackup; +#endif + UIImage * _thumbnailImage; + BOOL _thumbnailImageIsPlaceholder; + RetryingHTTPOperation * _thumbnailGetOperation; + MakeThumbnailOperation * _thumbnailResizeOperation; + RetryingHTTPOperation * _photoGetOperation; + NSString * _photoGetFilePath; + NSUInteger _photoNeededAssertions; + NSError * _photoGetError; +} + ++ (Photo *)insertNewPhotoWithProperties:(NSDictionary *)properties inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext; + // Creates a photo with the specified properties in the specified context. + // The properties dictionary is keyed by property names, in a KVC fashion. + +- (void)updateWithProperties:(NSDictionary *)properties; + // Updates the photo with the specified properties. This will update the various + // readonly properties listed below, triggering KVO notifications along the way. + +@property (nonatomic, retain, readonly ) NSString * photoID; // immutable, unique ID for the photo within this database +@property (nonatomic, retain, readonly ) NSString * displayName; // observable, user-visible name of the photo +@property (nonatomic, retain, readonly ) NSDate * date; // observable, date associated with the photo +@property (nonatomic, retain, readonly ) NSString * localPhotoPath; // observable, path of the photo file on disk, relative to the PhotoGalleryContext photosDirectoryPath, or nil if not downloaded +@property (nonatomic, retain, readonly ) NSString * remotePhotoPath; // observable, URL path of the photo, relative to the PhotoGalleryContext galleryURLString +@property (nonatomic, retain, readonly ) NSString * remoteThumbnailPath; // observable, URL path of the thumbnail, relative to the PhotoGalleryContext galleryURLString + +@property (nonatomic, retain, readonly ) Thumbnail * thumbnail; // observable, pointer to the Thumbnail object, or nil if not downloaded + +@property (nonatomic, retain, readonly ) UIImage * thumbnailImage; // observable, returns a placeholder if the thumbnail isn't available yet. +@property (nonatomic, retain, readonly ) UIImage * photoImage; // observable, returns nil if the photo isn't available yet + +// The Photo object does not download the full photo (that is, photoImage) unless someone wants to +// display it. Clients should register and unregister their interest in the full photo using these +// methods. + +- (void)assertPhotoNeeded; +- (void)deassertPhotoNeeded; + +// Status properties for the photo download operation. Note that photoGetError is only really +// interesting if photoImage is nil (indicating that the photo hasn't been downloaded), +// photoGetting is NO (indicating that the photo is not in the process of being downloaded), +// -assertPhotoNeeded has been called (indicating that someone actually wants the photo). +// In that case, photoGetError contains the error from the most recent photo get attempt. + +@property (nonatomic, assign, readonly ) BOOL photoGetting; // observable +@property (nonatomic, copy, readonly ) NSError * photoGetError; // observable + +@end diff --git a/MVCNetworking/Model/Photo.m b/MVCNetworking/Model/Photo.m new file mode 100644 index 0000000..3511764 --- /dev/null +++ b/MVCNetworking/Model/Photo.m @@ -0,0 +1,807 @@ +/* + File: Photo.m + + Contains: Model object for a photo. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "Photo.h" + +#import "Thumbnail.h" + +#import "PhotoGalleryContext.h" + +#import "MakeThumbnailOperation.h" + +#import "NetworkManager.h" + +#import "RetryingHTTPOperation.h" +#import "QHTTPOperation.h" + +#import "Logging.h" + +// After downloading a thumbnail this code automatically reduces the image to a square +// that's kThumbnailSize x kThumbnailSize. This is not exactly elegant (what if some +// other client wanted a different thumbnail size?), but it is very convenient. It +// means we can store the data for the reduced thumbnail image in the database, making +// it very quick to access. It also means the photo reduce operation is done by this +// code, right next to the photo get operation. +// +// Ideally you would have a one-to-many relationship between Photo and Thumbnail objects, +// and the thumbnail would record its own size. That would allow you to keep thumbnails +// around for many different clients simultaneously. I considered that option but decided +// that it was too complex for this sample. + +const CGFloat kThumbnailSize = 60.0f; + +@interface Photo () + +// read/write versions of public properties + +// IMPORTANT: The default implementation of a managed object property setter does not +// copy the incoming value. We could fix this by writing our own setters, but that's a +// pain. Instead, we take care to only assign values that are immutable, or to copy the +// values ourself. We can do this because the properties are readonly to our external clients. + +@property (nonatomic, retain, readwrite) NSString * photoID; +@property (nonatomic, retain, readwrite) NSString * displayName; +@property (nonatomic, retain, readwrite) NSDate * date; +@property (nonatomic, retain, readwrite) NSString * localPhotoPath; +@property (nonatomic, retain, readwrite) NSString * remotePhotoPath; +@property (nonatomic, retain, readwrite) NSString * remoteThumbnailPath; + +@property (nonatomic, retain, readwrite) Thumbnail * thumbnail; + +@property (nonatomic, copy, readwrite) NSError * photoGetError; + +// private properties + +@property (nonatomic, retain, readonly ) PhotoGalleryContext * photoGalleryContext; +@property (nonatomic, retain, readwrite) RetryingHTTPOperation * thumbnailGetOperation; +@property (nonatomic, retain, readwrite) MakeThumbnailOperation * thumbnailResizeOperation; +@property (nonatomic, retain, readwrite) RetryingHTTPOperation * photoGetOperation; +@property (nonatomic, copy, readwrite) NSString * photoGetFilePath; +@property (nonatomic, assign, readwrite) BOOL thumbnailImageIsPlaceholder; + +// forward declarations + +- (void)updateThumbnail; +- (void)updatePhoto; + +- (void)thumbnailCommitImage:(UIImage *)image isPlaceholder:(BOOL)isPlaceholder; +- (void)thumbnailCommitImageData:(UIImage *)image; + +@end + +@implementation Photo + ++ (Photo *)insertNewPhotoWithProperties:(NSDictionary *)properties inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext + // See comment in header. +{ + Photo * result; + + assert(properties != nil); + assert( [[properties objectForKey:@"photoID"] isKindOfClass:[NSString class]] ); + assert( [[properties objectForKey:@"displayName"] isKindOfClass:[NSString class]] ); + assert( [[properties objectForKey:@"date"] isKindOfClass:[NSDate class]] ); + assert( [[properties objectForKey:@"remotePhotoPath"] isKindOfClass:[NSString class]] ); + assert( [[properties objectForKey:@"remoteThumbnailPath"] isKindOfClass:[NSString class]] ); + assert(managedObjectContext != nil); + + result = (Photo *) [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:managedObjectContext]; + if (result != nil) { + assert([result isKindOfClass:[Photo class]]); + + result.photoID = [[[properties objectForKey:@"photoID"] copy] autorelease]; + assert(result.photoID != nil); + #if MVCNETWORKING_KEEP_PHOTO_ID_BACKUP + result->_photoIDBackup = [result.photoID copy]; + #endif + result.displayName = [[[properties objectForKey:@"displayName"] copy] autorelease]; + result.date = [[[properties objectForKey:@"date"] copy] autorelease]; + result.remotePhotoPath = [[[properties objectForKey:@"remotePhotoPath"] copy] autorelease]; + result.remoteThumbnailPath = [[[properties objectForKey:@"remoteThumbnailPath"] copy] autorelease]; + } + return result; +} + +#if MVCNETWORKING_KEEP_PHOTO_ID_BACKUP + +- (id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context + // In the debug build we maintain _photoIDBackup to assist with debugging. +{ + self = [super initWithEntity:entity insertIntoManagedObjectContext:context]; + if (self != nil) { + self->_photoIDBackup = [self.photoID copy]; + } + return self; +} + +#endif + +- (void)dealloc +{ + #if MVCNETWORKING_KEEP_PHOTO_ID_BACKUP + [self->_photoIDBackup release]; + #endif + [self->_thumbnailImage release]; + assert(self->_thumbnailGetOperation == nil); // As far as I can tell there are only two ways for these objects to get deallocated, + assert(self->_thumbnailResizeOperation == nil); // namely, the object being deleted and the entire managed object context going away + assert(self->_photoGetOperation == nil); // (which turns the object into a fault). In both cases -stop runs, which shuts down + assert(self->_photoGetFilePath == nil); // this stuff. But the asserts are here, just to be sure. + [self->_photoGetError release]; + [super dealloc]; +} + +- (void)updateWithProperties:(NSDictionary *)properties + // See comment in header. +{ + #pragma unused(properties) + BOOL thumbnailNeedsUpdate; + BOOL photoNeedsUpdate; + + assert( [self.photoID isEqual:[properties objectForKey:@"photoID"]] ); + assert( [[properties objectForKey:@"displayName"] isKindOfClass:[NSString class]] ); + assert( [[properties objectForKey:@"date"] isKindOfClass:[NSDate class]] ); + assert( [[properties objectForKey:@"remotePhotoPath"] isKindOfClass:[NSString class]] ); + assert( [[properties objectForKey:@"remoteThumbnailPath"] isKindOfClass:[NSString class]] ); + + if ( ! [self.displayName isEqual:[properties objectForKey:@"displayName"]] ) { + self.displayName = [[[properties objectForKey:@"displayName"] copy] autorelease]; + } + + thumbnailNeedsUpdate = NO; + photoNeedsUpdate = NO; + + // Look at the date and the various remote paths and decide what needs updating. + + if ( ! [self.date isEqual:[properties objectForKey:@"date"]] ) { + self.date = [[[properties objectForKey:@"date"] copy] autorelease]; + thumbnailNeedsUpdate = YES; + photoNeedsUpdate = YES; + } + if ( ! [self.remotePhotoPath isEqual:[properties objectForKey:@"remotePhotoPath"]] ) { + self.remotePhotoPath = [[[properties objectForKey:@"remotePhotoPath"] copy] autorelease]; + photoNeedsUpdate = YES; + } + if ( ! [self.remoteThumbnailPath isEqual:[properties objectForKey:@"remoteThumbnailPath"]] ) { + self.remoteThumbnailPath = [[[properties objectForKey:@"remoteThumbnailPath"] copy] autorelease]; + thumbnailNeedsUpdate = YES; + } + + // Do the updates. + + if (thumbnailNeedsUpdate) { + [self updateThumbnail]; + } + if (photoNeedsUpdate) { + [self updatePhoto]; + } +} + +@dynamic photoID; +@dynamic displayName; +@dynamic date; +@dynamic localPhotoPath; +@dynamic remotePhotoPath; +@dynamic remoteThumbnailPath; + +@dynamic thumbnail; + +- (PhotoGalleryContext *)photoGalleryContext +{ + PhotoGalleryContext * result; + + result = (PhotoGalleryContext *) [self managedObjectContext]; + assert( [result isKindOfClass:[PhotoGalleryContext class]] ); + + return result; +} + +- (BOOL)stopThumbnail +{ + BOOL didSomething; + + didSomething = NO; + if (self.thumbnailGetOperation != nil) { + [self.thumbnailGetOperation removeObserver:self forKeyPath:@"hasHadRetryableFailure"]; + [[NetworkManager sharedManager] cancelOperation:self.thumbnailGetOperation]; + self.thumbnailGetOperation = nil; + didSomething = YES; + } + if (self.thumbnailResizeOperation != nil) { + [[NetworkManager sharedManager] cancelOperation:self.thumbnailResizeOperation]; + self.thumbnailResizeOperation = nil; + didSomething = YES; + } + return didSomething; +} + +- (void)stop + // Stops all async activity on the object. +{ + BOOL didSomething; + + // If we're currently fetching the thumbnail, cancel that. + + didSomething = [self stopThumbnail]; + if (didSomething) { + [[QLog log] logWithFormat:@"photo %@ thumbnail get stopped", self.photoID]; + } + + // If we're currently fetching the photo, cancel that. + + if (self.photoGetOperation != nil) { + [[NetworkManager sharedManager] cancelOperation:self.photoGetOperation]; + self.photoGetOperation = nil; + if (self.photoGetFilePath != nil) { + (void) [[NSFileManager defaultManager] removeItemAtPath:self.photoGetFilePath error:NULL]; + self.photoGetFilePath = nil; + } + [[QLog log] logWithFormat:@"photo %@ photo get stopped", self.photoID]; + } +} + +- (void)prepareForDeletion + // We have to override prepareForDeletion in order to get rid of the photo + // file. We take the opportunity to stop any async operations at the + // same time. We'll get a second bite of that cherry in -willTurnIntoFault, + // but we might as well do it now. +{ + BOOL success; + + [[QLog log] logWithFormat:@"photo %@ deleted", self.photoID]; + + // Stop any asynchronous operations. + + [self stop]; + + // Delete the photo file if it exists on disk. + + if (self.localPhotoPath != nil) { + success = [[NSFileManager defaultManager] removeItemAtPath:[self.photoGalleryContext.photosDirectoryPath stringByAppendingPathComponent:self.localPhotoPath] error:NULL]; + assert(success); + } + + [super prepareForDeletion]; +} + +- (void)willTurnIntoFault + // There are three common reasons for turning into a fault: + // + // o Core Data has decided we're uninteresting, and is reclaiming our memory. + // o We're in the process of being deleted. + // o The managed object context itself is going away. + // + // Regardless of the reason, if we turn into a fault we can any async + // operations on the object. This is especially important in the last + // case, where Core Data can't satisfy any fault requests (and, unlike in + // the delete case, we didn't get a chance to stop our async operations in + // -prepareForDelete). +{ + [self stop]; + [super willTurnIntoFault]; +} + +#pragma mark * Thumbnails + +@synthesize thumbnailGetOperation = _thumbnailGetOperation; +@synthesize thumbnailResizeOperation = _thumbnailResizeOperation; +@synthesize thumbnailImageIsPlaceholder = _thumbnailImageIsPlaceholder; + +- (void)startThumbnailGet + // Starts the HTTP operation to GET the photo's thumbnail. +{ + NSURLRequest * request; + + assert(self.remoteThumbnailPath != nil); + assert(self.thumbnailGetOperation == nil); + assert(self.thumbnailResizeOperation == nil); + + request = [self.photoGalleryContext requestToGetGalleryRelativeString:self.remoteThumbnailPath]; + if (request == nil) { + [[QLog log] logWithFormat:@"photo %@ thumbnail get bad path '%@'", self.photoID, self.remoteThumbnailPath]; + [self thumbnailCommitImage:nil isPlaceholder:YES]; + } else { + self.thumbnailGetOperation = [[[RetryingHTTPOperation alloc] initWithRequest:request] autorelease]; + assert(self.thumbnailGetOperation != nil); + + [self.thumbnailGetOperation setQueuePriority:NSOperationQueuePriorityLow]; + self.thumbnailGetOperation.acceptableContentTypes = [NSSet setWithObjects:@"image/jpeg", @"image/png", nil]; + + [[QLog log] logWithFormat:@"photo %@ thumbnail get start '%@'", self.photoID, self.remoteThumbnailPath]; + + [self.thumbnailGetOperation addObserver:self forKeyPath:@"hasHadRetryableFailure" options:0 context:&self->_thumbnailImage]; + + [[NetworkManager sharedManager] addNetworkManagementOperation:self.thumbnailGetOperation finishedTarget:self action:@selector(thumbnailGetDone:)]; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == &self->_thumbnailImage) { + assert(object == self.thumbnailGetOperation); + assert( [keyPath isEqual:@"hasHadRetryableFailure"] ); + assert([NSThread isMainThread]); + + // If we're currently showing a placeholder and the network operation + // indicates that it's had one failure, change the placeholder to the deferred + // placeholder. The test for thumbnailImageIsPlaceholder is necessary in the + // -updateThumbnail case because we don't want to replace a valid (but old) + // thumbnail with a placeholder. + + if (self.thumbnailImageIsPlaceholder && self.thumbnailGetOperation.hasHadRetryableFailure) { + [self thumbnailCommitImage:[UIImage imageNamed:@"Placeholder-Deferred.png"] isPlaceholder:YES]; + } + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (void)thumbnailGetDone:(RetryingHTTPOperation *)operation + // Called when the HTTP operation to GET the photo's thumbnail completes. + // If all is well, we start a resize operation to reduce it the appropriate + // size. +{ + assert([NSThread isMainThread]); + assert([operation isKindOfClass:[RetryingHTTPOperation class]]); + assert(operation == self.thumbnailGetOperation); + assert([self.thumbnailGetOperation isFinished]); + + assert(self.thumbnailResizeOperation == nil); + + [[QLog log] logWithFormat:@"photo %@ thumbnail get done", self.photoID]; + + if (operation.error != nil) { + [[QLog log] logWithFormat:@"photo %@ thumbnail get error %@", self.photoID, operation.error]; + [self thumbnailCommitImage:nil isPlaceholder:YES]; + (void) [self stopThumbnail]; + } else { + [[QLog log] logOption:kLogOptionNetworkData withFormat:@"receive %@", operation.responseContent]; + + // Got the data successfully. Let's start the resize operation. + + self.thumbnailResizeOperation = [[[MakeThumbnailOperation alloc] initWithImageData:operation.responseContent MIMEType:operation.responseMIMEType] autorelease]; + assert(self.thumbnailResizeOperation != nil); + + self.thumbnailResizeOperation.thumbnailSize = kThumbnailSize; + + // We want thumbnails resizes to soak up unused CPU time, but the main thread should + // always run if it can. The operation priority is a relative value (courtesy of the + // underlying Mach THREAD_PRECEDENCE_POLICY), that is, it sets the priority relative + // to other threads in the same process. A value of 0.5 is the default, so we set a + // value significantly lower than that. + + if ( [self.thumbnailResizeOperation respondsToSelector:@selector(setThreadPriority:)] ) { + [self.thumbnailResizeOperation setThreadPriority:0.2]; + } + [self.thumbnailResizeOperation setQueuePriority:NSOperationQueuePriorityLow]; + + [[NetworkManager sharedManager] addCPUOperation:self.thumbnailResizeOperation finishedTarget:self action:@selector(thumbnailResizeDone:)]; + } +} + +- (void)thumbnailResizeDone:(MakeThumbnailOperation *)operation + // Called when the operation to resize the thumbnail completes. + // If all is well, we commit the thumbnail to our database. +{ + UIImage * image; + + assert([NSThread isMainThread]); + assert([operation isKindOfClass:[MakeThumbnailOperation class]]); + assert(operation == self.thumbnailResizeOperation); + assert([self.thumbnailResizeOperation isFinished]); + + [[QLog log] logWithFormat:@"photo %@ thumbnail resize done", self.photoID]; + + if (operation.thumbnail == NULL) { + [[QLog log] logWithFormat:@"photo %@ thumbnail resize failed", self.photoID]; + image = nil; + } else { + image = [UIImage imageWithCGImage:operation.thumbnail]; + assert(image != nil); + } + + [self thumbnailCommitImage:image isPlaceholder:NO]; + [self stopThumbnail]; +} + +- (void)thumbnailCommitImage:(UIImage *)image isPlaceholder:(BOOL)isPlaceholder + // Commits the thumbnail image to the object itself and to the Core Data database. +{ + // If we were given no image, that's a shortcut for the bad image placeholder. In + // that case we ignore the incoming value of placeholder and force it to YES. + + if (image == nil) { + isPlaceholder = YES; + image = [UIImage imageNamed:@"Placeholder-Bad.png"]; + assert(image != nil); + } + + // If it was a placeholder, someone else has logged about the failure, so + // we only log for real thumbnails. + + if ( ! isPlaceholder ) { + [[QLog log] logWithFormat:@"photo %@ thumbnail commit", self.photoID]; + } + + // If we got a non-placeholder image, commit its PNG representation into our thumbnail + // database. To avoid the scroll view stuttering, we only want to do this if the run loop + // is running in the default mode. Thus, we check the mode and either do it directly or + // defer the work until the next time the default run loop mode runs. + // + // If we were running on iOS 4 or later we could get the PNG representation using + // ImageIO, but I want to maintain iOS 3 compatibility for the moment and on that + // system we have to use UIImagePNGRepresentation. + + if ( ! isPlaceholder ) { + if ( [[[NSRunLoop currentRunLoop] currentMode] isEqual:NSDefaultRunLoopMode] ) { + [self thumbnailCommitImageData:image]; + } else { + [self performSelector:@selector(thumbnailCommitImageData:) withObject:image afterDelay:0.0 inModes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; + } + } + + // Commit the change to our thumbnailImage property. + + [self willChangeValueForKey:@"thumbnailImage"]; + [self->_thumbnailImage release]; + self->_thumbnailImage = [image retain]; + [self didChangeValueForKey:@"thumbnailImage"]; +} + +- (void)thumbnailCommitImageData:(UIImage *)image + // Commits the thumbnail data to the Core Data database. +{ + [[QLog log] logWithFormat:@"photo %@ thumbnail commit image data", self.photoID]; + + // If we have no thumbnail object, create it. + + if (self.thumbnail == nil) { + self.thumbnail = [NSEntityDescription insertNewObjectForEntityForName:@"Thumbnail" inManagedObjectContext:self.managedObjectContext]; + assert(self.thumbnail != nil); + } + + // Stash the data in the thumbnail object's imageData property. + + if (self.thumbnail.imageData == nil) { + self.thumbnail.imageData = UIImagePNGRepresentation(image); + assert(self.thumbnail.imageData != nil); + } +} + +- (UIImage *)thumbnailImage +{ + if (self->_thumbnailImage == nil) { + if ( (self.thumbnail != nil) && (self.thumbnail.imageData != nil) ) { + + // If we have a thumbnail from the database, return that. + + self.thumbnailImageIsPlaceholder = NO; + self->_thumbnailImage = [[UIImage alloc] initWithData:self.thumbnail.imageData]; + assert(self->_thumbnailImage != nil); + } else { + assert(self.thumbnailGetOperation == nil); // These should be nil because the only code paths that start + assert(self.thumbnailResizeOperation == nil); // a get also ensure there's a thumbnail in place (either a + // placeholder or the old thumbnail). + + // Otherwise, return the placeholder and kick off a get (unless we're + // already getting). + + self.thumbnailImageIsPlaceholder = YES; + self->_thumbnailImage = [[UIImage imageNamed:@"Placeholder.png"] retain]; + assert(self->_thumbnailImage != nil); + + [self startThumbnailGet]; + } + } + return self->_thumbnailImage; +} + +- (void)updateThumbnail + // Updates the thumbnail is response to a change in the photo's XML entity. +{ + [[QLog log] logWithFormat:@"photo %@ update thumbnail", self.photoID]; + + // We only do an update if we've previously handed out a thumbnail image. + // If not, the thumbnail will be fetched normally when the client first + // requests an image. + + if (self->_thumbnailImage != nil) { + + // If we're already getting a thumbnail, stop that get (it may be getting from + // the old path). + + (void) [self stopThumbnail]; + + // Nix our thumbnail data. This ensures that, if we quit before the get is complete, + // then, on relaunch, we will notice that we need to get the thumbnail. + + if (self.thumbnail != nil) { + self.thumbnail.imageData = nil; + } + + // Kick off the network get. Note that we don't nix _thumbnailImage here. The client + // will continue to see the old thumbnail (which might be a placeholder) until the + // get completes. + + [self startThumbnailGet]; + } +} + +#pragma mark * Photos + +@synthesize photoGetOperation = _photoGetOperation; +@synthesize photoGetFilePath = _photoGetFilePath; +@synthesize photoGetError = _photoGetError; + +- (void)startPhotoGet + // Starts the HTTP operation to GET the photo itself. +{ + NSURLRequest * request; + + assert(self.remotePhotoPath != nil); + // assert(self.localPhotoPath == nil); -- May be non-nil when we're updating the photo. + assert( ! self.photoGetting ); + + assert(self.photoGetOperation == nil); + assert(self.photoGetFilePath == nil); + + self.photoGetError = nil; + + request = [self.photoGalleryContext requestToGetGalleryRelativeString:self.remotePhotoPath]; + if (request == nil) { + [[QLog log] logWithFormat:@"photo %@ photo get bad path '%@'", self.photoID, self.remotePhotoPath]; + self.photoGetError = [NSError errorWithDomain:kQHTTPOperationErrorDomain code:400 userInfo:nil]; + } else { + + // We start by downloading the photo to a temporary file. Create an output stream + // for that file. + + self.photoGetFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"PhotoTemp-%.9f", [NSDate timeIntervalSinceReferenceDate]]]; + assert(self.photoGetFilePath != nil); + + // Create, configure, and start the download operation. + + self.photoGetOperation = [[[RetryingHTTPOperation alloc] initWithRequest:request] autorelease]; + assert(self.photoGetOperation != nil); + + [self.photoGetOperation setQueuePriority:NSOperationQueuePriorityHigh]; + self.photoGetOperation.responseFilePath = self.photoGetFilePath; + self.photoGetOperation.acceptableContentTypes = [NSSet setWithObjects:@"image/jpeg", @"image/png", nil]; + + [[QLog log] logWithFormat:@"photo %@ photo get start '%@'", self.photoID, self.remotePhotoPath]; + + [[NetworkManager sharedManager] addNetworkManagementOperation:self.photoGetOperation finishedTarget:self action:@selector(photoGetDone:)]; + } +} + +- (void)photoGetDone:(RetryingHTTPOperation *)operation + // Called when the HTTP operation to GET the photo completes. + // If all is well, we commit the photo to the database. +{ + assert([NSThread isMainThread]); + assert([operation isKindOfClass:[RetryingHTTPOperation class]]); + assert(operation == self.photoGetOperation); + + [[QLog log] logWithFormat:@"photo %@ photo get done", self.photoID]; + + if (operation.error != nil) { + [[QLog log] logWithFormat:@"photo %@ photo get error %@", self.photoID, operation.error]; + self.photoGetError = operation.error; + } else { + BOOL success; + NSString * type; + NSString * extension; + NSString * fileName; + NSUInteger fileCounter; + NSError * error; + + // Can't log the incoming data becauses it went directly to disk. + // + // [[QLog log] logOption:kLogOptionNetworkData withFormat:@"receive %@", operation.responseContent]; + + // Just to keep things sane, we set the file name extension based on the MIME type. + + type = operation.responseMIMEType; + assert(type != nil); + if ([type isEqual:@"image/png"]) { + extension = @"png"; + } else { + assert([type isEqual:@"image/jpeg"]); + extension = @"jpg"; + } + + // Move the file to the gallery's photo directory, and if that's successful, set localPhotoPath + // to point to it. We automatically rename the file to avoid conflicts. Conflicts do happen + // in day-to-day operations (specifically, in the case where we update a photo while actually + // displaying that photo). + + fileCounter = 0; + do { + fileName = [NSString stringWithFormat:@"Photo-%@-%zu.%@", self.photoID, (size_t) fileCounter, extension]; + assert(fileName != nil); + + success = [[NSFileManager defaultManager] moveItemAtPath:self.photoGetFilePath toPath:[self.photoGalleryContext.photosDirectoryPath stringByAppendingPathComponent:fileName] error:&error]; + if ( success ) { + self.photoGetFilePath = nil; + break; + } + fileCounter += 1; + if (fileCounter > 100) { + break; + } + } while (YES); + + // On success, update localPhotoPath to point to the newly downloaded photo + // and then delete the previous photo (if any). + + if (success) { + NSString * oldLocalPhotoPath; + + oldLocalPhotoPath = [[self.localPhotoPath copy] autorelease]; + + [[QLog log] logWithFormat:@"photo %@ photo get commit '%@'", self.photoID, fileName]; + self.localPhotoPath = fileName; + assert(self.photoGetError == nil); + + if (oldLocalPhotoPath != nil) { + [[QLog log] logWithFormat:@"photo %@ photo cleanup '%@'", self.photoID, oldLocalPhotoPath]; + (void) [[NSFileManager defaultManager] removeItemAtPath:[self.photoGalleryContext.photosDirectoryPath stringByAppendingPathComponent:oldLocalPhotoPath] error:NULL]; + } + } else { + assert(error != nil); + [[QLog log] logWithFormat:@"photo %@ photo get commit failed %@", self.photoID, error]; + self.photoGetError = error; + } + } + + // Clean up. + + self.photoGetOperation = nil; + if (self.photoGetFilePath != nil) { + (void) [[NSFileManager defaultManager] removeItemAtPath:self.photoGetFilePath error:NULL]; + self.photoGetFilePath = nil; + } +} + ++ (NSSet *)keyPathsForValuesAffectingPhotoImage +{ + return [NSSet setWithObject:@"localPhotoPath"]; +} + +- (UIImage *)photoImage + // See comment in header. +{ + UIImage * result; + + // Note that we don't retain the photo here. Photos are large, and holding on to them here + // is probably a mistake. It's likely that the caller is going to retain the photo anyway + // (by putting it into an image view, say). + + if (self.localPhotoPath == nil) { + result = nil; + } else { + result = [UIImage imageWithContentsOfFile:[self.photoGalleryContext.photosDirectoryPath stringByAppendingPathComponent:self.localPhotoPath]]; + if (result == nil) { + [[QLog log] logWithFormat:@"photo %@ photo data bad", self.photoID]; + } + } + return result; +} + ++ (NSSet *)keyPathsForValuesAffectingPhotoGetting +{ + return [NSSet setWithObject:@"photoGetOperation"]; +} + +- (BOOL)photoGetting + // See comment in header. +{ + return (self.photoGetOperation != nil); +} + +- (void)assertPhotoNeeded + // See comment in header. +{ + self->_photoNeededAssertions += 1; + if ( (self.localPhotoPath == nil) && ! self.photoGetting ) { + [self startPhotoGet]; + } +} + +- (void)deassertPhotoNeeded + // See comment in header. +{ + assert(self->_photoNeededAssertions != 0); + self->_photoNeededAssertions -= 1; +} + +- (void)updatePhoto + // Updates the photo is response to a change in the photo's XML entity. +{ + [[QLog log] logWithFormat:@"photo %@ update photo", self.photoID]; + + // We only fetch the photo is someone is actively looking at it. Otherwise + // we just nix our record of the photo and fault it in as per usual the next + // time that someone asserts that they need it. + + if (self->_photoNeededAssertions == 0) { + + // No one is actively looking at the photo. If we have the photo downloaded, + // just forget about it. + + if (self.localPhotoPath != nil) { + [[QLog log] logWithFormat:@"photo %@ photo delete old photo '%@'", self.photoID, self.localPhotoPath]; + [[NSFileManager defaultManager] removeItemAtPath:[self.photoGalleryContext.photosDirectoryPath stringByAppendingPathComponent:self.localPhotoPath] error:NULL]; + self.localPhotoPath = nil; + } + } else { + + // If we're already getting the photo, stop that get (it may be getting from + // the old path). + + if (self.photoGetOperation != nil) { + [[NetworkManager sharedManager] cancelOperation:self.photoGetOperation]; + self.photoGetOperation = nil; + } + + // Someone is actively looking at the photo. We start a new download, which + // will download the new photo to a new file. When that completes, it will + // change localPhotoPath to point to the new file and then delete the old + // file. + // + // Note that we don't trigger a KVO notification on photoImage at this point. + // Instead we leave the user looking at the old photo; it's better than nothing (-: + + [self startPhotoGet]; + } +} + +@end diff --git a/MVCNetworking/Model/PhotoGallery.h b/MVCNetworking/Model/PhotoGallery.h new file mode 100644 index 0000000..25add5e --- /dev/null +++ b/MVCNetworking/Model/PhotoGallery.h @@ -0,0 +1,151 @@ +/* + File: PhotoGallery.h + + Contains: A model object that represents a gallery of photos on the network. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +/* + This class manages a collection of photos from a gallery on the network at a + specified URL. You construct it with the URL of the gallery. It then attempts + to find a corresponding gallery cache in the caches directory. If not is found, + it creates a new blank one. Within that gallery cache there is a Core Data + database that holds the model objects and a "Photos" directory that stores actual + photos. Thus this class owns the Core Data managed object context that's used by + other parts of the application, and it exports certain aspects of that context + to help out things like the PhotoGalleryViewController. + + This class takes care of downloading the XML specification of the photo + gallery and syncing it with our local view of the gallery held in our Core Data + database, adding any photos we haven't seen before and removing any photos that + are no longer in the gallery. +*/ + +enum PhotoGallerySyncState { + kPhotoGallerySyncStateStopped, + kPhotoGallerySyncStateGetting, + kPhotoGallerySyncStateParsing, + kPhotoGallerySyncStateCommitting +}; +typedef enum PhotoGallerySyncState PhotoGallerySyncState; + +@class PhotoGalleryContext; +@class RetryingHTTPOperation; +@class GalleryParserOperation; + +@interface PhotoGallery : NSObject { + NSString * _galleryURLString; + NSUInteger _sequenceNumber; + + PhotoGalleryContext * _galleryContext; + NSEntityDescription * _photoEntity; + NSTimer * _saveTimer; + + NSDate * _lastSyncDate; + NSError * _lastSyncError; + NSDateFormatter * _standardDateFormatter; + PhotoGallerySyncState _syncState; + RetryingHTTPOperation * _getOperation; + GalleryParserOperation * _parserOperation; +} + +#pragma mark * Start up and shut down + ++ (void)applicationStartup; + // Called by the application delegate at startup time. This takes care of + // various bits of bookkeeping, including resetting the cache of photos + // if that debugging option has been set. + +- (id)initWithGalleryURLString:(NSString *)galleryURLString; + +@property (nonatomic, copy, readonly ) NSString * galleryURLString; + +- (void)start; + // Starts up the gallery (finds or creates a cache database and kicks off the initial + // sync). + +- (void)save; +- (void)stop; + // Called by the application delegate at -applicationDidEnterBackground: and + // -applicationWillTerminate: time, respectively. Note that it's safe, albeit a little + // weird, to call -save and -stop even if you haven't called -start. + // + // -stop is also called by the application delegate when it switches to a new gallery. + +#pragma mark * Core Data accessors + +// These properties are exported for the benefit of the PhotoGalleryViewController class, which +// uses them to set up its fetched results controller. + +@property (nonatomic, retain, readonly ) NSManagedObjectContext * managedObjectContext; // observable +@property (nonatomic, retain, readonly ) NSEntityDescription * photoEntity; + // Returns the entity description for the "Photo" entity in our database. + +#pragma mark * Syncing + +// These properties allow user interface controllers to learn about and control the +// state of the syncing process. + +@property (nonatomic, assign, readonly, getter=isSyncing) BOOL syncing; // observable, YES if syncState > kPhotoGallerySyncStateStopped +@property (nonatomic, assign, readonly ) PhotoGallerySyncState syncState; +@property (nonatomic, copy, readonly ) NSString * syncStatus; // observable, user-visible sync status +@property (nonatomic, copy, readonly ) NSDate * lastSyncDate; // observable, date of last /successful/ sync +@property (nonatomic, copy, readonly ) NSError * lastSyncError; // observable, error for last sync + +@property (nonatomic, copy, readonly ) NSDateFormatter * standardDateFormatter; // observable, date formatter for general purpose use + +- (void)startSync; + // Force a sync to start right now. Does nothing if a sync is already in progress. + +- (void)stopSync; + // Force a sync to stop right now. Does nothing if a no sync is in progress. + +@end diff --git a/MVCNetworking/Model/PhotoGallery.m b/MVCNetworking/Model/PhotoGallery.m new file mode 100644 index 0000000..e0e50a3 --- /dev/null +++ b/MVCNetworking/Model/PhotoGallery.m @@ -0,0 +1,1133 @@ +/* + File: PhotoGallery.m + + Contains: A model object that represents a gallery of photos on the network. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "PhotoGallery.h" + +#import "Photo.h" + +#import "PhotoGalleryContext.h" + +#import "NetworkManager.h" + +#import "RecursiveDeleteOperation.h" +#import "RetryingHTTPOperation.h" +#import "GalleryParserOperation.h" + +#import "Logging.h" + +@interface PhotoGallery () + +// read/write variants of public properties + +@property (nonatomic, retain, readwrite) NSEntityDescription * photoEntity; + +// private properties + +@property (nonatomic, assign, readonly ) NSUInteger sequenceNumber; +@property (nonatomic, retain, readwrite) PhotoGalleryContext * galleryContext; + +@property (nonatomic, copy, readonly ) NSString * galleryCachePath; +@property (nonatomic, retain, readwrite) NSTimer * saveTimer; + +@property (nonatomic, assign, readwrite) PhotoGallerySyncState syncState; +@property (nonatomic, retain, readwrite) RetryingHTTPOperation * getOperation; +@property (nonatomic, retain, readwrite) GalleryParserOperation * parserOperation; +@property (nonatomic, copy, readwrite) NSDate * lastSyncDate; +@property (nonatomic, copy, readwrite) NSError * lastSyncError; + +// forward declarations + +- (void)startParserOperationWithData:(NSData *)data; +- (void)commitParserResults:(NSArray *)latestResults; + +@end + +@implementation PhotoGallery + +// These strings define the format of our gallery cache. First up, kGalleryNameTemplate +// and kGalleryExtension specify the name of the gallery cache directory itself. + +static NSString * kGalleryNameTemplate = @"Gallery%.9f.%@"; +static NSString * kGalleryExtension = @"gallery"; + +// Then, within each gallery cache directory, there are the following items: +// +// o kInfoFileName is the name of a plist file within the gallery cache. If this is missing, +// the gallery cache has been abandoned (and can be removed at the next startup time). +// +// o kDatabaseFileName is the name of the Core Data file that holds the Photo and Thumbnail +// model objects. +// +// o kPhotosDirectoryName is the name of the directory containing the actual photo files. +// Note that this is shared with PhotoGalleryContext, which is why it's not "static". + +static NSString * kInfoFileName = @"GalleryInfo.plist"; +static NSString * kDatabaseFileName = @"Gallery.db"; + NSString * kPhotosDirectoryName = @"Photos"; + +// The gallery info file (kInfoFileName) contains a dictionary with just one property +// currently defined, kInfoFileName, which is the URL string of the gallery's XML data. + +static NSString * kGalleryInfoKeyGalleryURLString = @"gallerURLString"; + ++ (NSString *)cachesDirectoryPath + // Returns the path to the caches directory. This is a class method because it's + // used by +applicationStartup. +{ + NSString * result; + NSArray * paths; + + result = nil; + paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + if ( (paths != nil) && ([paths count] != 0) ) { + assert([[paths objectAtIndex:0] isKindOfClass:[NSString class]]); + result = [paths objectAtIndex:0]; + } + return result; +} + ++ (void)abandonGalleryCacheAtPath:(NSString *)galleryCachePath +{ + (void) [[NSFileManager defaultManager] removeItemAtPath:[galleryCachePath stringByAppendingPathComponent:kInfoFileName] error:NULL]; +} + ++ (void)applicationStartup + // See comment in header. +{ + NSUserDefaults * userDefaults; + NSFileManager * fileManager; + BOOL clearAllCaches; + NSString * cachesDirectoryPath; + NSArray * potentialGalleryCacheNames; + NSMutableArray * deletableGalleryCachePaths; + NSMutableArray * liveGalleryCachePathsAndDates; + + fileManager = [NSFileManager defaultManager]; + assert(fileManager != nil); + + userDefaults = [NSUserDefaults standardUserDefaults]; + assert(userDefaults != nil); + + cachesDirectoryPath = [self cachesDirectoryPath]; + assert(cachesDirectoryPath != nil); + + // See if we've been asked to nuke all gallery caches. + + clearAllCaches = [userDefaults boolForKey:@"galleryClearCache"]; + if (clearAllCaches) { + [[QLog log] logWithFormat:@"gallery clear cache"]; + + [userDefaults removeObjectForKey:@"galleryClearCache"]; + [userDefaults synchronize]; + } + + // Walk the list of gallery caches looking for abandoned ones (or, if we're + // clearing all caches, do them all). Add the targeted gallery caches + // to our list of things to delete. Also, for any galleries that remain, + // put the path and the mod date in a list so that we can then find the + // oldest galleries and delete them. + + deletableGalleryCachePaths = [NSMutableArray array]; + assert(deletableGalleryCachePaths != nil); + + potentialGalleryCacheNames = [fileManager contentsOfDirectoryAtPath:cachesDirectoryPath error:NULL]; + assert(potentialGalleryCacheNames != nil); + + liveGalleryCachePathsAndDates = [NSMutableArray array]; + assert(liveGalleryCachePathsAndDates != nil); + + for (NSString * galleryCacheName in potentialGalleryCacheNames) { + if ([galleryCacheName hasSuffix:kGalleryExtension]) { + NSString * galleryCachePath; + NSString * galleryInfoFilePath; + NSString * galleryDatabaseFilePath; + + galleryCachePath = [cachesDirectoryPath stringByAppendingPathComponent:galleryCacheName]; + assert(galleryCachePath != nil); + + galleryInfoFilePath = [galleryCachePath stringByAppendingPathComponent:kInfoFileName]; + assert(galleryInfoFilePath != nil); + + galleryDatabaseFilePath = [galleryCachePath stringByAppendingPathComponent:kDatabaseFileName]; + assert(galleryDatabaseFilePath != nil); + + if (clearAllCaches) { + [[QLog log] logWithFormat:@"gallery clear '%@'", galleryCacheName]; + (void) [fileManager removeItemAtPath:galleryInfoFilePath error:NULL]; + [deletableGalleryCachePaths addObject:galleryCachePath]; + } else if ( ! [fileManager fileExistsAtPath:galleryInfoFilePath]) { + [[QLog log] logWithFormat:@"gallery delete abandoned '%@'", galleryCacheName]; + [deletableGalleryCachePaths addObject:galleryCachePath]; + } else { + NSDate * modDate; + + // This gallery cache isn't abandoned. Get the modification date of its database. If + // that fails, the gallery cache is toast, so just add it to the to-delete list. + // If that succeeds, add a dictionary containing the gallery cache path and the + // mod date to the list of live gallery caches. + + modDate = [[fileManager attributesOfItemAtPath:galleryDatabaseFilePath error:NULL] objectForKey:NSFileModificationDate]; + if (modDate == nil) { + [[QLog log] logWithFormat:@"gallery delete invalid '%@'", galleryCacheName]; + [deletableGalleryCachePaths addObject:galleryCachePath]; + } else { + assert([modDate isKindOfClass:[NSDate class]]); + [liveGalleryCachePathsAndDates addObject:[NSDictionary dictionaryWithObjectsAndKeys: + galleryCachePath, @"path", + modDate, @"modDate", + nil + ]]; + } + } + } + } + + // See if we've exceeded our gallery cache limit, in which case we keep abandoning the oldest + // gallery cache until we're under that limit. + + [liveGalleryCachePathsAndDates sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"modDate" ascending:YES] autorelease]]]; + while ( [liveGalleryCachePathsAndDates count] > 3 ) { + NSString * path; + + path = [[liveGalleryCachePathsAndDates objectAtIndex:0] objectForKey:@"path"]; + assert([path isKindOfClass:[NSString class]]); + + [[QLog log] logWithFormat:@"gallery abandon and delete '%@'", [path lastPathComponent]]; + + [self abandonGalleryCacheAtPath:path]; + [deletableGalleryCachePaths addObject:path]; + + [liveGalleryCachePathsAndDates removeObjectAtIndex:0]; + } + + // Start an operation to delete the targeted gallery caches. This happens on a + // thread so that it doesn't prevent the app starting up. The app will + // ignore these gallery caches anyway, because we removed their gallery info files. + // Also, we don't monitor this operation for successful completion. It + // just does its stuff and then goes away. That means that we effectively + // leak the operation queue. Not a big deal. It also means that, if the + // app quits before the operation is done, it just gets killed. That's + // OK too; the delete will pick up where it left off when the app is next + // relaunched. + + if ( [deletableGalleryCachePaths count] != 0 ) { + static NSOperationQueue * sGalleryDeleteQueue; + RecursiveDeleteOperation * op; + + sGalleryDeleteQueue = [[NSOperationQueue alloc] init]; + assert(sGalleryDeleteQueue != nil); + + op = [[[RecursiveDeleteOperation alloc] initWithPaths:deletableGalleryCachePaths] autorelease]; + assert(op != nil); + + if ( [op respondsToSelector:@selector(setThreadPriority:)] ) { + [op setThreadPriority:0.1]; + } + + [sGalleryDeleteQueue addOperation:op]; + } +} + +- (id)initWithGalleryURLString:(NSString *)galleryURLString +{ + assert(galleryURLString != nil); + + // The initialisation method is very simple. All of the heavy lifting is done + // in -start. + + self = [super init]; + if (self != nil) { + static NSUInteger sNextGallerySequenceNumber; + + self->_galleryURLString = [galleryURLString copy]; + self->_sequenceNumber = sNextGallerySequenceNumber; + sNextGallerySequenceNumber += 1; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; + + [[QLog log] logWithFormat:@"gallery %zu is %@", (size_t) self->_sequenceNumber, galleryURLString]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; + + [self->_galleryURLString release]; + + // We should have been stopped before being released, so these properties + // should be nil by the time -dealloc is called. + assert(self->_galleryContext == nil); + assert(self->_photoEntity == nil); + assert(self->_saveTimer == nil); + + [self->_lastSyncDate release]; + [self->_lastSyncError release]; + [self->_standardDateFormatter release]; + + // We should have been stopped before being released, so these properties + // should be nil by the time -dealloc is called. + assert(self->_getOperation == nil); + assert(self->_parserOperation == nil); + + [super dealloc]; +} + +@synthesize galleryURLString = _galleryURLString; +@synthesize sequenceNumber = _sequenceNumber; + +- (void)didBecomeActive:(NSNotification *)note +{ + #pragma unused(note) + + // Having the ability to sync on activate makes it easy to test various cases where + // you want to force a sync in a weird context (like when the PhotoDetailViewController + // is up). + + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"gallerySyncOnActivate"] ) { + if (self.galleryContext != nil) { + [self startSync]; + } + } +} + +#pragma mark * Core Data wrangling + +@synthesize galleryContext = _galleryContext; + ++ (NSSet *)keyPathsForValuesAffectingManagedObjectContext +{ + return [NSSet setWithObject:@"galleryContext"]; +} + +- (NSManagedObjectContext *)managedObjectContext +{ + return self.galleryContext; +} + +- (NSEntityDescription *)photoEntity +{ + if (self->_photoEntity == nil) { + assert(self.galleryContext != nil); + self->_photoEntity = [[NSEntityDescription entityForName:@"Photo" inManagedObjectContext:self.galleryContext] retain]; + assert(self->_photoEntity != nil); + } + return self->_photoEntity; +} + +@synthesize photoEntity = _photoEntity; + +- (NSFetchRequest *)photosFetchRequest + // Returns a fetch request that gets all of the photos in the database. +{ + NSFetchRequest * fetchRequest; + + fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; + assert(fetchRequest != nil); + + [fetchRequest setEntity:self.photoEntity]; + [fetchRequest setFetchBatchSize:20]; + + return fetchRequest; +} + +- (NSString *)galleryCachePathForOurGallery + // Try to find the gallery cache for our gallery URL string. +{ + NSString * result; + NSFileManager * fileManager; + NSString * cachesDirectoryPath; + NSArray * potentialGalleries; + NSString * galleryName; + + assert(self.galleryURLString != nil); + + fileManager = [NSFileManager defaultManager]; + assert(fileManager != nil); + + cachesDirectoryPath = [[self class] cachesDirectoryPath]; + assert(cachesDirectoryPath != nil); + + // First look through the caches directory for a gallery cache whose info file + // matches the gallery URL string we're looking for. + + potentialGalleries = [fileManager contentsOfDirectoryAtPath:cachesDirectoryPath error:NULL]; + assert(potentialGalleries != nil); + + result = nil; + for (galleryName in potentialGalleries) { + if ([galleryName hasSuffix:kGalleryExtension]) { + NSDictionary * galleryInfo; + NSString * galleryInfoURLString; + + galleryInfo = [NSDictionary dictionaryWithContentsOfFile:[[cachesDirectoryPath stringByAppendingPathComponent:galleryName] stringByAppendingPathComponent:kInfoFileName]]; + if (galleryInfo != nil) { + galleryInfoURLString = [galleryInfo objectForKey:kGalleryInfoKeyGalleryURLString]; + if ( [self.galleryURLString isEqual:galleryInfoURLString] ) { + result = [cachesDirectoryPath stringByAppendingPathComponent:galleryName]; + break; + } + } + } + } + + // If we find nothing, create a new gallery cache and record it as belonging to the specified + // gallery URL string. + + if (result == nil) { + BOOL success; + + galleryName = [NSString stringWithFormat:kGalleryNameTemplate, [NSDate timeIntervalSinceReferenceDate], kGalleryExtension]; + assert(galleryName != nil); + + result = [cachesDirectoryPath stringByAppendingPathComponent:galleryName]; + success = [fileManager createDirectoryAtPath:result withIntermediateDirectories:NO attributes:NULL error:NULL]; + if (success) { + NSDictionary * galleryInfo; + + galleryInfo = [NSDictionary dictionaryWithObjectsAndKeys:self.galleryURLString, kGalleryInfoKeyGalleryURLString, nil]; + assert(galleryInfo != nil); + + success = [galleryInfo writeToFile:[result stringByAppendingPathComponent:kInfoFileName] atomically:YES]; + } + if ( ! success ) { + result = nil; + } + + [[QLog log] logWithFormat:@"gallery %zu created new '%@'", (size_t) self.sequenceNumber, galleryName]; + } else { + assert(galleryName != nil); + [[QLog log] logWithFormat:@"gallery %zu found existing '%@'", (size_t) self.sequenceNumber, galleryName]; + } + + return result; +} + +- (void)abandonGalleryCacheAtPath:(NSString *)galleryCachePath + // Abandons the specified gallery cache directory. We do this simply by removing the gallery + // info file. The directory will be deleted when the application is next launched. +{ + assert(galleryCachePath != nil); + + [[QLog log] logWithFormat:@"gallery %zu abandon '%@'", (size_t) self.sequenceNumber, [galleryCachePath lastPathComponent]]; + + [[self class] abandonGalleryCacheAtPath:galleryCachePath]; +} + +- (NSString *)galleryCachePath +{ + assert(self.galleryContext != nil); + return self.galleryContext.galleryCachePath; +} + +- (BOOL)setupGalleryContext + // Attempt to start up the gallery cache for our gallery URL string, either by finding an existing + // cache or by creating one from scratch. On success, self.galleryCachePath will point to that + // gallery cache and self.galleryContext will be the managed object context for the database + // within the gallery cache. +{ + BOOL success; + NSError * error; + NSFileManager * fileManager; + NSString * galleryCachePath; + NSString * photosDirectoryPath; + BOOL isDir; + NSURL * databaseURL; + NSManagedObjectModel * model; + NSPersistentStoreCoordinator * psc; + + assert(self.galleryURLString != nil); + + [[QLog log] logWithFormat:@"gallery %zu starting", (size_t) self.sequenceNumber]; + + error = nil; + + fileManager = [NSFileManager defaultManager]; + assert(fileManager != nil); + + // Find the gallery cache directory for this gallery. + + galleryCachePath = [self galleryCachePathForOurGallery]; + success = (galleryCachePath != nil); + + // Create the "Photos" directory if it doesn't already exist. + + if (success) { + photosDirectoryPath = [galleryCachePath stringByAppendingPathComponent:kPhotosDirectoryName]; + assert(photosDirectoryPath != nil); + + success = [fileManager fileExistsAtPath:photosDirectoryPath isDirectory:&isDir] && isDir; + if ( ! success ) { + success = [fileManager createDirectoryAtPath:photosDirectoryPath withIntermediateDirectories:NO attributes:NULL error:NULL]; + } + } + + // Start up Core Data in the gallery directory. + + if (success) { + NSString * modelPath; + + modelPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Photos" ofType:@"mom"]; + assert(modelPath != nil); + + model = [[[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]] autorelease]; + success = (model != nil); + } + if (success) { + databaseURL = [NSURL fileURLWithPath:[galleryCachePath stringByAppendingPathComponent:kDatabaseFileName]]; + assert(databaseURL != nil); + + psc = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model] autorelease]; + success = (psc != nil); + } + if (success) { + success = [psc addPersistentStoreWithType:NSSQLiteStoreType + configuration:nil + URL:databaseURL + options:nil + error:&error + ] != nil; + if (success) { + error = nil; + } + } + + if (success) { + PhotoGalleryContext * context; + + // Everything has gone well, so we create a managed object context from our persistent + // store. Note that we use a subclass of NSManagedObjectContext, PhotoGalleryContext, which + // carries along some state that the managed objects (specifically the Photo objects) need + // access to. + + context = [[[PhotoGalleryContext alloc] initWithGalleryURLString:self.galleryURLString galleryCachePath:galleryCachePath] autorelease]; + assert(context != nil); + + [context setPersistentStoreCoordinator:psc]; + + // In older versions of the code various folks observed our photoGalleryContext property + // and did clever things when it changed. So it was important to not set that property + // until everything as fully up and running. That no longer happens, but I've kept the + // configure-before-set code because it seems like the right thing to do. + + self.galleryContext = context; + + // Subscribe to the context changed notification so that we can auto-save. + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.managedObjectContext]; + + [[QLog log] logWithFormat:@"gallery %zu started '%@'", (size_t) self.sequenceNumber, [self.galleryCachePath lastPathComponent]]; + } else { + + // Bad things happened. Log the error and return NO. + + if (error == nil) { + [[QLog log] logWithFormat:@"gallery %zu start error", (size_t) self.sequenceNumber]; + } else { + [[QLog log] logWithFormat:@"gallery %zu start error %@", (size_t) self.sequenceNumber, error]; + } + + // Also, if we found or created a gallery cache but failed to start up in it, abandon it in + // the hope that our next attempt will work better. + + if (galleryCachePath != nil) { + [self abandonGalleryCacheAtPath:galleryCachePath]; + } + } + return success; +} + +- (void)start + // See comment in header. +{ + BOOL success; + + assert(self.galleryURLString != nil); + + // Try to start up. If this fails, it abandons the gallery cache, so a retry + // on our part is warranted. + + success = [self setupGalleryContext]; + if ( ! success ) { + success = [self setupGalleryContext]; + } + + // If all went well, start the syncing processing. If not, the application is dead + // and we crash. + + if (success) { + [self startSync]; + } else { + abort(); + } +} + +@synthesize saveTimer = _saveTimer; + +- (void)save + // See comment in header. +{ + NSError * error; + + error = nil; + + // Disable the auto-save timer. + + [self.saveTimer invalidate]; + self.saveTimer = nil; + + // Save. + + if ( (self.galleryContext != nil) && [self.galleryContext hasChanges] ) { + BOOL success; + + success = [self.galleryContext save:&error]; + if (success) { + error = nil; + } + } + + // Log the results. + + if (error == nil) { + [[QLog log] logWithFormat:@"gallery %zu saved", (size_t) self.sequenceNumber]; + } else { + [[QLog log] logWithFormat:@"gallery %zu save error %@", (size_t) self.sequenceNumber, error]; + } +} + +- (void)contextChanged:(NSNotification *)note + // Called when the managed object context changes (courtesy of the + // NSManagedObjectContextObjectsDidChangeNotification notification). We start an + // auto-save timer to fire in 5 seconds. This means that rapid-fire changes don't + // cause a flood of saves. +{ + #pragma unused(note) + if (self.saveTimer != nil) { + [self.saveTimer invalidate]; + } + self.saveTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(save) userInfo:nil repeats:NO]; +} + +- (void)stop + // See comment in header. + // + // Shuts down our access to the gallery cache. We do this in two situations: + // + // o When the user switches gallery. + // o When the application terminates. +{ + [self stopSync]; + + // Shut down the managed object context. + + if (self.galleryContext != nil) { + + // Shut down the auto save mechanism and then force a save. + + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextObjectsDidChangeNotification object:self.galleryContext]; + + [self save]; + + self.photoEntity = nil; + self.galleryContext = nil; + } + [[QLog log] logWithFormat:@"gallery %zu stopped", (size_t) self.sequenceNumber]; +} + +#pragma mark * Synchronisation + +@synthesize getOperation = _getOperation; +@synthesize parserOperation = _parserOperation; + +@synthesize lastSyncDate = _lastSyncDate; + ++ (NSSet *)keyPathsForValuesAffectingSyncStatus +{ + return [NSSet setWithObjects:@"syncState", @"lastSyncError", @"standardDateFormatter", @"lastSyncDate", @"getOperation.retryStateClient", nil]; +} + +- (NSString *)syncStatus + // See comment in header. +{ + NSString * result; + + if (self.lastSyncError == nil) { + switch (self.syncState) { + case kPhotoGallerySyncStateStopped: { + if (self.lastSyncDate == nil) { + result = @"Not updated"; + } else { + result = [NSString stringWithFormat:@"Updated: %@", [self.standardDateFormatter stringFromDate:self.lastSyncDate]]; + } + } break; + default: { + if ( (self.getOperation != nil) && (self.getOperation.retryStateClient == kRetryingHTTPOperationStateWaitingToRetry) ) { + result = @"Waiting for network"; + } else { + result = @"Updating…"; + } + } break; + } + } else { + if ([[self.lastSyncError domain] isEqual:NSCocoaErrorDomain] && [self.lastSyncError code] == NSUserCancelledError) { + result = @"Update cancelled"; + } else { + // At this point self.lastSyncError contains the actual error. + // However, we ignore that and return a very generic error status. + // Users don't understand "Connection reset by peer" anyway (-: + result = @"Update failed"; + } + } + return result; +} + +- (NSDateFormatter *)standardDateFormatter + // See comment in header. +{ + if (self->_standardDateFormatter == nil) { + self->_standardDateFormatter = [[NSDateFormatter alloc] init]; + assert(self->_standardDateFormatter != nil); + + [self->_standardDateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [self->_standardDateFormatter setTimeStyle:NSDateFormatterMediumStyle]; + + // Watch for changes in the locale and time zone so that we can update + // our date formatter accordingly. + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateStandardDateFormatter:) name:NSCurrentLocaleDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateStandardDateFormatter:) name:NSSystemTimeZoneDidChangeNotification object:nil]; + } + return self->_standardDateFormatter; +} + +- (void)updateStandardDateFormatter:(NSNotification *)note + // Called when either the current locale or the current time zone changes. + // We respond by applying the latest values to our date formatter. +{ + #pragma unused(note) + NSDateFormatter * df; + + df = self.standardDateFormatter; + [self willChangeValueForKey:@"standardDateFormatter"]; + [df setLocale:[NSLocale currentLocale]]; + [df setTimeZone:[NSTimeZone localTimeZone]]; + [self didChangeValueForKey:@"standardDateFormatter"]; +} + +@synthesize lastSyncError = _lastSyncError; + ++ (BOOL)automaticallyNotifiesObserversOfLastSyncError +{ + return NO; +} + +- (void)setLastSyncError:(NSError *)newValue + // We override this setter purely so that we can log the error. +{ + assert([NSThread isMainThread]); + + if (newValue != nil) { + [[QLog log] logWithFormat:@"gallery %zu sync error %@", (size_t) self.sequenceNumber, newValue]; + } + + if (newValue != self->_lastSyncError) { + [self willChangeValueForKey:@"lastSyncError"]; + [self->_lastSyncError release]; + self->_lastSyncError = [newValue copy]; + [self didChangeValueForKey:@"lastSyncError"]; + } +} + +- (void)startGetOperation + // Starts the HTTP operation to GET the photo gallery's XML. +{ + NSMutableURLRequest * request; + + assert(self.syncState == kPhotoGallerySyncStateStopped); + + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync get start", (size_t) self.sequenceNumber]; + + request = [self.galleryContext requestToGetGalleryRelativeString:nil]; + assert(request != nil); + + assert(self.getOperation == nil); + self.getOperation = [[[RetryingHTTPOperation alloc] initWithRequest:request] autorelease]; + assert(self.getOperation != nil); + + [self.getOperation setQueuePriority:NSOperationQueuePriorityNormal]; + self.getOperation.acceptableContentTypes = [NSSet setWithObjects:@"application/xml", @"text/xml", nil]; + + [[NetworkManager sharedManager] addNetworkManagementOperation:self.getOperation finishedTarget:self action:@selector(getOperationDone:)]; + + self.syncState = kPhotoGallerySyncStateGetting; +} + +- (void)getOperationDone:(RetryingHTTPOperation *)operation + // Called when the HTTP operation to GET the photo gallery's XML completes. + // If all is well we start an operation to parse the XML. +{ + NSError * error; + + assert([operation isKindOfClass:[RetryingHTTPOperation class]]); + assert(operation == self.getOperation); + assert(self.syncState == kPhotoGallerySyncStateGetting); + + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync listing done", (size_t) self.sequenceNumber]; + + error = operation.error; + if (error != nil) { + self.lastSyncError = error; + self.syncState = kPhotoGallerySyncStateStopped; + } else { + if ([QLog log].isEnabled) { + [[QLog log] logOption:kLogOptionNetworkData withFormat:@"receive %@", self.getOperation.responseContent]; + } + [self startParserOperationWithData:self.getOperation.responseContent]; + } + + self.getOperation = nil; +} + +- (void)startParserOperationWithData:(NSData *)data + // Starts the operation to parse the gallery's XML. +{ + assert(self.syncState == kPhotoGallerySyncStateGetting); + + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync parse start", (size_t) self.sequenceNumber]; + + assert(self.parserOperation == nil); + self.parserOperation = [[[GalleryParserOperation alloc] initWithData:data] autorelease]; + assert(self.parserOperation != nil); + + [self.parserOperation setQueuePriority:NSOperationQueuePriorityNormal]; + + [[NetworkManager sharedManager] addCPUOperation:self.parserOperation finishedTarget:self action:@selector(parserOperationDone:)]; + + self.syncState = kPhotoGallerySyncStateParsing; +} + +- (void)parserOperationDone:(GalleryParserOperation *)operation + // Called when the operation to parse the gallery's XML completes. + // If all went well we commit the results to our database. +{ + assert([NSThread isMainThread]); + assert([operation isKindOfClass:[GalleryParserOperation class]]); + assert(operation == self.parserOperation); + assert(self.syncState == kPhotoGallerySyncStateParsing); + + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync parse done", (size_t) self.sequenceNumber]; + + if (operation.error != nil) { + self.lastSyncError = operation.error; + self.syncState = kPhotoGallerySyncStateStopped; + } else { + [self commitParserResults:operation.results]; + + assert(self.lastSyncError == nil); + self.lastSyncDate = [NSDate date]; + self.syncState = kPhotoGallerySyncStateStopped; + [[QLog log] logWithFormat:@"gallery %zu sync success", (size_t) self.sequenceNumber]; + } + + self.parserOperation = nil; +} + +#if ! defined(NDEBUG) + +- (void)checkDatabase + // In debug mode we call this routine after committing our changes to the database + // to verify that the database looks reasonable. +{ + NSFetchRequest * photosFetchRequest; + NSFetchRequest * thumbnailsFetchRequest; + NSArray * allPhotos; + NSMutableSet * remainingThumbnails; + Photo * photo; + Thumbnail * thumbnail; + + assert(self.galleryContext != nil); + + // Get all of the photos and all of the thumbnails. + + photosFetchRequest = [self photosFetchRequest]; + assert(photosFetchRequest != nil); + + allPhotos = [self.galleryContext executeFetchRequest:photosFetchRequest error:NULL]; + assert(allPhotos != nil); + + thumbnailsFetchRequest = [[[NSFetchRequest alloc] init] autorelease]; + assert(thumbnailsFetchRequest != nil); + + [thumbnailsFetchRequest setEntity:[NSEntityDescription entityForName:@"Thumbnail" inManagedObjectContext:self.galleryContext]]; + [thumbnailsFetchRequest setFetchBatchSize:20]; + + remainingThumbnails = [NSMutableSet setWithArray:[self.galleryContext executeFetchRequest:thumbnailsFetchRequest error:NULL]]; + assert(remainingThumbnails != nil); + + // Check that ever photo has a thumbnail (and also remove that thumbnail + // from the remainingThumbnails set). + + for (photo in allPhotos) { + assert([photo isKindOfClass:[Photo class]]); + + thumbnail = photo.thumbnail; + if (thumbnail != nil) { + if ([remainingThumbnails containsObject:thumbnail]) { + [remainingThumbnails removeObject:thumbnail]; + } else { + NSLog(@"*** photo %@ has no thumbnail", photo.photoID); + } + } + } + + // Check that there are no orphaned thumbnails (thumbnails that aren't attached to + // a photo). + + for (thumbnail in remainingThumbnails) { + NSLog(@"*** thumbnail %@ orphaned", thumbnail); + } +} + +#endif + +- (void)commitParserResults:(NSArray *)parserResults + // Commits the results of parsing our the gallery's XML to the Core Data database. +{ + NSError * error; + NSDate * syncDate; + NSArray * knownPhotos; // of Photo + + syncDate = [NSDate date]; + assert(syncDate != nil); + + // Start by getting all of the photos that we currently have in the database. + + knownPhotos = [self.galleryContext executeFetchRequest:[self photosFetchRequest] error:&error]; + assert(knownPhotos != nil); + if (knownPhotos != nil) { + NSMutableSet * photosToRemove; + NSMutableDictionary * photoIDToKnownPhotos; + NSMutableSet * parserIDs; + Photo * knownPhoto; + + // For each photo found in the XML, get the corresponding Photo object + // (based on the photoID). If there is one, update it based on the new + // properties from the XML (this may cause the photo to get new thumbnail + // and photo images, and trigger significant UI updates). If there isn't an + // existing photo, create one based on the properties from the XML. + + // Create photosToRemove, which starts out as a set of all the photos we know + // about. As we refresh each existing photo, we remove it from this set. Any + // photos left over are no longer present in the XML, and we remove them. + + photosToRemove = [NSMutableSet setWithArray:knownPhotos]; + assert(photosToRemove != nil); + + // Create photoIDToKnownPhotos, which is a map from photoID to photo. We use this + // to quickly determine if a photo with a specific photoID currently exists. + + photoIDToKnownPhotos = [NSMutableDictionary dictionary]; + assert(photoIDToKnownPhotos != nil); + + for (knownPhoto in knownPhotos) { + assert([knownPhoto isKindOfClass:[Photo class]]); + + [photoIDToKnownPhotos setObject:knownPhoto forKey:knownPhoto.photoID]; + } + + // Finally, create parserIDs, which is set of all the photoIDs that have come in + // from the XML. We use this to detect duplicate photoIDs in the incoming XML. + // It would be bad to have two photos with the same ID. + + parserIDs = [NSMutableSet set]; + assert(parserIDs != nil); + + // Iterate through the incoming XML results, processing each one in turn. + + for (NSDictionary * parserResult in parserResults) { + NSString * photoID; + + photoID = [parserResult objectForKey:kGalleryParserResultPhotoID]; + assert([photoID isKindOfClass:[NSString class]]); + + // Check for duplicates. + + if ([parserIDs containsObject:photoID]) { + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync duplicate photo %@", (size_t) self.sequenceNumber, photoID]; + } else { + NSDictionary * properties; + + [parserIDs addObject:photoID]; + + // Build a properties dictionary, used by both the create and update code paths. + + properties = [NSDictionary dictionaryWithObjectsAndKeys: + photoID, @"photoID", + [parserResult objectForKey:kGalleryParserResultName], @"displayName", + [parserResult objectForKey:kGalleryParserResultDate], @"date", + [parserResult objectForKey:kGalleryParserResultPhotoPath], @"remotePhotoPath", + [parserResult objectForKey:kGalleryParserResultThumbnailPath], @"remoteThumbnailPath", + nil + ]; + assert(properties != nil); + + // See whether we know about this specific photoID. + + knownPhoto = [photoIDToKnownPhotos objectForKey:photoID]; + if (knownPhoto != nil) { + + // Yes. Give the photo a chance to update itself from the incoming properties. + + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync refresh %@", (size_t) self.sequenceNumber, photoID]; + [photosToRemove removeObject:knownPhoto]; + + [knownPhoto updateWithProperties:properties]; + } else { + + // No. Create a new photo with the specified properties. + + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync create %@", (size_t) self.sequenceNumber, photoID]; + knownPhoto = [Photo insertNewPhotoWithProperties:properties inManagedObjectContext:self.galleryContext]; + assert(knownPhoto != nil); + assert(knownPhoto.photoID != nil); + assert(knownPhoto.localPhotoPath == nil); + assert(knownPhoto.thumbnail == nil); + + [photoIDToKnownPhotos setObject:knownPhoto forKey:knownPhoto.photoID]; + } + } + } + + // Remove any photos that are no longer present in the XML. + + for (knownPhoto in photosToRemove) { + [[QLog log] logOption:kLogOptionSyncDetails withFormat:@"gallery %zu sync delete %@", (size_t) self.sequenceNumber, knownPhoto.photoID]; + [self.galleryContext deleteObject:knownPhoto]; + } + } + + #if ! defined(NDEBUG) + [self checkDatabase]; + #endif +} + ++ (NSSet *)keyPathsForValuesAffectingSyncing +{ + return [NSSet setWithObject:@"syncState"]; +} + +- (BOOL)isSyncing + // See comment in header. +{ + return (self->_syncState > kPhotoGallerySyncStateStopped); +} + +@synthesize syncState = _syncState; + ++ (BOOL)automaticallyNotifiesObserversOfSyncState +{ + return NO; +} + +- (void)setSyncState:(PhotoGallerySyncState)newValue +{ + if (newValue != self->_syncState) { + BOOL isSyncingChanged; + + isSyncingChanged = (self->_syncState > kPhotoGallerySyncStateStopped) != (newValue > kPhotoGallerySyncStateStopped); + [self willChangeValueForKey:@"syncState"]; + if (isSyncingChanged) { + [self willChangeValueForKey:@"syncing"]; + } + self->_syncState = newValue; + if (isSyncingChanged) { + [self didChangeValueForKey:@"syncing"]; + } + [self didChangeValueForKey:@"syncState"]; + } +} + +- (void)startSync + // See comment in header. +{ + if ( ! self.isSyncing ) { + if (self.syncState == kPhotoGallerySyncStateStopped) { + [[QLog log] logWithFormat:@"gallery %zu sync start", (size_t) self.sequenceNumber]; + assert(self.getOperation == nil); + self.lastSyncError = nil; + [self startGetOperation]; + } + } +} + +- (void)stopSync + // See comment in header. +{ + if (self.isSyncing) { + if (self.getOperation != nil) { + [[NetworkManager sharedManager] cancelOperation:self.getOperation]; + self.getOperation = nil; + } + if (self.parserOperation) { + [[NetworkManager sharedManager] cancelOperation:self.parserOperation]; + self.parserOperation = nil; + } + self.lastSyncError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]; + self.syncState = kPhotoGallerySyncStateStopped; + [[QLog log] logWithFormat:@"gallery %zu sync stopped", (size_t) self.sequenceNumber]; + } +} + +@end diff --git a/MVCNetworking/Model/PhotoGalleryContext.h b/MVCNetworking/Model/PhotoGalleryContext.h new file mode 100644 index 0000000..b9dd8cb --- /dev/null +++ b/MVCNetworking/Model/PhotoGalleryContext.h @@ -0,0 +1,80 @@ +/* + File: PhotoGalleryContext.h + + Contains: A managed object context subclass that carries along some photo gallery info. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +// There's a one-to-one relationship between PhotoGallery and PhotoGalleryContext objects. +// The reason why certain bits of state are stored here, rather than in PhotoGallery, is +// so that managed objects, specifically the Photo objects, can get access to this state +// easily (via their managedObjectContext property). + +@interface PhotoGalleryContext : NSManagedObjectContext +{ + NSString * _galleryURLString; + NSString * _galleryCachePath; +} + +- (id)initWithGalleryURLString:(NSString *)galleryURLString galleryCachePath:(NSString *)galleryCachePath; + +@property (nonatomic, copy, readonly ) NSString * galleryURLString; +@property (nonatomic, copy, readonly ) NSString * galleryCachePath; // path to gallery cache directory +@property (nonatomic, copy, readonly ) NSString * photosDirectoryPath; // path to Photos directory within galleryCachePath + +- (NSMutableURLRequest *)requestToGetGalleryRelativeString:(NSString *)path; + // Returns a mutable request that's configured to do an HTTP GET operation + // for a resources with the given path relative to the galleryURLString. + // If path is nil, returns a request for the galleryURLString resource + // itself. This can return fail (and return nil) if path is not nil and + // yet not a valid URL path. + +@end diff --git a/MVCNetworking/Model/PhotoGalleryContext.m b/MVCNetworking/Model/PhotoGalleryContext.m new file mode 100644 index 0000000..d1e07f6 --- /dev/null +++ b/MVCNetworking/Model/PhotoGalleryContext.m @@ -0,0 +1,128 @@ +/* + File: PhotoGalleryContext.m + + Contains: A managed object context subclass that carries along some photo gallery info. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "PhotoGalleryContext.h" + +#import "NetworkManager.h" + +@implementation PhotoGalleryContext + +- (id)initWithGalleryURLString:(NSString *)galleryURLString galleryCachePath:(NSString *)galleryCachePath +{ + assert(galleryURLString != nil); + assert(galleryCachePath != nil); + + self = [super init]; + if (self != nil) { + self->_galleryURLString = [galleryURLString copy]; + self->_galleryCachePath = [galleryCachePath copy]; + } + return self; +} + +- (void)dealloc +{ + [self->_galleryCachePath release]; + [self->_galleryURLString release]; + [super dealloc]; +} + +@synthesize galleryURLString = _galleryURLString; +@synthesize galleryCachePath = _galleryCachePath; + +- (NSString *)photosDirectoryPath +{ + // This comes from the PhotoGallery class. I didn't really want to include it's header + // here (because we are 'lower' in the architecture than PhotoGallery), and I don't want + // the declaration in "PhotoGalleryContext.h" either (because our public clients have + // no need of this). The best solution would be to have "PhotoGalleryPrivate.h", and + // put all the gallery cache structure strings into that file. But having a whole separate + // file just to solve that problem seems like overkill. So, for the moment, we just + // declare it extern here. + extern NSString * kPhotosDirectoryName; + return [self.galleryCachePath stringByAppendingPathComponent:kPhotosDirectoryName]; +} + +- (NSMutableURLRequest *)requestToGetGalleryRelativeString:(NSString *)path + // See comment in header. +{ + NSMutableURLRequest * result; + NSURL * url; + + assert([NSThread isMainThread]); + assert(self.galleryURLString != nil); + + result = nil; + + // Construct the URL. + + url = [NSURL URLWithString:self.galleryURLString]; + assert(url != nil); + if (path != nil) { + url = [NSURL URLWithString:path relativeToURL:url]; + // url may be nil because, while galleryURLString is guaranteed to be a valid + // URL, path may not be. + } + + // Call down to the network manager so that it can set up its stuff + // (notably the user agent string). + + if (url != nil) { + result = [[NetworkManager sharedManager] requestToGetURL:url]; + assert(result != nil); + } + + return result; +} + +@end diff --git a/MVCNetworking/Model/Photos.xcdatamodel/elements b/MVCNetworking/Model/Photos.xcdatamodel/elements new file mode 100644 index 0000000..9f23a50 Binary files /dev/null and b/MVCNetworking/Model/Photos.xcdatamodel/elements differ diff --git a/MVCNetworking/Model/Photos.xcdatamodel/layout b/MVCNetworking/Model/Photos.xcdatamodel/layout new file mode 100644 index 0000000..85f3074 Binary files /dev/null and b/MVCNetworking/Model/Photos.xcdatamodel/layout differ diff --git a/MVCNetworking/Model/RecursiveDeleteOperation.h b/MVCNetworking/Model/RecursiveDeleteOperation.h new file mode 100644 index 0000000..d438495 --- /dev/null +++ b/MVCNetworking/Model/RecursiveDeleteOperation.h @@ -0,0 +1,73 @@ +/* + File: RecursiveDeleteOperation.h + + Contains: Recursively deletes an array of file paths. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@interface RecursiveDeleteOperation : NSOperation +{ + NSArray * _paths; + NSError * _error; +} + +- (id)initWithPaths:(NSArray *)paths; + // Configures the operation with the array of paths to delete. + +// properties specified at init time + +@property (copy, readonly ) NSArray * paths; + +// properties that are valid after the operation is finished + +@property (copy, readonly ) NSError * error; + +@end diff --git a/MVCNetworking/Model/RecursiveDeleteOperation.m b/MVCNetworking/Model/RecursiveDeleteOperation.m new file mode 100644 index 0000000..833c021 --- /dev/null +++ b/MVCNetworking/Model/RecursiveDeleteOperation.m @@ -0,0 +1,110 @@ +/* + File: RecursiveDeleteOperation.h + + Contains: Recursively deletes an array of file paths. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "RecursiveDeleteOperation.h" + +@interface RecursiveDeleteOperation () + +// read/write versions of public properties + +@property (copy, readwrite) NSError * error; + +@end + +@implementation RecursiveDeleteOperation + +- (id)initWithPaths:(NSArray *)paths + // See comment in header. +{ + assert(paths != nil); + self = [super init]; + if (self != nil) { + self->_paths = [paths copy]; + assert(self->_paths != nil); + } + return self; +} + +- (void)dealloc +{ + [self->_paths release]; + [self->_error release]; + [super dealloc]; +} + +@synthesize paths = _paths; +@synthesize error = _error; + +- (void)main +{ + BOOL success; + NSFileManager * fileManager; + NSError * error; + + fileManager = [NSFileManager defaultManager]; + assert(fileManager != nil); + + success = YES; // necessary when self.paths is empty, which is a wacky corner case but I decided to allow it + for (NSString * path in self.paths) { + success = [fileManager removeItemAtPath:path error:&error]; + if ( ! success ) { + break; + } + } + + if ( ! success ) { + self.error = error; + } +} + +@end diff --git a/MVCNetworking/Model/Thumbnail.h b/MVCNetworking/Model/Thumbnail.h new file mode 100644 index 0000000..7059c4d --- /dev/null +++ b/MVCNetworking/Model/Thumbnail.h @@ -0,0 +1,70 @@ +/* + File: Thumbnail.h + + Contains: Model object for a thumbnail. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +// In contrast to the Photo class, the Thumbnail class is entirely passive. +// It's just a dumb container for the thumbnail data. +// +// Keep in mind that, by default, managed object properties are retained, not +// copied, so clients of Thumbnail must be careful if they assign potentially +// mutable data to the imageData property. + +@class Photo; + +@interface Thumbnail : NSManagedObject + +@property (nonatomic, retain, readwrite) NSData * imageData; // holds a PNG representation of the thumbnail +@property (nonatomic, retain, readwrite) Photo * photo; // a pointer back to the owning photo + +@end diff --git a/MVCNetworking/Model/Thumbnail.m b/MVCNetworking/Model/Thumbnail.m new file mode 100644 index 0000000..7bf28dd --- /dev/null +++ b/MVCNetworking/Model/Thumbnail.m @@ -0,0 +1,61 @@ +/* + File: Thumbnail.m + + Contains: Model object for a thumbnail. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "Thumbnail.h" + +@implementation Thumbnail + +@dynamic imageData; +@dynamic photo; + +@end diff --git a/MVCNetworking/Networking/GalleryParserOperation.h b/MVCNetworking/Networking/GalleryParserOperation.h new file mode 100644 index 0000000..faaf021 --- /dev/null +++ b/MVCNetworking/Networking/GalleryParserOperation.h @@ -0,0 +1,95 @@ +/* + File: GalleryParserOperation.h + + Contains: Parses an XML photo gallery. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@interface GalleryParserOperation : NSOperation +{ + NSData * _data; + NSError * _error; +#if ! defined(NDEBUG) + NSTimeInterval _debugDelay; + NSTimeInterval _debugDelaySoFar; +#endif + NSXMLParser * _parser; + NSMutableArray * _mutableResults; + NSMutableDictionary * _itemProperties; +} + +- (id)initWithData:(NSData *)data; + // Configures the operation to parse the specified XML data. + +// properties specified at init time + +@property (copy, readonly ) NSData * data; + +// properties that can be changed before starting the operation + +#if ! defined(NDEBUG) +@property (assign, readwrite) NSTimeInterval debugDelay; // default is 0.0 +#endif + +// properties that are valid after the operation is finished + +@property (copy, readonly ) NSError * error; +@property (copy, readonly ) NSArray * results; // of NSDictionary, keys below + +@end + +// Keys for the results dictionaries. + +extern NSString * kGalleryParserResultPhotoID; // NSString +extern NSString * kGalleryParserResultName; // NSString +extern NSString * kGalleryParserResultDate; // NSDate +extern NSString * kGalleryParserResultPhotoPath; // NSString +extern NSString * kGalleryParserResultThumbnailPath;// NSString diff --git a/MVCNetworking/Networking/GalleryParserOperation.m b/MVCNetworking/Networking/GalleryParserOperation.m new file mode 100644 index 0000000..df51a11 --- /dev/null +++ b/MVCNetworking/Networking/GalleryParserOperation.m @@ -0,0 +1,337 @@ +/* + File: GalleryParserOperation.m + + Contains: Parses an XML photo gallery. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "GalleryParserOperation.h" + +#import "Logging.h" + +#include // for strptime_l + +@interface GalleryParserOperation () + +// read/write variants of public properties + +@property (copy, readwrite) NSError * error; + +// private properties + +#if ! defined(NDEBUG) +@property (assign, readwrite) NSTimeInterval debugDelaySoFar; +#endif + +@property (retain, readonly ) NSMutableArray * mutableResults; +@property (retain, readwrite) NSXMLParser * parser; +@property (retain, readonly ) NSMutableDictionary * itemProperties; + +@end + +@implementation GalleryParserOperation + +- (id)initWithData:(NSData *)data + // See comment in header. +{ + assert(data != nil); + self = [super init]; + if (self != nil) { + self->_data = [data copy]; + self->_mutableResults = [[NSMutableArray alloc] init]; + assert(self->_mutableResults != nil); + self->_itemProperties = [[NSMutableDictionary alloc] init]; + assert(self->_itemProperties != nil); + } + return self; +} + +- (void)dealloc +{ + [self->_data release]; + [self->_error release]; + [self->_parser release]; + [self->_mutableResults release]; + [self->_itemProperties release]; + [super dealloc]; +} + +#if ! defined(NDEBUG) +@synthesize debugDelay = _debugDelay; +@synthesize debugDelaySoFar = _debugDelaySoFar; +#endif + +@synthesize data = _data; +@synthesize error = _error; + +@synthesize mutableResults = _mutableResults; +@synthesize parser = _parser; +@synthesize itemProperties = _itemProperties; + ++ (NSDate *)dateFromDateString:(NSString *)string + // Parses the supplied XML date string and returns an NSDate object. + // We avoid NSDateFormatter here and do the work using the much lighter + // weight strptime_l. +{ +/* + Dates are of the form "2006-07-30T07:47:17Z". +*/ + struct tm now; + NSDate * result; + BOOL success; + + result = nil; + success = strptime_l([string UTF8String], "%Y-%m-%dT%H:%M:%SZ", &now, NULL) != NULL; + if (success) { + result = [NSDate dateWithTimeIntervalSince1970:timelocal(&now)]; + } + + return result; +} + +- (NSArray *)results + // Returns a copy of the current results. +{ + return [[self->_mutableResults copy] autorelease]; +} + +- (void)main +{ + BOOL success; + + // Set up the parser. We keep this in a property so that our delegate callbacks + // have access to it. + + assert(self.data != nil); + self.parser = [[[NSXMLParser alloc] initWithData:self.data] autorelease]; + assert(self.parser != nil); + + self.parser.delegate = self; + + // Do the parse. + + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse start"]; + + success = [self.parser parse]; + if ( ! success ) { + + // If our parser delegate callbacks already set an error, we ignore the error + // coming back from NSXMLParser. Our delegate callbacks have the most accurate + // error info. + + if (self.error == nil) { + self.error = [self.parser parserError]; + assert(self.error != nil); + } + } + + // In the debug version, if we've been told to delay, do so. This gives + // us time to test the cancellation path. + + #if ! defined(NDEBUG) + { + while (self.debugDelaySoFar < self.debugDelay) { + // We always sleep in one second intervals. I could do the maths to + // sleep for the remaining amount of time or one second, whichever + // is the least, but hey, this is debugging code. + + [NSThread sleepForTimeInterval:1.0]; + self.debugDelaySoFar += 1.0; + + if ( [self isCancelled] ) { + // If we notice the cancel, we override any error we got from the XML. + self.error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]; + break; + } + } + } + #endif + + if (self.error == nil) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse success"]; + } else { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse failed %@", self.error]; + } + + self.parser = nil; +} + +/* + Here's an example of a "photo" element in our XML: + + + + + + +*/ + +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict +{ + assert(parser == self.parser); + #pragma unused(parser) + #pragma unused(namespaceURI) + #pragma unused(qName) + #pragma unused(attributeDict) + + // In the debug build, if we've been told to delay, and we haven't already delayed + // enough, just sleep for 0.1 seconds. + + #if ! defined(NDEBUG) + if (self.debugDelaySoFar < self.debugDelay) { + [NSThread sleepForTimeInterval:0.1]; + self.debugDelaySoFar += 0.1; + } + #endif + + // Check for cancellation at the start of each element. + + if ( [self isCancelled] ) { + self.error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]; + [self.parser abortParsing]; + } else if ( [elementName isEqual:@"photo"] ) { + NSString * tmpStr; + NSString * photoID; + NSString * name; + NSDate * date; + + // We're at the start of a "photo" element. Set up the itemProperties dictionary. + + [self.itemProperties removeAllObjects]; + + photoID = nil; + name = nil; + date = nil; + + photoID = [attributeDict objectForKey:@"id"]; + name = [attributeDict objectForKey:@"name"]; + tmpStr = [attributeDict objectForKey:@"date"]; + if (tmpStr != nil) { + date = [[self class] dateFromDateString:tmpStr]; + if (date == nil) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo date error '%@'", tmpStr]; + } + } + + if ( (photoID == nil) || ([photoID length] == 0) ) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo skipped, missing 'id'"]; + } else if ( (name == nil) || ([name length] == 0) ) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo skipped, missing 'name'"]; + } else if (date == nil) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo skipped, missing 'date'"]; + } else { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo start %@", photoID]; + [self.itemProperties setObject:photoID forKey:kGalleryParserResultPhotoID]; + [self.itemProperties setObject:name forKey:kGalleryParserResultName]; + [self.itemProperties setObject:date forKey:kGalleryParserResultDate]; + } + } else if ( [elementName isEqual:@"image"] ) { + if ( [self.itemProperties count] == 0 ) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo image skipped, out of context"]; + } else { + NSString * kindStr; + NSString * srcURLStr; + + // We're at the start of an "image" element. Check to see whether it's an image + // we care about. If so, add the "srcURL" attribute to our itemProperties dictionary. + + kindStr = [attributeDict objectForKey:@"kind"]; + srcURLStr = [attributeDict objectForKey:@"srcURL"]; + if ( (srcURLStr != nil) && ([srcURLStr length] != 0) ) { + if ( [kindStr isEqual:@"image"] ) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo image '%@'", srcURLStr]; + [self.itemProperties setObject:srcURLStr forKey:kGalleryParserResultPhotoPath]; + } else if ( [kindStr isEqual:@"thumbnail"] ) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo thumbnail '%@'", srcURLStr]; + [self.itemProperties setObject:srcURLStr forKey:kGalleryParserResultThumbnailPath]; + } + } + } + } +} + +- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName +{ + assert(parser == self.parser); + #pragma unused(parser) + #pragma unused(namespaceURI) + #pragma unused(qName) + + // At the end of the "photo" element, check to see we got all of the required + // properties and, if so, add an item to the result. + + if ( [elementName isEqual:@"photo"] ) { + if ([self.itemProperties count] == 0) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo skipped, out of context"]; + } else { + if ([self.itemProperties objectForKey:kGalleryParserResultPhotoPath] == nil) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo skipped, missing image"]; + } else if ([self.itemProperties objectForKey:kGalleryParserResultThumbnailPath] == nil) { + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo skipped, missing thumbnail"]; + } else { + assert([[self.itemProperties objectForKey:kGalleryParserResultPhotoID ] isKindOfClass:[NSString class]]); + assert([[self.itemProperties objectForKey:kGalleryParserResultName ] isKindOfClass:[NSString class]]); + assert([[self.itemProperties objectForKey:kGalleryParserResultDate ] isKindOfClass:[NSDate class]]); + assert([[self.itemProperties objectForKey:kGalleryParserResultPhotoPath ] isKindOfClass:[NSString class]]); + assert([[self.itemProperties objectForKey:kGalleryParserResultThumbnailPath] isKindOfClass:[NSString class]]); + [[QLog log] logOption:kLogOptionXMLParseDetails withFormat:@"xml parse photo success %@", [self.itemProperties objectForKey:kGalleryParserResultPhotoID]]; + [self.mutableResults addObject:[[self.itemProperties copy] autorelease]]; + [self.itemProperties removeAllObjects]; + } + } + } +} + +@end + +NSString * kGalleryParserResultPhotoID = @"photoID"; +NSString * kGalleryParserResultName = @"name"; +NSString * kGalleryParserResultDate = @"date"; +NSString * kGalleryParserResultPhotoPath = @"photoPath"; +NSString * kGalleryParserResultThumbnailPath = @"thumbnailPath"; diff --git a/MVCNetworking/Networking/NetworkManager.h b/MVCNetworking/Networking/NetworkManager.h new file mode 100644 index 0000000..a947d31 --- /dev/null +++ b/MVCNetworking/Networking/NetworkManager.h @@ -0,0 +1,146 @@ +/* + File: NetworkManager.h + + Contains: A singleton to manage the core network interactions. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@interface NetworkManager : NSObject +{ + NSThread * _networkRunLoopThread; + NSOperationQueue * _queueForNetworkManagement; + NSOperationQueue * _queueForNetworkTransfers; + NSOperationQueue * _queueForCPU; + CFMutableDictionaryRef _runningOperationToTargetMap; + CFMutableDictionaryRef _runningOperationToActionMap; + CFMutableDictionaryRef _runningOperationToThreadMap; + NSUInteger _runningNetworkTransferCount; +} + ++ (NetworkManager *)sharedManager; + // Returns the network manager singleton. + // + // Can be called from any thread. + +- (NSMutableURLRequest *)requestToGetURL:(NSURL *)url; + // Returns a mutable request that's configured to do an HTTP GET operation + // for the specified URL. This sets up any request properties that should be + // common to all network requests, most notably the user agent string. + // + // Can be called from any thread. + +// networkInUse is YES if any network transfer operations are in progress; you can only +// call the getter from the main thread. + +@property (nonatomic, assign, readonly ) BOOL networkInUse; // observable, always changes on main thread + +// Operation dispatch + +// We have three operation queues to separate our various operations. There are a bunch of +// important points here: +// +// o There are separate network management, network transfer and CPU queues, so that network +// operations don't hold up CPU operations, and vice versa. +// +// o The width of the network management queue (that is, the maxConcurrentOperationCount value) +// is unbounded, so that network management operations always proceed. This is fine because +// network management operations are all run loop based and consume very few real resources. +// +// o The width of the network transfer queue is set to some fixed value, which controls the total +// number of network operations that we can be running simultaneously. +// +// o The width of the CPU operation queue is left at the default value, which typically means +// we start one CPU operation per available core (which on iOS devices means one). This +// prevents us from starting lots of CPU operations that just thrash the scheduler without +// getting any concurrency benefits. +// +// o When you queue an operation you must supply a target/action pair that is called when +// the operation completes without being cancelled. +// +// o The target/action pair is called on the thread that added the operation to the queue. +// You have to ensure that this thread runs its run loop. +// +// o If you queue a network operation and that network operation supports the runLoopThread +// property and the value of that property is nil, this sets the run loop thread of the operation +// to the above-mentioned internal networking thread. This means that, by default, all +// network run loop callbacks run on this internal networking thread. The goal here is to +// minimise main thread latency. +// +// It's worth noting that this is only true for network operation run loop callbacks, and is +// /not/ true for target/action completions. These are called on the thread that queued +// the operation, as described above. +// +// o If you cancel an operation you must do so using -cancelOperation:, lest things get +// very confused. +// +// o Both -addXxxOperation:finishedTarget:action: and -cancelOperation: can be called from +// any thread. +// +// o If you always cancel the operation on the same thread that you used to queue the operation +// (and therefore the same thread that will run the target/action completion), you can be +// guaranteed that, after -cancelOperation: returns, the target/action completion will +// never be called. +// +// o To simplify clean up, -cancelOperation: does nothing if the supplied operation is nil +// or if it's not currently queued. +// +// We don't do any prioritisation of operations, although that would be a relatively +// simple extension. For example, you could have one network transfer queue for gallery XML +// files and another for thumbnail downloads, and tweak their widths appropriately. And +// don't forget, within a queue, a client can affect the priority of an operation using +// -[NSOperation setThreadPriority:] and -[NSOperation setQueuePriority:]. + +- (void)addNetworkManagementOperation:(NSOperation *)operation finishedTarget:(id)target action:(SEL)action; +- (void)addNetworkTransferOperation:(NSOperation *)operation finishedTarget:(id)target action:(SEL)action; +- (void)addCPUOperation:(NSOperation *)operation finishedTarget:(id)target action:(SEL)action; +- (void)cancelOperation:(NSOperation *)operation; + +@end diff --git a/MVCNetworking/Networking/NetworkManager.m b/MVCNetworking/Networking/NetworkManager.m new file mode 100644 index 0000000..22e2d25 --- /dev/null +++ b/MVCNetworking/Networking/NetworkManager.m @@ -0,0 +1,512 @@ +/* + File: NetworkManager.m + + Contains: A singleton to manage the core network interactions. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "NetworkManager.h" + +#import "QHTTPOperation.h" + +#import "Logging.h" + +@interface NetworkManager () + +// private properties + +@property (nonatomic, retain, readonly ) NSThread * networkRunLoopThread; + +@property (nonatomic, retain, readonly ) NSOperationQueue * queueForNetworkTransfers; +@property (nonatomic, retain, readonly ) NSOperationQueue * queueForNetworkManagement; +@property (nonatomic, retain, readonly ) NSOperationQueue * queueForCPU; + +@end + +@implementation NetworkManager + ++ (NetworkManager *)sharedManager + // See comment in header. +{ + static NetworkManager * sNetworkManager; + + // This can be called on any thread, so we synchronise. We only do this in + // the sNetworkManager case because, once sNetworkManager goes non-nil, it can + // never go nil again. + + if (sNetworkManager == nil) { + @synchronized (self) { + sNetworkManager = [[NetworkManager alloc] init]; + assert(sNetworkManager != nil); + } + } + return sNetworkManager; +} + +- (id)init +{ + // any thread, but serialised by +sharedManager + self = [super init]; + if (self != nil) { + + // Create the network management queue. We will run an unbounded number of these operations + // in parallel because each one consumes minimal resources. + + self->_queueForNetworkManagement = [[NSOperationQueue alloc] init]; + assert(self->_queueForNetworkManagement != nil); + + [self->_queueForNetworkManagement setMaxConcurrentOperationCount:NSIntegerMax]; + assert(self->_queueForNetworkManagement != nil); + + // Create the network transfer queue. We will run up to 4 simultaneous network requests. + + self->_queueForNetworkTransfers = [[NSOperationQueue alloc] init]; + assert(self->_queueForNetworkTransfers != nil); + + [self->_queueForNetworkTransfers setMaxConcurrentOperationCount:4]; + assert(self->_queueForNetworkTransfers != nil); + + // Create the CPU queue. In contrast to the network queues, we leave + // maxConcurrentOperationCount set to the default, which means on current iOS devices + // the CPU operations are serialised. There's no point bouncing a single CPU between + // threads for this stuff. + + self->_queueForCPU = [[NSOperationQueue alloc] init]; + assert(self->_queueForCPU != nil); + + // Create two dictionaries to store the target and action for each queued operation. + // Note that we retain the operation and the target but there's no need to retain the + // action selector. + + self->_runningOperationToTargetMap = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + assert(self->_runningOperationToTargetMap != NULL); + self->_runningOperationToActionMap = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL); + assert(self->_runningOperationToActionMap != NULL); + self->_runningOperationToThreadMap = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + assert(self->_runningOperationToThreadMap != NULL); + + // We run all of our network callbacks on a secondary thread to ensure that they don't + // contribute to main thread latency. Create and configure that thread. + + self->_networkRunLoopThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRunLoopThreadEntry) object:nil]; + assert(self->_networkRunLoopThread != nil); + + [self->_networkRunLoopThread setName:@"networkRunLoopThread"]; + if ( [self->_networkRunLoopThread respondsToSelector:@selector(setThreadPriority)] ) { + [self->_networkRunLoopThread setThreadPriority:0.3]; + } + + [self->_networkRunLoopThread start]; + } + return self; +} + +- (void)dealloc +{ + // This object lives for the entire life of the application. Getting it to support being + // deallocated would be quite tricky (particularly from a threading perspective), so we + // don't even try. + assert(NO); + [super dealloc]; +} + +- (NSMutableURLRequest *)requestToGetURL:(NSURL *)url + // See comment in header. +{ + NSMutableURLRequest * result; + static NSString * sUserAgentString; + + // any thread + assert(url != nil); + + // Create the request. + + result = [NSMutableURLRequest requestWithURL:url]; + assert(result != nil); + + // Set up the user agent string. + + if (sUserAgentString == nil) { + @synchronized ([self class]) { + sUserAgentString = [[NSString alloc] initWithFormat:@"MVCNetworking/%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleVersionKey]]; + assert(sUserAgentString != nil); + } + } + [result setValue:sUserAgentString forHTTPHeaderField:@"User-Agent"]; + + return result; +} + +#pragma mark * Operation dispatch + +@synthesize networkRunLoopThread = _networkRunLoopThread; + +- (void)networkRunLoopThreadEntry + // This thread runs all of our network operation run loop callbacks. +{ + assert( ! [NSThread isMainThread] ); + while (YES) { + NSAutoreleasePool * pool; + + pool = [[NSAutoreleasePool alloc] init]; + assert(pool != nil); + + [[NSRunLoop currentRunLoop] run]; + + [pool drain]; + } + assert(NO); +} + +- (BOOL)networkInUse + // See comment in header. +{ + assert([NSThread isMainThread]); + + // I base -networkInUse off the number of running operations, not the number of running + // network operations. This is probably technically incorrect, but the reality is that + // changing it would be tricky (but not /that/ tricky) and there's some question as to + // whether it's the right thing to do anyway. In an application that did extensive CPU work + // that was unrelated to the network then, sure, you'd only want the network activity + // indicator running while you were hitting the network. But in this application + // all CPU activity is the direct result of networking, so leaving the network activity + // indicator running while this CPU activity is busy isn't too far from the mark. + + return self->_runningNetworkTransferCount != 0; +} + +- (void)incrementRunningNetworkTransferCount +{ + BOOL movingToInUse; + + assert([NSThread isMainThread]); + + movingToInUse = (self->_runningNetworkTransferCount == 0); + if (movingToInUse) { + [self willChangeValueForKey:@"networkInUse"]; + } + self->_runningNetworkTransferCount += 1; + if (movingToInUse) { + [self didChangeValueForKey:@"networkInUse"]; + } +} + +- (void)decrementRunningNetworkTransferCount +{ + BOOL movingToNotInUse; + + assert([NSThread isMainThread]); + + assert(self->_runningNetworkTransferCount != 0); + movingToNotInUse = (self->_runningNetworkTransferCount == 1); + if (movingToNotInUse) { + [self willChangeValueForKey:@"networkInUse"]; + } + self->_runningNetworkTransferCount -= 1; + if (movingToNotInUse) { + [self didChangeValueForKey:@"networkInUse"]; + } +} + +@synthesize queueForNetworkTransfers = _queueForNetworkTransfers; +@synthesize queueForNetworkManagement = _queueForNetworkManagement; +@synthesize queueForCPU = _queueForCPU; + +- (void)addOperation:(NSOperation *)operation toQueue:(NSOperationQueue *)queue finishedTarget:(id)target action:(SEL)action + // Core code to enqueue an operation on a queue. +{ + // any thread + assert(operation != nil); + assert(target != nil); + assert(action != nil); + + // In the debug build, apply our debugging preferences to any operations + // we enqueue. + + #if ! defined(NDEBUG) + + // While, in theory, networkErrorRate should only apply to network operations, we + // apply it to all operations if they support the -setDebugError: method. + + if ( [operation respondsToSelector:@selector(setDebugError:)] ) { + static NSInteger sOperationCount; + NSInteger networkErrorRate; + + networkErrorRate = [[NSUserDefaults standardUserDefaults] integerForKey:@"networkErrorRate"]; + if (networkErrorRate != 0) { + sOperationCount += 1; + if ( (sOperationCount % networkErrorRate) == 0) { + [(id)operation setDebugError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCannotConnectToHost userInfo:nil]]; + } + } + } + if ( [operation respondsToSelector:@selector(setDebugDelay:)] ) { + NSTimeInterval operationDelay; + + operationDelay = [[NSUserDefaults standardUserDefaults] doubleForKey:@"operationDelay"]; + if (operationDelay > 0.0) { + [(id)operation setDebugDelay:operationDelay]; + } + } + #endif + + // Update our networkInUse property; because we can be running on any thread, we + // do this update on the main thread. + + if (queue == self.queueForNetworkTransfers) { + [self performSelectorOnMainThread:@selector(incrementRunningNetworkTransferCount) withObject:nil waitUntilDone:NO]; + } + + // Atomically enter the operation into our target and action maps. + + @synchronized (self) { + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + + assert( CFDictionaryGetValue(self->_runningOperationToTargetMap, operation) == NULL ); // shouldn't already be in our map + assert( CFDictionaryGetValue(self->_runningOperationToActionMap, operation) == NULL ); // shouldn't already be in our map + assert( CFDictionaryGetValue(self->_runningOperationToThreadMap, operation) == NULL ); // shouldn't already be in our map + + // Add the operations to , triggering a KVO notification + // of networkInUse if required. + + CFDictionarySetValue(self->_runningOperationToTargetMap, operation, target); + CFDictionarySetValue(self->_runningOperationToActionMap, operation, action); + CFDictionarySetValue(self->_runningOperationToThreadMap, operation, [NSThread currentThread]); + + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + } + + // Observe the isFinished property of the operation. We pass the queue parameter as the + // context so that, in the completion routine, we know what queue the operation was sent + // to (necessary to decide what thread to run the target/action on). + + [operation addObserver:self forKeyPath:@"isFinished" options:0 context:queue]; + + // Queue the operation. When the operation completes, -operationDone: is called. + + [queue addOperation:operation]; +} + +- (void)addNetworkManagementOperation:(NSOperation *)operation finishedTarget:(id)target action:(SEL)action + // See comment in header. +{ + if ([operation respondsToSelector:@selector(setRunLoopThread:)]) { + if ( [(id)operation runLoopThread] == nil ) { + [ (id)operation setRunLoopThread:self.networkRunLoopThread]; + } + } + [self addOperation:operation toQueue:self.queueForNetworkManagement finishedTarget:target action:action]; +} + +- (void)addNetworkTransferOperation:(NSOperation *)operation finishedTarget:(id)target action:(SEL)action + // See comment in header. +{ + if ([operation respondsToSelector:@selector(setRunLoopThread:)]) { + if ( [(id)operation runLoopThread] == nil ) { + [ (id)operation setRunLoopThread:self.networkRunLoopThread]; + } + } + [self addOperation:operation toQueue:self.queueForNetworkTransfers finishedTarget:target action:action]; +} + +- (void)addCPUOperation:(NSOperation *)operation finishedTarget:(id)target action:(SEL)action + // See comment in header. +{ + [self addOperation:operation toQueue:self.queueForCPU finishedTarget:target action:action]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // any thread + if ( [keyPath isEqual:@"isFinished"] ) { + NSOperation * operation; + NSOperationQueue * queue; + NSThread * thread; + + operation = (NSOperation *) object; + assert([operation isKindOfClass:[NSOperation class]]); + assert([operation isFinished]); + + queue = (NSOperationQueue *) context; + assert([queue isKindOfClass:[NSOperationQueue class]]); + + [operation removeObserver:self forKeyPath:@"isFinished"]; + + @synchronized (self) { + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + + thread = (NSThread *) CFDictionaryGetValue(self->_runningOperationToThreadMap, operation); + if (thread != nil) { + [thread retain]; + } + } + + if (thread != nil) { + [self performSelector:@selector(operationDone:) onThread:thread withObject:operation waitUntilDone:NO]; + + [thread release]; + + if (queue == self.queueForNetworkTransfers) { + [self performSelectorOnMainThread:@selector(decrementRunningNetworkTransferCount) withObject:nil waitUntilDone:NO]; + } + } + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (void)operationDone:(NSOperation *)operation + // Called by the operation queue when the operation is done. We find the corresponding + // target/action and call it on this thread. +{ + id target; + SEL action; + NSThread * thread; + + // any thread + assert(operation != nil); + + // Find the target/action, if any, in the map and then remove it. + + @synchronized (self) { + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + + target = (id) CFDictionaryGetValue(self->_runningOperationToTargetMap, operation); + action = (SEL) CFDictionaryGetValue(self->_runningOperationToActionMap, operation); + thread = (NSThread *) CFDictionaryGetValue(self->_runningOperationToThreadMap, operation); + assert( (target != nil) == (action != nil) ); + assert( (target != nil) == (thread != nil) ); + + // We need target to persist across the remove /and/ after we leave the @synchronized + // block, so we retain it here. We need to test target for nil because -cancelOperation: + // might have pulled it out from underneath us. + + if (target != nil) { + [target retain]; + + assert( thread == [NSThread currentThread] ); + + CFDictionaryRemoveValue(self->_runningOperationToTargetMap, operation); + CFDictionaryRemoveValue(self->_runningOperationToActionMap, operation); + CFDictionaryRemoveValue(self->_runningOperationToThreadMap, operation); + } + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + } + + // If we removed the operation, call the target/action. However, we still have to + // test isCancelled here because -cancelOperation: might have cancelled it but + // not yet pulled it out of the map. + // + // Note that there's no race condition testing isCancelled here. We know that the + // operation is out of the map at this point (specifically, at the point we leave + // the @synchronized block), so no one can call -cancelOperation: on the operation. + // So, the final fate of the operation, cancelled or not, is determined before + // we enter the @synchronized block. + + if (target != nil) { + if ( ! [operation isCancelled] ) { + [target performSelector:action withObject:operation]; + } + + [target release]; + } +} + +- (void)cancelOperation:(NSOperation *)operation + // See comment in header. +{ + id target; + SEL action; + NSThread * thread; + + // any thread + + // To simplify the client's clean up code, we specifically allow the operation to be nil + // and the operation to not be queued. + + if (operation != nil) { + + // We do the cancellation outside of the @synchronized block because it might take + // some time. + + [operation cancel]; + + // Now we pull the target/action out of the map. + + @synchronized (self) { + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + + target = (id) CFDictionaryGetValue(self->_runningOperationToTargetMap, operation); + action = (SEL) CFDictionaryGetValue(self->_runningOperationToActionMap, operation); + thread = (NSThread *) CFDictionaryGetValue(self->_runningOperationToThreadMap, operation); + assert( (target != nil) == (action != nil) ); + assert( (target != nil) == (thread != nil) ); + + // We don't need to retain target here because we never actually call it, we just + // test it for nil. We need to test for target for nil because -operationDone: + // might have won the race to pull it out. + + if (target != nil) { + CFDictionaryRemoveValue(self->_runningOperationToTargetMap, operation); + CFDictionaryRemoveValue(self->_runningOperationToActionMap, operation); + CFDictionaryRemoveValue(self->_runningOperationToThreadMap, operation); + } + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToActionMap) ); + assert( CFDictionaryGetCount(self->_runningOperationToTargetMap) == CFDictionaryGetCount(self->_runningOperationToThreadMap) ); + } + } +} + +@end diff --git a/MVCNetworking/Networking/QHTTPOperation.h b/MVCNetworking/Networking/QHTTPOperation.h new file mode 100644 index 0000000..62332da --- /dev/null +++ b/MVCNetworking/Networking/QHTTPOperation.h @@ -0,0 +1,245 @@ +/* + File: QHTTPOperation.h + + Contains: An NSOperation that runs an HTTP request. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QRunLoopOperation.h" + +/* + QHTTPOperation is a general purpose NSOperation that runs an HTTP request. + You initialise it with an HTTP request and then, when you run the operation, + it sends the request and gathers the response. It is quite a complex + object because it handles a wide variety of edge cases, but it's very + easy to use in simple cases: + + 1. create the operation with the URL you want to get + + op = [[[QHTTPOperation alloc] initWithURL:url] autorelease]; + + 2. set up any non-default parameters, for example, set which HTTP + content types are acceptable + + op.acceptableContentTypes = [NSSet setWithObject:@"text/html"]; + + 3. enqueue the operation + + [queue addOperation:op]; + + 4. finally, when the operation is done, use the lastResponse and + error properties to find out how things went + + As mentioned above, QHTTPOperation is very general purpose. There are a + large number of configuration and result options available to you. + + o You can specify a NSURLRequest rather than just a URL. + + o You can configure the run loop and modes on which the NSURLConnection is + scheduled. + + o You can specify what HTTP status codes and content types are OK. + + o You can set an authentication delegate to handle authentication challenges. + + o You can accumulate responses in memory or in an NSOutputStream. + + o For in-memory responses, you can specify a default response size + (used to size the response buffer) and a maximum response size + (to prevent unbounded memory use). + + o You can get at the last request and the last response, to track + redirects. + + o There are a variety of funky debugging options to simulator errors + and delays. + + Finally, it's perfectly reasonable to subclass QHTTPOperation to meet you + own specific needs. Specifically, it's common for the subclass to + override -connection:didReceiveResponse: in order to setup the output + stream based on the specific details of the response. +*/ + +@protocol QHTTPOperationAuthenticationDelegate; + +@interface QHTTPOperation : QRunLoopOperation /* */ +{ + NSURLRequest * _request; + NSIndexSet * _acceptableStatusCodes; + NSSet * _acceptableContentTypes; + id _authenticationDelegate; + NSOutputStream * _responseOutputStream; + NSUInteger _defaultResponseSize; + NSUInteger _maximumResponseSize; + NSURLConnection * _connection; + BOOL _firstData; + NSMutableData * _dataAccumulator; + NSURLRequest * _lastRequest; + NSHTTPURLResponse * _lastResponse; + NSData * _responseBody; +#if ! defined(NDEBUG) + NSError * _debugError; + NSTimeInterval _debugDelay; + NSTimer * _debugDelayTimer; +#endif +} + +- (id)initWithRequest:(NSURLRequest *)request; // designated +- (id)initWithURL:(NSURL *)url; // convenience, calls +[NSURLRequest requestWithURL:] + +// Things that are configured by the init method and can't be changed. + +@property (copy, readonly) NSURLRequest * request; +@property (copy, readonly) NSURL * URL; + +// Things you can configure before queuing the operation. + +// runLoopThread and runLoopModes inherited from QRunLoopOperation +@property (copy, readwrite) NSIndexSet * acceptableStatusCodes; // default is nil, implying 200..299 +@property (copy, readwrite) NSSet * acceptableContentTypes; // default is nil, implying anything is acceptable +@property (assign, readwrite) id authenticationDelegate; + +#if ! defined(NDEBUG) +@property (copy, readwrite) NSError * debugError; // default is nil +@property (assign, readwrite) NSTimeInterval debugDelay; // default is none +#endif + +// Things you can configure up to the point where you start receiving data. +// Typically you would change these in -connection:didReceiveResponse:, but +// it is possible to change them up to the point where -connection:didReceiveData: +// is called for the first time (that is, you could override -connection:didReceiveData: +// and change these before calling super). + +// IMPORTANT: If you set a response stream, QHTTPOperation calls the response +// stream synchronously. This is fine for file and memory streams, but it would +// not work well for other types of streams (like a bound pair). + +@property (retain, readwrite) NSOutputStream * responseOutputStream; // defaults to nil, which puts response into responseBody +@property (assign, readwrite) NSUInteger defaultResponseSize; // default is 1 MB, ignored if responseOutputStream is set +@property (assign, readwrite) NSUInteger maximumResponseSize; // default is 4 MB, ignored if responseOutputStream is set + // defaults are 1/4 of the above on embedded + +// Things that are only meaningful after a response has been received; + +@property (assign, readonly, getter=isStatusCodeAcceptable) BOOL statusCodeAcceptable; +@property (assign, readonly, getter=isContentTypeAcceptable) BOOL contentTypeAcceptable; + +// Things that are only meaningful after the operation is finished. + +// error property inherited from QRunLoopOperation +@property (copy, readonly) NSURLRequest * lastRequest; +@property (copy, readonly) NSHTTPURLResponse * lastResponse; + +@property (copy, readonly) NSData * responseBody; + +@end + +@interface QHTTPOperation (NSURLConnectionDelegate) + +// QHTTPOperation implements all of these methods, so if you override them +// you must consider whether or not to call super. +// +// These will be called on the operation's run loop thread. + +- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace; + // Routes the request to the authentication delegate if it exists, otherwise + // just returns NO. + +- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; + // Routes the request to the authentication delegate if it exists, otherwise + // just cancels the challenge. + +- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response; + // Latches the request and response in lastRequest and lastResponse. + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; + // Latches the response in lastResponse. + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; + // If this is the first chunk of data, it decides whether the data is going to be + // routed to memory (responseBody) or a stream (responseOutputStream) and makes the + // appropriate preparations. For this and subsequent data it then actually shuffles + // the data to its destination. + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection; + // Completes the operation with either no error (if the response status code is acceptable) + // or an error (otherwise). + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; + // Completes the operation with the error. + +@end + +@protocol QHTTPOperationAuthenticationDelegate +@required + +// These are called on the operation's run loop thread and have the same semantics as their +// NSURLConnection equivalents. It's important to realise that there is no +// didCancelAuthenticationChallenge callback (because NSURLConnection doesn't issue one to us). +// Rather, an authentication delegate is expected to observe the operation and cancel itself +// if the operation completes while the challenge is running. + +- (BOOL)httpOperation:(QHTTPOperation *)operation canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace; +- (void)httpOperation:(QHTTPOperation *)operation didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; + +@end + +extern NSString * kQHTTPOperationErrorDomain; + +// positive error codes are HTML status codes (when they are not allowed via acceptableStatusCodes) +// +// 0 is, of course, not a valid error code +// +// negative error codes are errors from the module + +enum { + kQHTTPOperationErrorResponseTooLarge = -1, + kQHTTPOperationErrorOnOutputStream = -2, + kQHTTPOperationErrorBadContentType = -3 +}; diff --git a/MVCNetworking/Networking/QHTTPOperation.m b/MVCNetworking/Networking/QHTTPOperation.m new file mode 100644 index 0000000..fec3f19 --- /dev/null +++ b/MVCNetworking/Networking/QHTTPOperation.m @@ -0,0 +1,653 @@ +/* + File: QHTTPOperation.m + + Contains: An NSOperation that runs an HTTP request. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QHTTPOperation.h" + +@interface QHTTPOperation () + +// Read/write versions of public properties + +@property (copy, readwrite) NSURLRequest * lastRequest; +@property (copy, readwrite) NSHTTPURLResponse * lastResponse; + +// Internal properties + +@property (retain, readwrite) NSURLConnection * connection; +@property (assign, readwrite) BOOL firstData; +@property (retain, readwrite) NSMutableData * dataAccumulator; + +#if ! defined(NDEBUG) +@property (retain, readwrite) NSTimer * debugDelayTimer; +#endif + +@end + +@implementation QHTTPOperation + +#pragma mark * Initialise and finalise + +- (id)initWithRequest:(NSURLRequest *)request + // See comment in header. +{ + // any thread + assert(request != nil); + assert([request URL] != nil); + // Because we require an NSHTTPURLResponse, we only support HTTP and HTTPS URLs. + assert([[[[request URL] scheme] lowercaseString] isEqual:@"http"] || [[[[request URL] scheme] lowercaseString] isEqual:@"https"]); + self = [super init]; + if (self != nil) { + #if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR + static const NSUInteger kPlatformReductionFactor = 4; + #else + static const NSUInteger kPlatformReductionFactor = 1; + #endif + self->_request = [request copy]; + self->_defaultResponseSize = 1 * 1024 * 1024 / kPlatformReductionFactor; + self->_maximumResponseSize = 4 * 1024 * 1024 / kPlatformReductionFactor; + self->_firstData = YES; + } + return self; +} + +- (id)initWithURL:(NSURL *)url + // See comment in header. +{ + assert(url != nil); + return [self initWithRequest:[NSURLRequest requestWithURL:url]]; +} + +- (void)dealloc +{ + #if ! defined(NDEBUG) + [self->_debugError release]; + [self->_debugDelayTimer invalidate]; + [self->_debugDelayTimer release]; + #endif + // any thread + [self->_request release]; + [self->_acceptableStatusCodes release]; + [self->_acceptableContentTypes release]; + [self->_responseOutputStream release]; + assert(self->_connection == nil); // should have been shut down by now + [self->_dataAccumulator release]; + [self->_lastRequest release]; + [self->_lastResponse release]; + [self->_responseBody release]; + [super dealloc]; +} + +#pragma mark * Properties + +// We write our own settings for many properties because we want to bounce +// sets that occur in the wrong state. And, given that we've written the +// setter anyway, we also avoid KVO notifications when the value doesn't change. + +@synthesize request = _request; + +@synthesize authenticationDelegate = _authenticationDelegate; + ++ (BOOL)automaticallyNotifiesObserversOfAuthenticationDelegate +{ + return NO; +} + +- (id)authenticationDelegate +{ + return self->_authenticationDelegate; +} + +- (void)setAuthenticationDelegate:(id)newValue +{ + if (self.state != kQRunLoopOperationStateInited) { + assert(NO); + } else { + if (newValue != self->_authenticationDelegate) { + [self willChangeValueForKey:@"authenticationDelegate"]; + self->_authenticationDelegate = newValue; + [self didChangeValueForKey:@"authenticationDelegate"]; + } + } +} + +@synthesize acceptableStatusCodes = _acceptableStatusCodes; + ++ (BOOL)automaticallyNotifiesObserversOfAcceptableStatusCodes +{ + return NO; +} + +- (NSIndexSet *)acceptableStatusCodes +{ + return [[self->_acceptableStatusCodes retain] autorelease]; +} + +- (void)setAcceptableStatusCodes:(NSIndexSet *)newValue +{ + if (self.state != kQRunLoopOperationStateInited) { + assert(NO); + } else { + if (newValue != self->_acceptableStatusCodes) { + [self willChangeValueForKey:@"acceptableStatusCodes"]; + [self->_acceptableStatusCodes autorelease]; + self->_acceptableStatusCodes = [newValue copy]; + [self didChangeValueForKey:@"acceptableStatusCodes"]; + } + } +} + +@synthesize acceptableContentTypes = _acceptableContentTypes; + ++ (BOOL)automaticallyNotifiesObserversOfAcceptableContentTypes +{ + return NO; +} + +- (NSSet *)acceptableContentTypes +{ + return [[self->_acceptableContentTypes retain] autorelease]; +} + +- (void)setAcceptableContentTypes:(NSSet *)newValue +{ + if (self.state != kQRunLoopOperationStateInited) { + assert(NO); + } else { + if (newValue != self->_acceptableContentTypes) { + [self willChangeValueForKey:@"acceptableContentTypes"]; + [self->_acceptableContentTypes autorelease]; + self->_acceptableContentTypes = [newValue copy]; + [self didChangeValueForKey:@"acceptableContentTypes"]; + } + } +} + +@synthesize responseOutputStream = _responseOutputStream; + ++ (BOOL)automaticallyNotifiesObserversOfResponseOutputStream +{ + return NO; +} + +- (NSOutputStream *)responseOutputStream +{ + return [[self->_responseOutputStream retain] autorelease]; +} + +- (void)setResponseOutputStream:(NSOutputStream *)newValue +{ + if (self.dataAccumulator != nil) { + assert(NO); + } else { + if (newValue != self->_responseOutputStream) { + [self willChangeValueForKey:@"responseOutputStream"]; + [self->_responseOutputStream autorelease]; + self->_responseOutputStream = [newValue retain]; + [self didChangeValueForKey:@"responseOutputStream"]; + } + } +} + +@synthesize defaultResponseSize = _defaultResponseSize; + ++ (BOOL)automaticallyNotifiesObserversOfDefaultResponseSize +{ + return NO; +} + +- (NSUInteger)defaultResponseSize +{ + return self->_defaultResponseSize; +} + +- (void)setDefaultResponseSize:(NSUInteger)newValue +{ + if (self.dataAccumulator != nil) { + assert(NO); + } else { + if (newValue != self->_defaultResponseSize) { + [self willChangeValueForKey:@"defaultResponseSize"]; + self->_defaultResponseSize = newValue; + [self didChangeValueForKey:@"defaultResponseSize"]; + } + } +} + +@synthesize maximumResponseSize = _maximumResponseSize; + ++ (BOOL)automaticallyNotifiesObserversOfMaximumResponseSize +{ + return NO; +} + +- (NSUInteger)maximumResponseSize +{ + return self->_maximumResponseSize; +} + +- (void)setMaximumResponseSize:(NSUInteger)newValue +{ + if (self.dataAccumulator != nil) { + assert(NO); + } else { + if (newValue != self->_maximumResponseSize) { + [self willChangeValueForKey:@"maximumResponseSize"]; + self->_maximumResponseSize = newValue; + [self didChangeValueForKey:@"maximumResponseSize"]; + } + } +} + +@synthesize lastRequest = _lastRequest; +@synthesize lastResponse = _lastResponse; +@synthesize responseBody = _responseBody; + +@synthesize connection = _connection; +@synthesize firstData = _firstData; +@synthesize dataAccumulator = _dataAccumulator; + +- (NSURL *)URL +{ + return [self.request URL]; +} + +- (BOOL)isStatusCodeAcceptable +{ + NSIndexSet * acceptableStatusCodes; + NSInteger statusCode; + + assert(self.lastResponse != nil); + + acceptableStatusCodes = self.acceptableStatusCodes; + if (acceptableStatusCodes == nil) { + acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)]; + } + assert(acceptableStatusCodes != nil); + + statusCode = [self.lastResponse statusCode]; + return (statusCode >= 0) && [acceptableStatusCodes containsIndex: (NSUInteger) statusCode]; +} + +- (BOOL)isContentTypeAcceptable +{ + NSString * contentType; + + assert(self.lastResponse != nil); + contentType = [self.lastResponse MIMEType]; + return (self.acceptableContentTypes == nil) || ((contentType != nil) && [self.acceptableContentTypes containsObject:contentType]); +} + +#pragma mark * Start and finish overrides + +- (void)operationDidStart + // Called by QRunLoopOperation when the operation starts. This kicks of an + // asynchronous NSURLConnection. +{ + assert(self.isActualRunLoopThread); + assert(self.state == kQRunLoopOperationStateExecuting); + + assert(self.defaultResponseSize > 0); + assert(self.maximumResponseSize > 0); + assert(self.defaultResponseSize <= self.maximumResponseSize); + + assert(self.request != nil); + + // If a debug error is set, apply that error rather than running the connection. + + #if ! defined(NDEBUG) + if (self.debugError != nil) { + [self finishWithError:self.debugError]; + return; + } + #endif + + // Create a connection that's scheduled in the required run loop modes. + + assert(self.connection == nil); + self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease]; + assert(self.connection != nil); + + for (NSString * mode in self.actualRunLoopModes) { + [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; + } + + [self.connection start]; +} + +- (void)operationWillFinish + // Called by QRunLoopOperation when the operation has finished. We + // do various bits of tidying up. +{ + assert(self.isActualRunLoopThread); + assert(self.state == kQRunLoopOperationStateExecuting); + + // It is possible to hit this state of the operation is cancelled while + // the debugDelayTimer is running. In that case, hey, we'll just accept + // the inevitable and finish rather than trying anything else clever. + + #if ! defined(NDEBUG) + if (self.debugDelayTimer != nil) { + [self.debugDelayTimer invalidate]; + self.debugDelayTimer = nil; + } + #endif + + [self.connection cancel]; + self.connection = nil; + + // If we have an output stream, close it at this point. We might never + // have actually opened this stream but, AFAICT, closing an unopened stream + // doesn't hurt. + + if (self.responseOutputStream != nil) { + [self.responseOutputStream close]; + } +} + +- (void)finishWithError:(NSError *)error + // We override -finishWithError: just so we can handle our debug delay. +{ + // If a debug delay was set, don't finish now but rather start the debug delay timer + // and have it do the actual finish. We clear self.debugDelay so that the next + // time this code runs its doesn't do this again. + // + // We only do this in the non-cancellation case. In the cancellation case, we + // just stop immediately. + + #if ! defined(NDEBUG) + if (self.debugDelay > 0.0) { + if ( (error != nil) && [[error domain] isEqual:NSCocoaErrorDomain] && ([error code] == NSUserCancelledError) ) { + self.debugDelay = 0.0; + } else { + assert(self.debugDelayTimer == nil); + self.debugDelayTimer = [NSTimer timerWithTimeInterval:self.debugDelay target:self selector:@selector(debugDelayTimerDone:) userInfo:error repeats:NO]; + assert(self.debugDelayTimer != nil); + for (NSString * mode in self.actualRunLoopModes) { + [[NSRunLoop currentRunLoop] addTimer:self.debugDelayTimer forMode:mode]; + } + self.debugDelay = 0.0; + return; + } + } + #endif + + [super finishWithError:error]; +} + +#if ! defined(NDEBUG) + +@synthesize debugError = _debugError; +@synthesize debugDelay = _debugDelay; +@synthesize debugDelayTimer = _debugDelayTimer; + +- (void)debugDelayTimerDone:(NSTimer *)timer +{ + NSError * error; + + assert(timer == self.debugDelayTimer); + + error = [[[timer userInfo] retain] autorelease]; + assert( (error == nil) || [error isKindOfClass:[NSError class]] ); + + [self.debugDelayTimer invalidate]; + self.debugDelayTimer = nil; + + [self finishWithError:error]; +} + +#endif + +#pragma mark * NSURLConnection delegate callbacks + +- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace + // See comment in header. +{ + BOOL result; + + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + assert(protectionSpace != nil); + #pragma unused(protectionSpace) + + result = NO; + if (self.authenticationDelegate != nil) { + result = [self.authenticationDelegate httpOperation:self canAuthenticateAgainstProtectionSpace:protectionSpace]; + } + return result; +} + +- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge + // See comment in header. +{ + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + assert(challenge != nil); + #pragma unused(challenge) + + if (self.authenticationDelegate != nil) { + [self.authenticationDelegate httpOperation:self didReceiveAuthenticationChallenge:challenge]; + } else { + if ( [challenge previousFailureCount] == 0 ) { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } else { + [[challenge sender] cancelAuthenticationChallenge:challenge]; + } + } +} + +- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response + // See comment in header. +{ + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + assert( (response == nil) || [response isKindOfClass:[NSHTTPURLResponse class]] ); + + self.lastRequest = request; + self.lastResponse = (NSHTTPURLResponse *) response; + return request; +} + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response + // See comment in header. +{ + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + assert([response isKindOfClass:[NSHTTPURLResponse class]]); + + self.lastResponse = (NSHTTPURLResponse *) response; + + // We don't check the status code here because we want to give the client an opportunity + // to get the data of the error message. Perhaps we /should/ check the content type + // here, but I'm not sure whether that's the right thing to do. +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data + // See comment in header. +{ + BOOL success; + + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + assert(data != nil); + + // If we don't yet have a destination for the data, calculate one. Note that, even + // if there is an output stream, we don't use it for error responses. + + success = YES; + if (self.firstData) { + assert(self.dataAccumulator == nil); + + if ( (self.responseOutputStream == nil) || ! self.isStatusCodeAcceptable ) { + long long length; + + assert(self.dataAccumulator == nil); + + length = [self.lastResponse expectedContentLength]; + if (length == NSURLResponseUnknownLength) { + length = self.defaultResponseSize; + } + if (length <= (long long) self.maximumResponseSize) { + self.dataAccumulator = [NSMutableData dataWithCapacity:(NSUInteger)length]; + } else { + [self finishWithError:[NSError errorWithDomain:kQHTTPOperationErrorDomain code:kQHTTPOperationErrorResponseTooLarge userInfo:nil]]; + success = NO; + } + } + + // If the data is going to an output stream, open it. + + if (success) { + if (self.dataAccumulator == nil) { + assert(self.responseOutputStream != nil); + [self.responseOutputStream open]; + } + } + + self.firstData = NO; + } + + // Write the data to its destination. + + if (success) { + if (self.dataAccumulator != nil) { + if ( ([self.dataAccumulator length] + [data length]) <= self.maximumResponseSize ) { + [self.dataAccumulator appendData:data]; + } else { + [self finishWithError:[NSError errorWithDomain:kQHTTPOperationErrorDomain code:kQHTTPOperationErrorResponseTooLarge userInfo:nil]]; + } + } else { + NSUInteger dataOffset; + NSUInteger dataLength; + const uint8_t * dataPtr; + NSError * error; + NSInteger bytesWritten; + + assert(self.responseOutputStream != nil); + + dataOffset = 0; + dataLength = [data length]; + dataPtr = [data bytes]; + error = nil; + do { + if (dataOffset == dataLength) { + break; + } + bytesWritten = [self.responseOutputStream write:&dataPtr[dataOffset] maxLength:dataLength - dataOffset]; + if (bytesWritten <= 0) { + error = [self.responseOutputStream streamError]; + if (error == nil) { + error = [NSError errorWithDomain:kQHTTPOperationErrorDomain code:kQHTTPOperationErrorOnOutputStream userInfo:nil]; + } + break; + } else { + dataOffset += bytesWritten; + } + } while (YES); + + if (error != nil) { + [self finishWithError:error]; + } + } + } +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection + // See comment in header. +{ + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + + assert(self.lastResponse != nil); + + // Swap the data accumulator over to the response data so that we don't trigger a copy. + + assert(self->_responseBody == nil); + self->_responseBody = self->_dataAccumulator; + self->_dataAccumulator = nil; + + // Because we fill out _dataAccumulator lazily, an empty body will leave _dataAccumulator + // set to nil. That's not what our clients expect, so we fix it here. + + if (self->_responseBody == nil) { + self->_responseBody = [[NSData alloc] init]; + assert(self->_responseBody != nil); + } + + if ( ! self.isStatusCodeAcceptable ) { + [self finishWithError:[NSError errorWithDomain:kQHTTPOperationErrorDomain code:self.lastResponse.statusCode userInfo:nil]]; + } else if ( ! self.isContentTypeAcceptable ) { + [self finishWithError:[NSError errorWithDomain:kQHTTPOperationErrorDomain code:kQHTTPOperationErrorBadContentType userInfo:nil]]; + } else { + [self finishWithError:nil]; + } +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error + // See comment in header. +{ + assert(self.isActualRunLoopThread); + assert(connection == self.connection); + #pragma unused(connection) + assert(error != nil); + + [self finishWithError:error]; +} + +@end + +NSString * kQHTTPOperationErrorDomain = @"kQHTTPOperationErrorDomain"; diff --git a/MVCNetworking/Networking/QReachabilityOperation.h b/MVCNetworking/Networking/QReachabilityOperation.h new file mode 100644 index 0000000..7f3c257 --- /dev/null +++ b/MVCNetworking/Networking/QReachabilityOperation.h @@ -0,0 +1,86 @@ +/* + File: QReachabilityOperation.h + + Contains: Runs until a host's reachability attains a certain value. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QRunLoopOperation.h" + +#include + +@interface QReachabilityOperation : QRunLoopOperation +{ + NSString * _hostName; + NSUInteger _flagsTargetMask; + NSUInteger _flagsTargetValue; + NSUInteger _flags; + SCNetworkReachabilityRef _ref; +} + +- (id)initWithHostName:(NSString *)hostName; + // Initialises the operation to monitor the reachability of the specified + // host. The operation finishes when (flags & flagsTargetMask) == flagsTargetValue. + +// Things that are configured by the init method and can't be changed. + +@property (copy, readonly ) NSString * hostName; + +// Things you can configure before queuing the operation. + +// runLoopThread and runLoopModes inherited from QRunLoopOperation +@property (assign, readwrite) NSUInteger flagsTargetMask; +@property (assign, readwrite) NSUInteger flagsTargetValue; + +// Things that change as part of the progress of the operation. + +// error property inherited from QRunLoopOperation +@property (assign, readonly ) NSUInteger flags; // observable, changes on the actual run loop thread + +@end diff --git a/MVCNetworking/Networking/QReachabilityOperation.m b/MVCNetworking/Networking/QReachabilityOperation.m new file mode 100644 index 0000000..c87bb4c --- /dev/null +++ b/MVCNetworking/Networking/QReachabilityOperation.m @@ -0,0 +1,174 @@ +/* + File: QReachabilityOperation.h + + Contains: Runs until a host's reachability attains a certain value. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QReachabilityOperation.h" + +@interface QReachabilityOperation () + +// read/write versions of public properties + +@property (assign, readwrite) NSUInteger flags; + +// forward declarations + +static void ReachabilityCallback( + SCNetworkReachabilityRef target, + SCNetworkReachabilityFlags flags, + void * info +); + +- (void)reachabilitySetFlags:(NSUInteger)newValue; + +@end + +@implementation QReachabilityOperation + +- (id)initWithHostName:(NSString *)hostName + // See comment in header. +{ + assert(hostName != nil); + self = [super init]; + if (self != nil) { + self->_hostName = [hostName copy]; + self->_flagsTargetMask = kSCNetworkReachabilityFlagsReachable | kSCNetworkReachabilityFlagsInterventionRequired; + self->_flagsTargetValue = kSCNetworkReachabilityFlagsReachable; + } + return self; +} + +- (void)dealloc +{ + [self->_hostName release]; + assert(self->_ref == NULL); + [super dealloc]; +} + +@synthesize hostName = _hostName; +@synthesize flagsTargetMask = _flagsTargetMask; +@synthesize flagsTargetValue = _flagsTargetValue; +@synthesize flags = _flags; + +- (void)operationDidStart + // Called by QRunLoopOperation when the operation starts. This is our opportunity + // to install our run loop callbacks, which is exactly what we do. The only tricky + // thing is that we have to schedule the reachability ref to run in all of the + // run loop modes specified by our client. +{ + Boolean success; + SCNetworkReachabilityContext context = { 0, self, NULL, NULL, NULL }; + + assert(self->_ref == NULL); + self->_ref = SCNetworkReachabilityCreateWithName(NULL, [self.hostName UTF8String]); + assert(self->_ref != NULL); + + success = SCNetworkReachabilitySetCallback(self->_ref, ReachabilityCallback, &context); + assert(success); + + for (NSString * mode in self.actualRunLoopModes) { + success = SCNetworkReachabilityScheduleWithRunLoop(self->_ref, CFRunLoopGetCurrent(), (CFStringRef) mode); + assert(success); + } +} + +static void ReachabilityCallback( + SCNetworkReachabilityRef target, + SCNetworkReachabilityFlags flags, + void * info +) + // Called by the system when the reachability flags change. We just forward + // the flags to our Objective-C code. +{ + QReachabilityOperation * obj; + + obj = (QReachabilityOperation *) info; + assert([obj isKindOfClass:[QReachabilityOperation class]]); + assert(target == obj->_ref); + #pragma unused(target) + + [obj reachabilitySetFlags:flags]; +} + +- (void)reachabilitySetFlags:(NSUInteger)newValue + // Called when the reachability flags change. We just store the flags and then + // check to see if the flags meet our target criteria, in which case we stop the + // operation. +{ + assert( [NSThread currentThread] == self.actualRunLoopThread ); + + self.flags = newValue; + if ( (self.flags & self.flagsTargetMask) == self.flagsTargetValue ) { + [self finishWithError:nil]; + } +} + +- (void)operationWillFinish + // Called by QRunLoopOperation when the operation finishes. We just clean up + // our reachability ref. +{ + Boolean success; + + if (self->_ref != NULL) { + for (NSString * mode in self.actualRunLoopModes) { + success = SCNetworkReachabilityUnscheduleFromRunLoop(self->_ref, CFRunLoopGetCurrent(), (CFStringRef) mode); + assert(success); + } + + success = SCNetworkReachabilitySetCallback(self->_ref, NULL, NULL); + assert(success); + + CFRelease(self->_ref); + self->_ref = NULL; + } +} + +@end diff --git a/MVCNetworking/Networking/QRunLoopOperation.h b/MVCNetworking/Networking/QRunLoopOperation.h new file mode 100644 index 0000000..7c1f76f --- /dev/null +++ b/MVCNetworking/Networking/QRunLoopOperation.h @@ -0,0 +1,119 @@ +/* + File: QRunLoopOperation.h + + Contains: An abstract subclass of NSOperation for async run loop based operations. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +enum QRunLoopOperationState { + kQRunLoopOperationStateInited, + kQRunLoopOperationStateExecuting, + kQRunLoopOperationStateFinished +}; +typedef enum QRunLoopOperationState QRunLoopOperationState; + +@interface QRunLoopOperation : NSOperation +{ + QRunLoopOperationState _state; + NSThread * _runLoopThread; + NSSet * _runLoopModes; + NSError * _error; +} + +// Things you can configure before queuing the operation. + +// IMPORTANT: Do not change these after queuing the operation; it's very likely that +// bad things will happen if you do. + +@property (retain, readwrite) NSThread * runLoopThread; // default is nil, implying main thread +@property (copy, readwrite) NSSet * runLoopModes; // default is nil, implying set containing NSDefaultRunLoopMode + +// Things that are only meaningful after the operation is finished. + +@property (copy, readonly ) NSError * error; + +// Things you can only alter implicitly. + +@property (assign, readonly ) QRunLoopOperationState state; +@property (retain, readonly ) NSThread * actualRunLoopThread; // main thread if runLoopThread is nil, runLoopThread otherwise +@property (assign, readonly ) BOOL isActualRunLoopThread; // YES if the current thread is the actual run loop thread +@property (copy, readonly ) NSSet * actualRunLoopModes; // set containing NSDefaultRunLoopMode if runLoopModes is nil or empty, runLoopModes otherwise + +@end + +@interface QRunLoopOperation (SubClassSupport) + +// Override points + +// A subclass will probably need to override -operationDidStart and -operationWillFinish +// to set up and tear down its run loop sources, respectively. These are always called +// on the actual run loop thread. +// +// Note that -operationWillFinish will be called even if the operation is cancelled. +// +// -operationWillFinish can check the error property to see whether the operation was +// successful. error will be NSCocoaErrorDomain/NSUserCancelledError on cancellation. +// +// -operationDidStart is allowed to call -finishWithError:. + +- (void)operationDidStart; +- (void)operationWillFinish; + +// Support methods + +// A subclass should call finishWithError: when the operation is complete, passing nil +// for no error and an error otherwise. It must call this on the actual run loop thread. +// +// Note that this will call -operationWillFinish before returning. + +- (void)finishWithError:(NSError *)error; + +@end diff --git a/MVCNetworking/Networking/QRunLoopOperation.m b/MVCNetworking/Networking/QRunLoopOperation.m new file mode 100644 index 0000000..ab75aa2 --- /dev/null +++ b/MVCNetworking/Networking/QRunLoopOperation.m @@ -0,0 +1,359 @@ +/* + File: QRunLoopOperation.m + + Contains: An abstract subclass of NSOperation for async run loop based operations. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QRunLoopOperation.h" + +/* + Theory of Operation + ------------------- + Some critical points: + + 1. By the time we're running on the run loop thread, we know that all further state + transitions happen on the run loop thread. That's because there are only three + states (inited, executing, and finished) and run loop thread code can only run + in the last two states and the transition from executing to finished is + always done on the run loop thread. + + 2. -start can only be called once. So run loop thread code doesn't have to worry + about racing with -start because, by the time the run loop thread code runs, + -start has already been called. + + 3. -cancel can be called multiple times from any thread. Run loop thread code + must take a lot of care with do the right thing with cancellation. + + Some state transitions: + + 1. init -> dealloc + 2. init -> cancel -> dealloc +XXX 3. init -> cancel -> start -> finish -> dealloc + 4. init -> cancel -> start -> startOnRunLoopThreadThread -> finish dealloc +!!! 5. init -> start -> cancel -> startOnRunLoopThreadThread -> finish -> cancelOnRunLoopThreadThread -> dealloc +XXX 6. init -> start -> cancel -> cancelOnRunLoopThreadThread -> startOnRunLoopThreadThread -> finish -> dealloc +XXX 7. init -> start -> cancel -> startOnRunLoopThreadThread -> cancelOnRunLoopThreadThread -> finish -> dealloc + 8. init -> start -> startOnRunLoopThreadThread -> finish -> dealloc + 9. init -> start -> startOnRunLoopThreadThread -> cancel -> cancelOnRunLoopThreadThread -> finish -> dealloc +!!! 10. init -> start -> startOnRunLoopThreadThread -> cancel -> finish -> cancelOnRunLoopThreadThread -> dealloc + 11. init -> start -> startOnRunLoopThreadThread -> finish -> cancel -> dealloc + + Markup: + XXX means that the case doesn't happen. + !!! means that the case is interesting. + + Described: + + 1. It's valid to allocate an operation and never run it. + 2. It's also valid to allocate an operation, cancel it, and yet never run it. + 3. While it's valid to cancel an operation before it starting it, this case doesn't + happen because -start always bounces to the run loop thread to maintain the invariant + that the executing to finished transition always happens on the run loop thread. + 4. In this -startOnRunLoopThread detects the cancellation and finishes immediately. + 5. Because the -cancel can happen on any thread, it's possible for the -cancel + to come in between the -start and the -startOnRunLoop thread. In this case + -startOnRunLoopThread notices isCancelled and finishes straightaway. And + -cancelOnRunLoopThread detects that the operation is finished and does nothing. + 6. This case can never happen because -performSelecton:onThread:xxx + callbacks happen in order, -start is synchronised with -cancel, and -cancel + only schedules if -start has run. + 7. This case can never happen because -startOnRunLoopThread will finish immediately + if it detects isCancelled (see case 5). + 8. This is the standard run-to-completion case. + 9. This is the standard cancellation case. -cancelOnRunLoopThread wins the race + with finish, and it detects that the operation is executing and actually cancels. + 10. In this case the -cancelOnRunLoopThread loses the race with finish, but that's OK + because -cancelOnRunLoopThread already does nothing if the operation is already + finished. + 11. Cancellating after finishing still sets isCancelled but has no impact + on the RunLoop thread code. +*/ + +@interface QRunLoopOperation () + +// read/write versions of public properties + +@property (assign, readwrite) QRunLoopOperationState state; +@property (copy, readwrite) NSError * error; + +@end + +@implementation QRunLoopOperation + +- (id)init +{ + self = [super init]; + if (self != nil) { + assert(self->_state == kQRunLoopOperationStateInited); + } + return self; +} + +- (void)dealloc +{ + assert(self->_state != kQRunLoopOperationStateExecuting); + [self->_runLoopModes release]; + [self->_runLoopThread release]; + [self->_error release]; + [super dealloc]; +} + +#pragma mark * Properties + +@synthesize runLoopThread = _runLoopThread; +@synthesize runLoopModes = _runLoopModes; + +- (NSThread *)actualRunLoopThread + // Returns the effective run loop thread, that is, the one set by the user + // or, if that's not set, the main thread. +{ + NSThread * result; + + result = self.runLoopThread; + if (result == nil) { + result = [NSThread mainThread]; + } + return result; +} + +- (BOOL)isActualRunLoopThread + // Returns YES if the current thread is the actual run loop thread. +{ + return [[NSThread currentThread] isEqual:self.actualRunLoopThread]; +} + +- (NSSet *)actualRunLoopModes +{ + NSSet * result; + + result = self.runLoopModes; + if ( (result == nil) || ([result count] == 0) ) { + result = [NSSet setWithObject:NSDefaultRunLoopMode]; + } + return result; +} + +@synthesize error = _error; + +#pragma mark * Core state transitions + +- (QRunLoopOperationState)state +{ + return self->_state; +} + +- (void)setState:(QRunLoopOperationState)newState + // Change the state of the operation, sending the appropriate KVO notifications. +{ + // any thread + + @synchronized (self) { + QRunLoopOperationState oldState; + + // The following check is really important. The state can only go forward, and there + // should be no redundant changes to the state (that is, newState must never be + // equal to self->_state). + + assert(newState > self->_state); + + // Transitions from executing to finished must be done on the run loop thread. + + assert( (newState != kQRunLoopOperationStateFinished) || self.isActualRunLoopThread ); + + // inited + executing -> isExecuting + // inited + finished -> isFinished + // executing + finished -> isExecuting + isFinished + + oldState = self->_state; + if ( (newState == kQRunLoopOperationStateExecuting) || (oldState == kQRunLoopOperationStateExecuting) ) { + [self willChangeValueForKey:@"isExecuting"]; + } + if (newState == kQRunLoopOperationStateFinished) { + [self willChangeValueForKey:@"isFinished"]; + } + self->_state = newState; + if (newState == kQRunLoopOperationStateFinished) { + [self didChangeValueForKey:@"isFinished"]; + } + if ( (newState == kQRunLoopOperationStateExecuting) || (oldState == kQRunLoopOperationStateExecuting) ) { + [self didChangeValueForKey:@"isExecuting"]; + } + } +} + +- (void)startOnRunLoopThread + // Starts the operation. The actual -start method is very simple, + // deferring all of the work to be done on the run loop thread by this + // method. +{ + assert(self.isActualRunLoopThread); + assert(self.state == kQRunLoopOperationStateExecuting); + + if ([self isCancelled]) { + + // We were cancelled before we even got running. Flip the the finished + // state immediately. + + [self finishWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]]; + } else { + [self operationDidStart]; + } +} + +- (void)cancelOnRunLoopThread + // Cancels the operation. +{ + assert(self.isActualRunLoopThread); + + // We know that a) state was kQRunLoopOperationStateExecuting when we were + // scheduled (that's enforced by -cancel), and b) the state can't go + // backwards (that's enforced by -setState), so we know the state must + // either be kQRunLoopOperationStateExecuting or kQRunLoopOperationStateFinished. + // We also know that the transition from executing to finished always + // happens on the run loop thread. Thus, we don't need to lock here. + // We can look at state and, if we're executing, trigger a cancellation. + + if (self.state == kQRunLoopOperationStateExecuting) { + [self finishWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]]; + } +} + +- (void)finishWithError:(NSError *)error +{ + assert(self.isActualRunLoopThread); + // error may be nil + + if (self.error == nil) { + self.error = error; + } + [self operationWillFinish]; + self.state = kQRunLoopOperationStateFinished; +} + +#pragma mark * Subclass override points + +- (void)operationDidStart +{ + assert(self.isActualRunLoopThread); +} + +- (void)operationWillFinish +{ + assert(self.isActualRunLoopThread); +} + +#pragma mark * Overrides + +- (BOOL)isConcurrent +{ + // any thread + return YES; +} + +- (BOOL)isExecuting +{ + // any thread + return self.state == kQRunLoopOperationStateExecuting; +} + +- (BOOL)isFinished +{ + // any thread + return self.state == kQRunLoopOperationStateFinished; +} + +- (void)start +{ + // any thread + + assert(self.state == kQRunLoopOperationStateInited); + + // We have to change the state here, otherwise isExecuting won't necessarily return + // true by the time we return from -start. Also, we don't test for cancellation + // here because that would a) result in us sending isFinished notifications on a + // thread that isn't our run loop thread, and b) confuse the core cancellation code, + // which expects to run on our run loop thread. Finally, we don't have to worry + // about races with other threads calling -start. Only one thread is allowed to + // start us at a time. + + self.state = kQRunLoopOperationStateExecuting; + [self performSelector:@selector(startOnRunLoopThread) onThread:self.actualRunLoopThread withObject:nil waitUntilDone:NO modes:[self.actualRunLoopModes allObjects]]; +} + +- (void)cancel +{ + BOOL runCancelOnRunLoopThread; + BOOL oldValue; + + // any thread + + // We need to synchronise here to avoid state changes to isCancelled and state + // while we're running. + + @synchronized (self) { + oldValue = [self isCancelled]; + + // Call our super class so that isCancelled starts returning true immediately. + + [super cancel]; + + // If we were the one to set isCancelled (that is, we won the race with regards + // other threads calling -cancel) and we're actually running (that is, we lost + // the race with other threads calling -start and the run loop thread finishing), + // we schedule to run on the run loop thread. + + runCancelOnRunLoopThread = ! oldValue && self.state == kQRunLoopOperationStateExecuting; + } + if (runCancelOnRunLoopThread) { + [self performSelector:@selector(cancelOnRunLoopThread) onThread:self.actualRunLoopThread withObject:nil waitUntilDone:YES modes:[self.actualRunLoopModes allObjects]]; + } +} + +@end diff --git a/MVCNetworking/Networking/RetryingHTTPOperation.h b/MVCNetworking/Networking/RetryingHTTPOperation.h new file mode 100644 index 0000000..656af3f --- /dev/null +++ b/MVCNetworking/Networking/RetryingHTTPOperation.h @@ -0,0 +1,151 @@ +/* + File: RetryingHTTPOperation.h + + Contains: Runs an HTTP request, with support for retries. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QRunLoopOperation.h" + +/* + RetryingHTTPOperation is a run loop based concurrent operation that initiates + an HTTP request and handles retrying the request if it fails. There are a bunch + of important points to note: + + o You should only use this class for idempotent requests, that is, requests that + won't cause problems if they are retried. See RFC 2616 for more info on this topic. + + + + o It only retries requests where the result is likely to change. For example, + there's no point retrying after an HTTP 404 status code. The (private) method + -shouldRetryAfterError: controls what will and won't be retried. + + o The fundamental retry mechanism is a random expotential back-off algorithm. + After a failure it choose a random delay between the 0 and the max delay. + Each failure increases the maximum delay up to some overall limit. The current + max delay sequence is one second, one minute, one hour, and six hours. + You can tweak this by changing kRetryDelays. + + o In addition to this it does a fast retry if one of the following things happens: + + - The reachability status of the host associated with the request changes from + unreachable to reachable. The change from unreachable to reachable indicates + that the local network environment has changed sufficiently to justify a + fresh retry. + + - Some other request to that host succeeds, which is a good indication that + other requests will succeed as well. + + o The operation runs out of the run loop associated with the actualRunLoopThread + inherited from QRunLoopOperation. If you observe any properties, expect them + to be changed by that thread. + + o The exception is the hasHadRetryableFailure property. This property is always + changed by the main thread. This makes it easy for main thread code to + display a 'retrying' user interface. +*/ + +@class QHTTPOperation; +@class QReachabilityOperation; + +enum RetryingHTTPOperationState { + kRetryingHTTPOperationStateNotStarted, + kRetryingHTTPOperationStateGetting, + kRetryingHTTPOperationStateWaitingToRetry, + kRetryingHTTPOperationStateRetrying, + kRetryingHTTPOperationStateFinished +}; +typedef enum RetryingHTTPOperationState RetryingHTTPOperationState; + +@interface RetryingHTTPOperation : QRunLoopOperation +{ + NSUInteger _sequenceNumber; + NSURLRequest * _request; + NSSet * _acceptableContentTypes; + NSString * _responseFilePath; + NSHTTPURLResponse * _response; + NSData * _responseContent; + RetryingHTTPOperationState _retryState; + RetryingHTTPOperationState _retryStateClient; + QHTTPOperation * _networkOperation; + BOOL _hasHadRetryableFailure; + NSUInteger _retryCount; + NSTimer * _retryTimer; + QReachabilityOperation * _reachabilityOperation; + BOOL _notificationInstalled; +} + +- (id)initWithRequest:(NSURLRequest *)request; + // Initialise the operation to run the specified HTTP request. + +// Things that are configured by the init method and can't be changed. + +@property (copy, readonly) NSURLRequest * request; + +// Things you can configure before queuing the operation. + +// runLoopThread and runLoopModes inherited from QRunLoopOperation +@property (copy, readwrite) NSSet * acceptableContentTypes; // default is nil, implying anything is acceptable +@property (retain, readwrite) NSString * responseFilePath; // defaults to nil, which puts response into responseContent + +// Things that change as part of the progress of the operation. + +@property (assign, readonly ) RetryingHTTPOperationState retryState; // observable, always changes on actualRunLoopthread +@property (assign, readonly ) RetryingHTTPOperationState retryStateClient; // observable, always changes on /main/ thread +@property (assign, readonly ) BOOL hasHadRetryableFailure; // observable, always changes on /main/ thread +@property (assign, readonly ) NSUInteger retryCount; // observable, always changes on actualRunLoopthread + +// Things that are only meaningful after the operation is finished. + +// error property inherited from QRunLoopOperation +@property (copy, readonly ) NSString * responseMIMEType; // MIME type of responseContent +@property (copy, readonly ) NSData * responseContent; // responseContent (nil if response content went to responseFilePath) + +@end diff --git a/MVCNetworking/Networking/RetryingHTTPOperation.m b/MVCNetworking/Networking/RetryingHTTPOperation.m new file mode 100644 index 0000000..d1b99be --- /dev/null +++ b/MVCNetworking/Networking/RetryingHTTPOperation.m @@ -0,0 +1,584 @@ +/* + File: RetryingHTTPOperation.m + + Contains: Runs an HTTP request, with support for retries. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "RetryingHTTPOperation.h" + +#import "NetworkManager.h" + +#import "Logging.h" + +#import "QHTTPOperation.h" +#import "QReachabilityOperation.h" + +// When one operation completes it posts the following notification. Other operations +// listen for that notification and, if the host name matches, expedite their retry. +// This means that, if one request succeeds, subsequent requests will retry quickly. + +static NSString * kRetryingHTTPOperationTransferDidSucceedNotification = @"com.apple.dts.kRetryingHTTPOperationTransferDidSucceedNotification"; +static NSString * kRetryingHTTPOperationTransferDidSucceedHostKey = @"hostName"; + +@interface RetryingHTTPOperation () + +// read/write versions of public properties + +@property (assign, readwrite) RetryingHTTPOperationState retryState; +@property (assign, readwrite) RetryingHTTPOperationState retryStateClient; +@property (assign, readwrite) BOOL hasHadRetryableFailure; +@property (assign, readwrite) NSUInteger retryCount; +@property (copy, readwrite) NSData * responseContent; + +// private properties + +@property (copy, readwrite) NSHTTPURLResponse * response; +@property (retain, readwrite) QHTTPOperation * networkOperation; +@property (retain, readwrite) NSTimer * retryTimer; +@property (retain, readwrite) QReachabilityOperation * reachabilityOperation; +@property (assign, readwrite) BOOL notificationInstalled; + +// forward declaration + +- (void)startRequest; +- (void)startReachabilityReachable:(BOOL)reachable; +- (void)startRetryAfterTimeInterval:(NSTimeInterval)delay; + +@end + +@implementation RetryingHTTPOperation + +- (id)initWithRequest:(NSURLRequest *)request + // See comment in header. +{ + assert(request != nil); + + // Certain HTTP methods are idempotent, meaning that doing the request N times is + // equivalent to doing it once. As this class will automatically retry the request, + // the requests method should be idempotent lest the automatic retries cause problems. + // For example, you could imagine a situation where an automatically retried POST might + // cause a gazillion identical messages to show up on a bulletin board well site. + + #if ! defined(NDEBUG) + static NSSet * sIdempotentHTTPMethods; + + if (sIdempotentHTTPMethods == nil) { + @synchronized ([self class]) { + if (sIdempotentHTTPMethods == nil) { + sIdempotentHTTPMethods = [[NSSet alloc] initWithObjects:@"GET", @"HEAD", @"PUT", @"DELETE", @"OPTIONS", @"TRACE", nil]; + } + } + } + assert([sIdempotentHTTPMethods containsObject:[request HTTPMethod]]); + #endif + + self = [super init]; + if (self != nil) { + @synchronized ([self class]) { + static NSUInteger sSequenceNumber; + self->_sequenceNumber = sSequenceNumber; + sSequenceNumber += 1; + } + self->_request = [request copy]; + assert(self->_retryState == kRetryingHTTPOperationStateNotStarted); + } + return self; +} + +- (void)dealloc +{ + [self->_request release]; + [self->_acceptableContentTypes release]; + [self->_responseFilePath release]; + [self->_response release]; + [self->_responseContent release]; + assert(self->_networkOperation == nil); + assert(self->_retryTimer == nil); + assert(self->_reachabilityOperation == nil); + [super dealloc]; +} + +#pragma mark * Properties + +@synthesize request = _request; + +- (RetryingHTTPOperationState)retryState +{ + return self->_retryState; +} + +- (void)setRetryState:(RetryingHTTPOperationState)newValue + // We don't really need this custom setter, but it's a great way to flush + // out redundant update problems. +{ + assert([self isActualRunLoopThread]); + assert(newValue != self->_retryState); + self->_retryState = newValue; + + [self performSelectorOnMainThread:@selector(syncRetryStateClient) withObject:nil waitUntilDone:NO]; +} + +@synthesize retryStateClient = retryStateClient; + +- (void)syncRetryStateClient + // Sets the retryStateClient property on the main thread. +{ + assert([NSThread isMainThread]); + self.retryStateClient = self.retryState; +} + +@synthesize hasHadRetryableFailure = _hasHadRetryableFailure; +@synthesize acceptableContentTypes = _acceptableContentTypes; +@synthesize responseFilePath = _responseFilePath; +@synthesize response = _response; +@synthesize networkOperation = _networkOperation; +@synthesize retryTimer = _retryTimer; +@synthesize retryCount = _retryCount; +@synthesize reachabilityOperation = _reachabilityOperation; +@synthesize notificationInstalled = _notificationInstalled; + +- (NSString *)responseMIMEType + // See comment in header. +{ + NSString * result; + NSHTTPURLResponse * response; + + result = nil; + response = self.response; + if (response != nil) { + result = [response MIMEType]; + } + return result; +} + +@synthesize responseContent = _responseContent; + +#pragma mark * Utilities + +- (void)setHasHadRetryableFailureOnMainThread + // Sets the hasHadRetryableFailure on the main thread. +{ + assert([NSThread isMainThread]); + assert( ! self.hasHadRetryableFailure ); + self.hasHadRetryableFailure = YES; +} + +- (BOOL)shouldRetryAfterError:(NSError *)error + // Returns YES if the supplied error is fatal, that is, it can't be + // meaningfully retried. +{ + BOOL shouldRetry; + + if ( [[error domain] isEqual:kQHTTPOperationErrorDomain] ) { + + // We can easily understand the consequence of coming directly from + // QHTTPOperation. + + if ( [error code] > 0 ) { + // The request made it to the server, which failed it. We consider that to be + // fatal. It might make sense to handle error 503 "Service Unavailable" as a + // special case here but, realistically, how common is that? + shouldRetry = NO; + } else { + switch ( [error code] ) { + default: + assert(NO); // what is this error? + // fall through + case kQHTTPOperationErrorResponseTooLarge: + case kQHTTPOperationErrorOnOutputStream: + case kQHTTPOperationErrorBadContentType: { + shouldRetry = NO; // all of these conditions are unlikely to fail + } break; + } + } + } else { + + // We treat all other errors are retryable. Most errors are likely to be from + // the network, and that's exactly what we want to retry. Clearly this is going to + // need some refinement based on real world experience. + + shouldRetry = YES; + } + return shouldRetry; +} + +// This isn't a crypto system, so we don't care about mod bias, so we just calculate +// the random time interval by taking the random number, mod'ing it by the number +// of milliseconds of the delay range, and then converting that number of milliseconds +// to an NSTimeInterval. + +- (NSTimeInterval)retryDelayWithinRangeAtIndex:(NSUInteger)rangeIndex + // Helper method for -shortRetryDelay and -randomRetryDelay. +{ + // First retry is after one second; next retry is after one minute; next retry + // is after one hour; next retry (and all subsequent retries) is after six hours. + static const NSUInteger kRetryDelays[] = { 1, 60, 60 * 60, 6 * 60 * 60 }; + + if (rangeIndex >= (sizeof(kRetryDelays) / sizeof(kRetryDelays[0]))) { + rangeIndex = (sizeof(kRetryDelays) / sizeof(kRetryDelays[0])) - 1; + } + return ((NSTimeInterval) (((NSUInteger) arc4random()) % (kRetryDelays[rangeIndex] * 1000))) / 1000.0; +} + +- (NSTimeInterval)shortRetryDelay + // Returns a random short delay (that is, within the next second). +{ + return [self retryDelayWithinRangeAtIndex:0]; +} + +- (NSTimeInterval)randomRetryDelay + // Returns a random delay that's based on the retryCount; the delay range grows + // rapidly with the number of retries, thereby ensuring that we don't continuously + // thrash the device doing unsuccessful retries. +{ + return [self retryDelayWithinRangeAtIndex:self.retryCount]; +} + +#pragma mark * Core state transitions + +- (void)operationDidStart + // Called by QRunLoopOperation when the operation starts. We just kick off the + // initial HTTP request. +{ + assert([self isActualRunLoopThread]); + assert(self.retryState == kRetryingHTTPOperationStateNotStarted); + + [super operationDidStart]; + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu start %@", (size_t) self->_sequenceNumber, [self.request URL]]; + + self.retryState = kRetryingHTTPOperationStateGetting; + [self startRequest]; +} + +- (void)startRequest + // Starts the HTTP request. This might be the first request or a retry. +{ + assert([self isActualRunLoopThread]); + assert( (self.retryState == kRetryingHTTPOperationStateGetting) || (self.retryState == kRetryingHTTPOperationStateRetrying) ); + assert(self.networkOperation == nil); + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu request start", (size_t) self->_sequenceNumber]; + + // Create the network operation. + + self.networkOperation = [[[QHTTPOperation alloc] initWithRequest:self.request] autorelease]; + assert(self.networkOperation != nil); + + // Copy our properties over to the network operation. + + [self.networkOperation setQueuePriority:[self queuePriority]]; + self.networkOperation.acceptableContentTypes = self.acceptableContentTypes; + self.networkOperation.runLoopThread = self.runLoopThread; + self.networkOperation.runLoopModes = self.runLoopModes; + + // If we're downloading to a file, set up an output stream that points to that file. + // + // Note that we pass NO to the append parameter; if we wanted to support resumeable + // downloads, we could do it here (but we'd have to mess around with etags and so on). + + if (self.responseFilePath != nil) { + self.networkOperation.responseOutputStream = [NSOutputStream outputStreamToFileAtPath:self.responseFilePath append:NO]; + assert(self.networkOperation.responseOutputStream != nil); + } + + [[NetworkManager sharedManager] addNetworkTransferOperation:self.networkOperation finishedTarget:self action:@selector(networkOperationDone:)]; +} + +- (void)networkOperationDone:(QHTTPOperation *)operation + // Called when the network operation finishes. We look at the error to decide how to proceed. +{ + assert([self isActualRunLoopThread]); + assert( (self.retryState == kRetryingHTTPOperationStateGetting) || (self.retryState == kRetryingHTTPOperationStateRetrying) ); + assert(operation == self.networkOperation); + self.networkOperation = nil; + + if (operation.error == nil) { + + // The request was successful; let's complete the operation. + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu request success", (size_t) self->_sequenceNumber]; + + self.response = operation.lastResponse; + self.responseContent = operation.responseBody; + + [self finishWithError:nil]; // this changes state to kRetryingHTTPOperationStateFinished + + } else { + + // Something went wrong. Deal with the error. + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu request error %@", (size_t) self->_sequenceNumber, operation.error]; + + if ( ! [self shouldRetryAfterError:operation.error] ) { + + // If the error is fatal, we just fail the overall operation. + + [self finishWithError:operation.error]; + } else { + + // If this is our first retry, tell our client that we are in retry mode. + + if (self.retryState == kRetryingHTTPOperationStateGetting) { + [self performSelectorOnMainThread:@selector(setHasHadRetryableFailureOnMainThread) withObject:nil waitUntilDone:NO]; + } + + // If our notification callback isn't installed, install it. + // + // This notification is broadcast if any download succeeds. If it fires, we + // trigger a very quick retry because, if one transfer succeeds, it's likely that + // other transfers will succeed as well. + + if ( ! self.notificationInstalled ) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(transferDidSucceed:) name:kRetryingHTTPOperationTransferDidSucceedNotification object:nil]; + self.notificationInstalled = YES; + } + + // If the reachability operation is not running (this can happen the first time we fail + // and if a subsequent reachability-based retry fails), start it up. Given that reachability + // only tells us about the state of our local machine, the operation could have failed for + // reasons that reachability knows nothing about. So before we use a reachability + // check to trigger a retry, we want to make sure that the host is first /unreachable/, + // and then wait for it to become reachability. So, let's start with that first part. + + if (self.reachabilityOperation == nil) { + [self startReachabilityReachable:NO]; + } + + // Start a time-based retry. + + self.retryState = kRetryingHTTPOperationStateWaitingToRetry; + [self startRetryAfterTimeInterval:[self randomRetryDelay]]; + } + } +} + +- (void)transferDidSucceed:(NSNotification *)note + // Called when kRetryingHTTPOperationTransferDidSucceedNotification is posted. + // We see if this notification is relevant to us and, if so, pass it on to code + // running on our run loop. +{ + // Can't look at state at this point, but it is safe to look at request because + // that's immutable. + + assert( [[note name] isEqual:kRetryingHTTPOperationTransferDidSucceedNotification] ); + assert( [[[note userInfo] objectForKey:kRetryingHTTPOperationTransferDidSucceedHostKey] isKindOfClass:[NSString class]] ); + + // If the successful transfer was to /our/ host, we pass the notification off to + // our run loop thread. + + if ( [[[note userInfo] objectForKey:kRetryingHTTPOperationTransferDidSucceedHostKey] isEqual:[[self.request URL] host]] ) { + + // This raises the question of what happens if the operation changes state (most critically, + // if it finishes) while waiting for this selector to be performed. It turns out that's OK. + // The perform will retain self while it's in flight, and if it is delivered in an inappropriate + // context (after, say, the operation has finished), it will be ignored based on the retryState. + + [self performSelector:@selector(transferDidSucceedOnRunLoopThread) onThread:self.actualRunLoopThread withObject:nil waitUntilDone:NO]; + } +} + +- (void)transferDidSucceedOnRunLoopThread + // Called on our run loop when a kRetryingHTTPOperationTransferDidSucceedNotification + // notification relevant to us is posted. We check whether a fast retry is in order. +{ + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu other transfer succeeeded", (size_t) self->_sequenceNumber]; + + // If some other transfer to the same host succeeded, radically reduce our retry delay. + + if (self.retryState == kRetryingHTTPOperationStateWaitingToRetry) { + assert(self.retryTimer != nil); + [self.retryTimer invalidate]; + self.retryTimer = nil; + + [self startRetryAfterTimeInterval:[self shortRetryDelay]]; + } +} + +- (void)startRetryAfterTimeInterval:(NSTimeInterval)delay + // Schedules a retry to occur after the specified delay. +{ + assert(self.retryState == kRetryingHTTPOperationStateWaitingToRetry); + assert(self.retryTimer == nil); + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu retry wait start %.3f", (size_t) self->_sequenceNumber, delay]; + + self.retryTimer = [NSTimer timerWithTimeInterval:delay target:self selector:@selector(retryTimerDone:) userInfo:nil repeats:NO]; + assert(self.retryTimer != nil); + for (NSString * mode in self.actualRunLoopModes) { + [[NSRunLoop currentRunLoop] addTimer:self.retryTimer forMode:mode]; + } +} + +- (void)retryTimerDone:(NSTimer *)timer + // Called when the retry timer expires. It just starts the actual retry. +{ + assert([self isActualRunLoopThread]); + assert(timer == self.retryTimer); + #pragma unused(timer) + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu retry wait done", (size_t) self->_sequenceNumber]; + + [self.retryTimer invalidate]; + self.retryTimer = nil; + + assert(self.retryState == kRetryingHTTPOperationStateWaitingToRetry); + self.retryState = kRetryingHTTPOperationStateRetrying; + self.retryCount += 1; + [self startRequest]; +} + +- (void)startReachabilityReachable:(BOOL)reachable + // Starts a reachability operation waiting for the host associated with this request + // to become unreachable or reachabel (depending on the "reachable" parameter). +{ + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu %sreachable start", (size_t) self->_sequenceNumber, reachable ? "" : "un" ]; + + assert(self.reachabilityOperation == nil); + self.reachabilityOperation = [[[QReachabilityOperation alloc] initWithHostName:[[self.request URL] host]] autorelease]; + assert(self.reachabilityOperation != nil); + + // In the reachable case the default mask and value is fine. In the unreachable case + // we have to customise them. + + if ( ! reachable ) { + self.reachabilityOperation.flagsTargetMask = kSCNetworkReachabilityFlagsReachable; + self.reachabilityOperation.flagsTargetValue = 0; + } + + [self.reachabilityOperation setQueuePriority:[self queuePriority]]; + self.reachabilityOperation.runLoopThread = self.runLoopThread; + self.reachabilityOperation.runLoopModes = self.runLoopModes; + + [[NetworkManager sharedManager] addNetworkManagementOperation:self.reachabilityOperation finishedTarget:self action:@selector(reachabilityOperationDone:)]; +} + +- (void)reachabilityOperationDone:(QReachabilityOperation *)operation + // Called when the reachability operation finishes. If we were looking for the + // host to become unreachable, we respond by scheduling a new operation waiting + // for the host to become reachable. OTOH, if we've found that the host has + // become reachable (and this must be a transition because we only schedule + // such an operation if the host is current unreachable), we force a fast retry. +{ + assert([self isActualRunLoopThread]); + assert(self.retryState >= kRetryingHTTPOperationStateWaitingToRetry); + assert(operation == self.reachabilityOperation); + self.reachabilityOperation = nil; + + assert(operation.error == nil); // ReachabilityOperation can never actually fail + + if ( ! (operation.flags & kSCNetworkReachabilityFlagsReachable) ) { + + // We've know that the host is not unreachable. Schedule a reachability operation to + // wait for it to become reachable. + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu unreachable done (0x%zx)", (size_t) self->_sequenceNumber, (size_t) operation.flags]; + + [self startReachabilityReachable:YES]; + } else { + + // Reachability has flipped from being unreachable to being reachable. We respond by + // radically shortening the retry delay (although not too short, we want to give the + // system time to settle after the reachability change). + + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu reachable done (0x%zx)", (size_t) self->_sequenceNumber, (size_t) operation.flags]; + + if (self.retryState == kRetryingHTTPOperationStateWaitingToRetry) { + assert(self.retryTimer != nil); + [self.retryTimer invalidate]; + self.retryTimer = nil; + + [self startRetryAfterTimeInterval:[self shortRetryDelay] + 3.0]; + } + } +} + +- (void)operationWillFinish + // Called by QRunLoopOperation when the operation finishes. We just clean up + // our various operations and callbacks. +{ + assert([self isActualRunLoopThread]); + + [super operationWillFinish]; + + if (self.networkOperation != nil) { + [[NetworkManager sharedManager] cancelOperation:self.networkOperation]; + self.networkOperation = nil; + } + if (self.retryTimer != nil) { + [self.retryTimer invalidate]; + self.retryTimer = nil; + } + if (self.reachabilityOperation != nil) { + [[NetworkManager sharedManager] cancelOperation:self.reachabilityOperation]; + self.reachabilityOperation = nil; + } + if (self.notificationInstalled) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:kRetryingHTTPOperationTransferDidSucceedNotification object:nil]; + self.notificationInstalled = NO; + } + self.retryState = kRetryingHTTPOperationStateFinished; + + if (self.error == nil) { + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu success", (size_t) self->_sequenceNumber]; + + // We were successful. Broadcast a notification to that effect so that other transfers who + // are delayed waiting to retry know that now is a good time. + + [[NSNotificationCenter defaultCenter] postNotificationName:kRetryingHTTPOperationTransferDidSucceedNotification + object:nil + userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[[self.request URL] host], kRetryingHTTPOperationTransferDidSucceedHostKey, nil] + ]; + } else { + [[QLog log] logOption:kLogOptionNetworkDetails withFormat:@"http %zu error %@", (size_t) self->_sequenceNumber, self.error]; + } +} + +@end diff --git a/MVCNetworking/Read Me About MVCNetworking.txt b/MVCNetworking/Read Me About MVCNetworking.txt new file mode 100644 index 0000000..524c056 --- /dev/null +++ b/MVCNetworking/Read Me About MVCNetworking.txt @@ -0,0 +1,287 @@ +Read Me About MVCNetworking +=========================== +1.0 + +MVCNetworking is a sample that shows how to create a network application using the Model-View-Controller design pattern. Specifically, it displays a photo gallery by getting the gallery's XML description, thumbnails and photos from a web server, and uses Core Data to cache this information locally. + +MVCNetworking requires iOS 3.1.3 or later. + +Packing List +------------ +The sample contains the following items: + +o Read Me About MVCNetworking.txt -- This document. + +o MVCNetworking.xcodeproj -- An Xcode project for the application. + +o MainWindow.xib -- The application's main NIB. + +o Info.plist -- The application's property list. + +o Images -- A directory containing all the images used by the sample. + +o TestGallery -- A photo gallery to test with. + +o main.m -- A standard main function. + +o AppDelegate.[hm] -- The application delegate. This class isn't very big, but it controls the overall structure of the application. For example, it's this class that remembers which gallery you're viewing. + +o Logging -- Good logging is vital to any network application. This directory contains a simple but effective logging package, including a Settings bundle to enable and disable various log and debug options. + +o Networking -- This directory contains the networking classes used by the sample. + +o Model -- This directory contains the model objects for the sample, along with a Core Data model for those objects. It also contains a number of non-networking NSOperation subclasses that are used by the model. + +o View Controllers -- This directory contains the classes that run the user interface. These include two view controllers, and the associated NIBs and view classes. + +Building the Sample +------------------- +The sample was built using Xcode 3.2.4 from the iOS 4.1 SDK on Mac OS X 10.6.4. You should be able to just open the project, choose your configuration from the Overview popup, and then choose Build from the Build menu. + +Using the Sample +---------------- +The easiest way to test the sample is in the simulator. To do this: + +1. On your Mac, copy the "TestGallery" directory to "/Library/WebServer/Documents/". + +2. In the Sharing panel of System Preferences, enable Web Sharing. + +3. Build the sample for the simulator and run it. + +4. In the simulator you will now see the Setup view. Tap one of the pre-configured gallery URLs from the list and then tap Save. + +5. You will now see the photo gallery, which displays the thumbnail, name and date for each photo. + +6. If you tap on a cell it will display the photo details, that is, a large view of the photo that's scrollable and zoomable. + +Once you've verified the basic functionality in the simulator, it's time to test on a device. You have two choices here: + +o If you are happy to rename your Mac, you can just change its name to "Worker" (in the Sharing panel of System Preferences). When built for the device, the application is configured to connect to "worker.local." by default. + +o If that's not an option, you should edit the definition of HOSTNAME in -[SetupViewController initWithGalleryURLString:] to the .local name of your Mac. + +You can then run the app and choose a gallery just like you did on the simulator. + +Settings Bundle +--------------- +The application includes a Settings bundle that lets you configure a world of logging and debugging facilities: + +o Logging > Enabled -- This is the master on/off switch for the logging. + +o Logging > Show View -- If you enable this option, the main view of the application profits a "Log" button. You can tap this button to see the log (displayed by the QLogViewer class), which also lets you clear, copy, print (to stderr), and email the log. + +o Logging > Logging Options -- These options let you enable and disable logging within specific subsystems. + +o Debug > Debug Options > Clear Setup -- You can use this to reset the application's preferences. This includes the current gallery, and the list of galleries shown in the Setup view. + +IMPORTANT: This preference only works on launch; on multitasking systems it is ignored when the application is resumed from the background. + +o Debug > Debug Options > Clear Cache -- You can use this to clear all information cached by the application (including the Core Data database that stores its view of the world, the thumbnails and the photos themselves). + +IMPORTANT: This preference only works on launch; on multitasking systems it is ignored when the application is resumed from the background. + +o Debug > Debug Options > Sync on Activate -- If you enable this option, the application will initiate a sync every time it's activated. This, combined with iOS 4's multitasking, lets you test the syncing behaviour in odd situations (like when the log view is up). + +o Debug > Debug Options > Operation Delay -- You can use this option to artificially delay the completion of certain async operations (most notably the network and XML parsing operations). This allows you to test things that are hard to test otherwise, such as cancellation. + +o Debug > Debug Options > Network Errors -- You can use this to simulate network errors, and thereby test how well the application handles them. + +High-Level Notes +---------------- +This sample is quite complex. Most sample code is designed to illustrate a single API or concept, which means it can be relatively small. In contrast, this sample is designed to show how to structure a real application to deal with the real challenges of networking. As such, it's hard to escape the complexity. However, the sample is clearly structured, with the various components well isolated from one another, so it shouldn't be too hard to grok. + +Even at its current size there are still numerous features and enhancements that were omitted to prevent it from getting any bigger. See "Sins of Omission" (below) for the details. + +For a tutorial introduction to the philosophy behind this sample, you should watch WWDC 2010 presentation, "Network Apps for iPhone OS", part 1 and 2 (session 207 and 208). + + + +This sample follows the Model-View-Controller design pattern. If you're not familiar with that pattern, you should read the extensive treatment in the "Cocoa Fundamentals Guide". + + + +You might also want to watch the WWDC 2010 presentation Session 116 "Model-View-Controller for iPhone OS", which is a great introduction to MVC on iOS. + + + +This sample makes extensive use of NSOperation. If you're not familiar with NSOperation, you should check out the following resources: + +o "Concurrency Programming Guide" + + + +o TN2109 "Simple and Reliable Threading with NSOperation" and its associated ListAdder sample code + + + + +This sample makes extensive use of Key-Value Observing (KVO). If you're not familiar with KVO, you should read the "Key-Value Observing Programming Guide". + + + +How it Works - The Model +------------------------ +The best place to start with understanding this sample is the model. The model is based around the concept of a photo gallery. Each photo gallery has a URL and a gallery cache. The URL is the location of an XML file that lists the photos in the gallery, along with various attributes of those photos. For example: + + + + + + +This XML element describes a single photo named "Kids In A Box", that was last modified on 30 Jul 2006 at 7:47:17 GMT and has the unique ID "12345" (this must be unique within the context of a specific gallery). The photo has two different image elements: + +o -- this is the thumbnail +o -- this is the full size photo + +And for each image there is a "srcURL" attribute that specifies the location of the image resource (relative to the location of the XML itself). + +Within the application these concepts are represented by three main classes: + +o PhotoGallery represents the gallery itself. This class has three main functions: + +- It remembers the gallery URL. + +- It tracks the gallery cache, creating it if necessary. This cache includes a Core Data database and a directory that contains any downloaded full size photos. + +- It manages the syncing process. When told to sync it starts a network operation (RetryingHTTPOperation) to get the XML and, once that completes, it starts a parser operation (GalleryParserOperation) to parse that XML. When that's done it looks at the results, which represent the new state of the gallery, and syncs that to the current state. + +IMPORTANT: All of this syncing is done at the model level. The view controllers just watch the model and adapt to any changes. + +o Photo represents a photo within a gallery. It has properties like photoID, displayName, date, and so on. It also has two properties that return images, thumbnailImage (the thumbnail) and photoImage (the full size image). + +Photo is a managed object that comes from the Core Data database associated with the gallery. + +Photo does not store the data for either the thumbnail or the full size photo. The thumbnail data is stored in a separate Thumbnail object (there's an optional one-to-one relationship between Photo and Thumbnail) and the full size photo is stored in a file (Photo just stores the relative path to that file). + +o Thumbnail holds the data for a thumbnail. Again, this is a managed object. It is separated from the Photo class because its properties are large (the thumbnail's PNG representation) and, in general, it's a good idea to separate large objects from small objects within a Core Data database. + +Finally, there's one other critical class related to the model, namely PhotoGalleryContext. This is an NSManagedObjectContext subclass that holds information about the photo gallery. This allows managed objects, specifically the Photo objects, to get at gallery state, such as the gallery URL. + +How It Works - The Networking +----------------------------- +Below the model there is a whole raft of networking classes. All networking is done via asynchronous NSOperation subclasses, each one tailored to its own specific role. Beyond that there's a network manager singleton (an instance of NetworkManager) that owns the NSOperationQueues which execute these operations. There are three operation queues, each with its own specific purpose: + +o queueForCPU -- This queue is used for CPU operations, like XML parsing and thumbnail resizes. Its width (that is, its maxConcurrentOperationCount) is left at the default value (NSOperationQueueDefaultMaxConcurrentOperationCount), which means you get one operation in progress on a current iOS device. This prevents the iOS device's single core being thrashed about trying to run multiple concurrent CPU intensive tasks. + +o queueForNetworkTransfers -- This queue is used for network transfer operations, that is, operations that are actively hitting the network. This has a limited width (currently 4) which prevents the application flooding a specific server with dozens of simultaneous network requests. The number of operations in this queue is used to determine the networkInUse property (see below). + +o queueForNetworkManagement -- This queue is used for network management operations, that is, networking operations that aren't actually hitting the network. For example, reachability operations (QReachabilityOperation) go on this queue, as do the operations that manage the retry process for network requests (RetryingHTTPOperation). This queue's width is unbounded. Each operation is more-or-less permanently blocked, so it's OK to allow them to all run concurrently. + +IMPORTANT: This last point is only acceptable because all of the operations on this queue are concurrent operations, that is, operations that don't require NSOperationQueue to dedicate a thread to running them. In fact, within this sample all operations (except those run on queueForCPU) are run loop based operations (subclasses of QRunLoopOperation). + +The network manager exports three methods (of the form -addXxxOperation:finishedTarget:action:), each of which runs an operation on one of the queues listed above. These methods schedule the operation and, when it finishes (assuming it wasn't cancelled), call the specified action method on the specified target. This makes it easy for high-level code to create simple state machines that start an operation and get called back when it's done. + +In order to minimise the load on the main thread (necessary for smooth scrolling within a large gallery on a slow device) the network manager creates a secondary thread (networkRunLoopThread) for all run loop operations. This requires a bit of trickery when managing the above-mentioned target/action callbacks. The network manager keeps track of the thread that added the operation and always calls the action method on that same thread. + +One final nice feature of the network manager is that it knows about all networking operations that are currently in flight. It uses this information to update its networkInUse property, which the application delegate observes (via KVO) in order to maintain the network activity indicator. + +How It Works - Controllers and Views +------------------------------------ +There are three main view controllers in the application: + +o PhotoGalleryViewController -- This table view controller subclass displays a list of photos, with their thumbnails, names and dates. The core of this view controller is remarkably simple; it just uses an NSFetchedResultsController to get, sort and maintain the list of photos and then populates a table view based on that. Beyond that, there are two additional wrinkles: + +- The view controller has a photoGallery properties that determines the gallery it will display. This property is read/write, and is modified by the application delegate as the user changes between galleries. Handling a change of galleries is a little tricky. The controller uses KVO to do this; it simply observes its own photoGallery property and responds to changes from there. + +- The view controller maintains a toolbar at the bottom that display sync status from the underlying photo gallery, and includes a Refresh button that the user can tap to force a sync (or stop the sync if one is already in progress). + +Finally, the PhotoGalleryViewController uses a custom table view cell, PhotoCell, to actually display the photo. This cell is passed a Photo object and uses KVO to automatically respond to changes in that object. + +o PhotoDetailViewController -- This displays a single photo in a view that the user can zoom and pan. The code is fairly straightforward. The biggest issue is that it has to respond to changes in the underlying Photo model object. For example, if the full size photo hasn't been downloaded yet, it shows a label saying "Loading". Also, the view controller has to handle the photo being deleted. This can happen if a sync is running in the background and that sync discovers that this photo is no longer part of the gallery. PhotoDetailViewController detects this and automatically pops itself off the navigation stack. + +PhotoDetailViewController uses a UIScrollView subclass (QImageScrollView) to display its image. This approach, cribbed from the PhotoScroller sample code (see below), is required to centre a small photo in the middle of the scroll view rather than placing it at the top left. It's simpler than other approaches (such as messing with the contentInset property) and it works well on all versions of iOS. + +o SetupViewController -- This is a very simple view controller that presents the user with a list of galleries and allows them to choose a gallery to display (or type in the URL of a custom gallery). It has a delegate property which it calls when the user taps Save or Cancel. The application delegate presents this view and acts as its delegate. When the user taps Save to change gallery, the application delegate responds by disconnecting the PhotoGalleryViewController from the current photo gallery, creating a new photo gallery for the chosen URL, and connecting the PhotoGalleryViewController to that new photo gallery. + +Reusable Parts +-------------- +The following classes were intended to be reused as is: + +o QLog and QLogView -- These classes represent a simple but effective logging package that you could integrate directly into your code. + +o QRunLoopOperation -- This is an abstract base class that makes it easy to implement run loop based concurrent NSOperations. + +o QHTTPOperation -- This is a concrete subclass of QRunLoopOperation that runs an HTTP request. + +o QReachabilityOperation -- This is a concrete subclass of QRunLoopOperation that runs a reachability test. + +Note: QRunLoopOperation and QHTTPOperation feature in other networking samples, including LinkedImageFetcher and PictureSharing. + + + + +IMPORTANT: Just because these classes can be reused whole, doesn't preclude you from customising them to meet your specific needs. + +Other clasess are not directly reusable, but might make a useful starting point for an equivalent class in your application. These include: + +o NetworkManager -- While the fine structure of this class is specific to this sample, it would be easy to adapt it for use in other contexts. + +o RetryingHTTPOperation -- This depends on NetworkManager, and thus can't be reused as is. But, again, it would be easy to adapt to another context. + +o RecursiveDeleteOperation -- This is an NSOperation subclass that will delete a bunch of file system objects asynchronously. It's very simple and you could definitely reuse it as is. It also makes a great template for other asynchronous file system operations. For example, it would be very straightforward to adapt this to copy a file system object. + +o MakeThumbnailOperation -- This operation shows how to do background image manipulation using Core Graphics. Again, it would be easy to adapt this to other contexts. + +Caveats +------- +The sample continues to support iOS 3.1.3, mainly to allow performance testing on the oldest and slowest devices (specifically the original iPhone). + +The sample does not worry too much about memory consumption. While the final code has no specific memory usage problems (for example, it runs just fine on limited memory devices, like the original iPhone), certain things could be done better: + +o The sample does not respond to memory warnings (beyond the responses built in to the system). There are at least two places where this might be appropriate: + + - the Photo objects should release their thumbnail images + + - the Core Data object graph could be pruned + +o The PhotoDetailViewController could use memory much more efficiently. This is discussed more below. + +Certain debugging preferences are only noticed at launch time, rather than when coming back from the background on multitasking systems. Supporting these at resume time is a little tricky, and wasn't a priority because they are debugging options after all. + +The application does not save and restore the navigation controller state. For example, if you're viewing a photo and then quit the application, on relaunch you'll be back at the gallery view. This isn't a big deal; there are plenty of other samples that show how to do this. + +Scrolling performance on the original iPhone is less than ideal. It's fine once everything is cached, but scrolling while downloading stutters a bit. This was originally a lot worse, but various optimisations have improved it considerable. Still, it could be better. In contrast, scrolling on even a slightly faster CPU, such as the iPod touch (second generation), is quite acceptable. + +The photos in the "TestGallery" are of very poor quality because they have been compressed within an inch of their life in order to reduce the overall size of the sample. + +The QLog module does not currently have any code to limit the size of the log, something that's important for a production system. + +A bug in the iOS SDK 4.1 causes problems for simulator builds; the sample works around this with a conditional build setting that adds "__IPHONE_OS_VERSION_MIN_REQUIRED=30103" to the Preprocessor Macros build setting (GCC_PREPROCESSOR_DEFINITIONS) for simulator builds. This will not be necessary for future iOS SDKs. + +Sins of Omission +---------------- +This section describes the enhancements that were omitted in order to keep the sample at a reasonable size: + +o rotation -- The sample does not support rotation. Supporting rotation would present a few challenges (mostly related to the PhotoDetailController), but overall it would be pretty easy. + +o iPad user interface -- The sample runs fine as an iPhone application on the iPad. A proper iPad user interface would be cool but it also would present some UI challenges (specifically the layout of the PhotoGalleryViewController) and was thus omitted. + +o periodic sync -- The application only syncs the gallery at launch time, when you switch galleries, and when you tap the sync button. A periodic sync would be easy, but it was extra code and the sample is big enough already. + +o resuming transfers -- The sample does not resume interrupted transfers, something that would be cool, especially when transferring large items, like the full size photo, over WWAN. This would be easy to implement within the framework provided by the RetryingHTTPOperation class, but it's a specific technique that would be better suited to a more focused sample. + +o task completion -- It would be cool to use the task completion API to complete a large download after going into the background. The sample doesn't do this because the code would be quite complex, and it would make it harder to support iOS 3. + +o authentication challenges -- The sample does not deal with HTTP authentication challenges. You might think that's not necessary because the gallery is always hosted on a public site, but that's not the case. Even if your application only accesses public resources, you still have to deal with HTTP authentication challenges because the user might be behind an authenticating proxy. The sample doesn't do this because the code would make an already complex sample even more complex. If you'd like to learn how to deal with HTTP authentication challenges in a coherent fashion, you should look at the AdvancedURLConnections sample code. + + + +o photo viewing -- The sample's photo viewing code (PhotoDetailViewController) gets the job done, but it is very naive. This is, after all, a networking sample, not a graphics sample. If you're looking for a good photo viewer, I suggest you check out WWDC 2010 Session 104 "Designing Apps with Scroll Views" and the associated PhotoScroller sample. + + + + +Credits and Version History +--------------------------- +If you find any problems with this sample, please file a bug against it. + + + +1.0 (Oct 2010) was the first shipping version. + +Share and Enjoy + +Apple Developer Technical Support +Core OS/Hardware + +1 Oct 2010 diff --git a/MVCNetworking/TestGallery/broken-attributes.xml b/MVCNetworking/TestGallery/broken-attributes.xml new file mode 100644 index 0000000..2954ec6 --- /dev/null +++ b/MVCNetworking/TestGallery/broken-attributes.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/broken-empty.xml b/MVCNetworking/TestGallery/broken-empty.xml new file mode 100644 index 0000000..e69de29 diff --git a/MVCNetworking/TestGallery/broken-html.html b/MVCNetworking/TestGallery/broken-html.html new file mode 100644 index 0000000..256d00d --- /dev/null +++ b/MVCNetworking/TestGallery/broken-html.html @@ -0,0 +1,11 @@ + + + + + HTML, Not XML! + + +

This document contains HTML, not XML.

+ + diff --git a/MVCNetworking/TestGallery/broken-html.xml b/MVCNetworking/TestGallery/broken-html.xml new file mode 100644 index 0000000..731e74a --- /dev/null +++ b/MVCNetworking/TestGallery/broken-html.xml @@ -0,0 +1,11 @@ + + + + + HTML, Not XML! + + +

This claims to be XML, but is in fact XML.

+ + diff --git a/MVCNetworking/TestGallery/broken-images.xml b/MVCNetworking/TestGallery/broken-images.xml new file mode 100644 index 0000000..f526590 --- /dev/null +++ b/MVCNetworking/TestGallery/broken-images.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/broken-text.txt b/MVCNetworking/TestGallery/broken-text.txt new file mode 100644 index 0000000..1c83214 --- /dev/null +++ b/MVCNetworking/TestGallery/broken-text.txt @@ -0,0 +1 @@ +This is just not XML. In fact, it's plain text! diff --git a/MVCNetworking/TestGallery/broken-text.xml b/MVCNetworking/TestGallery/broken-text.xml new file mode 100644 index 0000000..1c83214 --- /dev/null +++ b/MVCNetworking/TestGallery/broken-text.xml @@ -0,0 +1 @@ +This is just not XML. In fact, it's plain text! diff --git a/MVCNetworking/TestGallery/broken-xml.xml b/MVCNetworking/TestGallery/broken-xml.xml new file mode 100644 index 0000000..a6f87c7 --- /dev/null +++ b/MVCNetworking/TestGallery/broken-xml.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/changes-A.xml b/MVCNetworking/TestGallery/changes-A.xml new file mode 100644 index 0000000..1fed069 --- /dev/null +++ b/MVCNetworking/TestGallery/changes-A.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/changes-B.xml b/MVCNetworking/TestGallery/changes-B.xml new file mode 100644 index 0000000..2209b6f --- /dev/null +++ b/MVCNetworking/TestGallery/changes-B.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/changes.xml b/MVCNetworking/TestGallery/changes.xml new file mode 100644 index 0000000..1fed069 --- /dev/null +++ b/MVCNetworking/TestGallery/changes.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/images/IMG_0119.jpg b/MVCNetworking/TestGallery/images/IMG_0119.jpg new file mode 100644 index 0000000..b7beda6 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0119.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0122.jpg b/MVCNetworking/TestGallery/images/IMG_0122.jpg new file mode 100644 index 0000000..a317435 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0122.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0125.gif b/MVCNetworking/TestGallery/images/IMG_0125.gif new file mode 100644 index 0000000..a3b4204 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0125.gif differ diff --git a/MVCNetworking/TestGallery/images/IMG_0125.jpg b/MVCNetworking/TestGallery/images/IMG_0125.jpg new file mode 100644 index 0000000..113c2c2 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0125.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0125.png b/MVCNetworking/TestGallery/images/IMG_0125.png new file mode 100644 index 0000000..2ab7da1 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0125.png differ diff --git a/MVCNetworking/TestGallery/images/IMG_0125b.jpg b/MVCNetworking/TestGallery/images/IMG_0125b.jpg new file mode 100644 index 0000000..d6114cd --- /dev/null +++ b/MVCNetworking/TestGallery/images/IMG_0125b.jpg @@ -0,0 +1 @@ +This is not a JPEG! \ No newline at end of file diff --git a/MVCNetworking/TestGallery/images/IMG_0125s.jpg b/MVCNetworking/TestGallery/images/IMG_0125s.jpg new file mode 100644 index 0000000..257a886 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0125s.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0125u.jpg b/MVCNetworking/TestGallery/images/IMG_0125u.jpg new file mode 100644 index 0000000..3ff6df0 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0125u.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0127.jpg b/MVCNetworking/TestGallery/images/IMG_0127.jpg new file mode 100644 index 0000000..46da414 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0127.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0130.jpg b/MVCNetworking/TestGallery/images/IMG_0130.jpg new file mode 100644 index 0000000..cfbf01f Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0130.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0133.jpg b/MVCNetworking/TestGallery/images/IMG_0133.jpg new file mode 100644 index 0000000..9ae0261 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0133.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0139.jpg b/MVCNetworking/TestGallery/images/IMG_0139.jpg new file mode 100644 index 0000000..48f1eb7 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0139.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0149.jpg b/MVCNetworking/TestGallery/images/IMG_0149.jpg new file mode 100644 index 0000000..df95153 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0149.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0152.jpg b/MVCNetworking/TestGallery/images/IMG_0152.jpg new file mode 100644 index 0000000..c9204a6 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0152.jpg differ diff --git a/MVCNetworking/TestGallery/images/IMG_0156.jpg b/MVCNetworking/TestGallery/images/IMG_0156.jpg new file mode 100644 index 0000000..53c1715 Binary files /dev/null and b/MVCNetworking/TestGallery/images/IMG_0156.jpg differ diff --git a/MVCNetworking/TestGallery/index-big.xml b/MVCNetworking/TestGallery/index-big.xml new file mode 100644 index 0000000..ddad14c --- /dev/null +++ b/MVCNetworking/TestGallery/index-big.xml @@ -0,0 +1,69 @@ + + + + +

The Glasgow Botanic Gardens moved to its current site in Kelvinside in 1842. This gallery shows just a few of its many attractions.

+
+ + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + +
diff --git a/MVCNetworking/TestGallery/index-empty.xml b/MVCNetworking/TestGallery/index-empty.xml new file mode 100644 index 0000000..87399af --- /dev/null +++ b/MVCNetworking/TestGallery/index-empty.xml @@ -0,0 +1,2 @@ + + diff --git a/MVCNetworking/TestGallery/index-giant.xml b/MVCNetworking/TestGallery/index-giant.xml new file mode 100644 index 0000000..3eb0cc3 --- /dev/null +++ b/MVCNetworking/TestGallery/index-giant.xml @@ -0,0 +1,689 @@ + + + + +

The Glasgow Botanic Gardens moved to its current site in Kelvinside in 1842. This gallery shows just a few of its many attractions.

+
+ + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+ + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + +
diff --git a/MVCNetworking/TestGallery/index.xml b/MVCNetworking/TestGallery/index.xml new file mode 100644 index 0000000..e4d4548 --- /dev/null +++ b/MVCNetworking/TestGallery/index.xml @@ -0,0 +1,38 @@ + + + + +

The Glasgow Botanic Gardens moved to its current site in Kelvinside in 1842. This gallery shows just a few of its many attractions.

+
+ + +

Originally built as a conservatory for a private home, Kibble Palace was moved to the Botanic Gardens in 1872. After 130 years of sterling service, it was beautifully restored over a three year period between 2003 and 2006.

+
+ + + +
+ + + + + + + + + + + + + + + + + +

This is one of five police boxes still standing in Glasgow. One little known piece of police box trivia is that Glasgow police boxes were originally painted red.

+
+ + + +
+
diff --git a/MVCNetworking/TestGallery/index2.xml b/MVCNetworking/TestGallery/index2.xml new file mode 100644 index 0000000..dd46259 --- /dev/null +++ b/MVCNetworking/TestGallery/index2.xml @@ -0,0 +1,35 @@ + + + + + +

This is the view from Queen Margaret Bridge, looking towards the weir and the ruins of Garrioch Mill.

+
+ + + +
+ + +

BBC Scotland has since moved to a new building on the South Side, but someone forgot to take down the signage.

+
+ + + +
+ + + + + + + + + + + + + + + +
diff --git a/MVCNetworking/TestGallery/oddballs.xml b/MVCNetworking/TestGallery/oddballs.xml new file mode 100644 index 0000000..83287bc --- /dev/null +++ b/MVCNetworking/TestGallery/oddballs.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0119.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0119.jpg new file mode 100644 index 0000000..b5a25ca Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0119.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0122.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0122.jpg new file mode 100644 index 0000000..0692652 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0122.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0125.gif b/MVCNetworking/TestGallery/thumbnails/IMG_0125.gif new file mode 100644 index 0000000..691aa75 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0125.gif differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0125.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0125.jpg new file mode 100644 index 0000000..009f9d9 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0125.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0125.png b/MVCNetworking/TestGallery/thumbnails/IMG_0125.png new file mode 100644 index 0000000..94da1a0 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0125.png differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0125b.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0125b.jpg new file mode 100644 index 0000000..86d660e --- /dev/null +++ b/MVCNetworking/TestGallery/thumbnails/IMG_0125b.jpg @@ -0,0 +1 @@ +This is also not a JPEG. \ No newline at end of file diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0125s.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0125s.jpg new file mode 100644 index 0000000..009f9d9 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0125s.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0125u.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0125u.jpg new file mode 100644 index 0000000..381f1eb Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0125u.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0127.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0127.jpg new file mode 100644 index 0000000..f5a80ad Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0127.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0130.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0130.jpg new file mode 100644 index 0000000..1653add Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0130.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0133.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0133.jpg new file mode 100644 index 0000000..b7906e9 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0133.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0139.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0139.jpg new file mode 100644 index 0000000..98acca5 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0139.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0149.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0149.jpg new file mode 100644 index 0000000..0bed483 Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0149.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0152.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0152.jpg new file mode 100644 index 0000000..222de3e Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0152.jpg differ diff --git a/MVCNetworking/TestGallery/thumbnails/IMG_0156.jpg b/MVCNetworking/TestGallery/thumbnails/IMG_0156.jpg new file mode 100644 index 0000000..91e34ee Binary files /dev/null and b/MVCNetworking/TestGallery/thumbnails/IMG_0156.jpg differ diff --git a/MVCNetworking/View Controllers/PhotoCell.h b/MVCNetworking/View Controllers/PhotoCell.h new file mode 100644 index 0000000..6c05239 --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoCell.h @@ -0,0 +1,72 @@ +/* + File: PhotoCell.h + + Contains: A table view cell to display a photo. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@class Photo; + +@interface PhotoCell : UITableViewCell +{ + Photo * _photo; + NSDateFormatter * _dateFormatter; +} + +- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier; + +@property (nonatomic, retain, readwrite) Photo * photo; +@property (nonatomic, retain, readwrite) NSDateFormatter * dateFormatter; + +// IMPORTANT: dateFormatter is /retain/, not /copy/, because we want to share the same +// date formatter object between all our cells. + +@end diff --git a/MVCNetworking/View Controllers/PhotoCell.m b/MVCNetworking/View Controllers/PhotoCell.m new file mode 100644 index 0000000..992aaff --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoCell.m @@ -0,0 +1,167 @@ +/* + File: PhotoCell.m + + Contains: A table view cell to display a photo. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "PhotoCell.h" + +#import "Photo.h" + +@implementation PhotoCell + +- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; + if (self != nil) { + + // Observe a bunch of our own properties so that the UI adjusts to any changes. + + [self addObserver:self forKeyPath:@"photo.displayName" options:0 context:&self->_photo]; + [self addObserver:self forKeyPath:@"photo.date" options:0 context:&self->_dateFormatter]; + [self addObserver:self forKeyPath:@"photo.thumbnailImage" options:0 context:&self->_photo]; + [self addObserver:self forKeyPath:@"dateFormatter" options:0 context:&self->_dateFormatter]; + } + return self; +} + +- (void)dealloc +{ + // Remove our observers. + + [self removeObserver:self forKeyPath:@"photo.displayName"]; + [self removeObserver:self forKeyPath:@"photo.date"]; + [self removeObserver:self forKeyPath:@"photo.thumbnailImage"]; + [self removeObserver:self forKeyPath:@"dateFormatter"]; + + // Clean up our memory. + + [self->_photo release]; + [self->_dateFormatter release]; + + [super dealloc]; +} + +// Because we self-observe dateFormatter in order to update after a locale change, +// we only want to fire KVO notifications if the date formatter actually changes (which +// is infrequent in day-to-day operations. So we override the setter and handle the +// KVO notifications ourself. + +@synthesize dateFormatter = _dateFormatter; + ++ (BOOL)automaticallyNotifiesObserversOfDateFormatter +{ + return NO; +} + +- (void)setDateFormatter:(NSDateFormatter *)newValue +{ + if (newValue != self->_dateFormatter) { + [self willChangeValueForKey:@"dateFormatter"]; + [self->_dateFormatter release]; + self->_dateFormatter = [newValue retain]; + [self didChangeValueForKey:@"dateFormatter"]; + } +} + +@synthesize photo = _photo; + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context + // Called when various properties of the photo change; updates the cell accordingly. +{ + if (context == &self->_photo) { + assert(object == self); + + if ([keyPath isEqual:@"photo.displayName"]) { + if (self.photo == nil) { + self.textLabel.text = nil; + } else { + self.textLabel.text = self.photo.displayName; + } + + // iOS 3 has a bug where, if you set the text of a cell's label to something longer + // than the existing text, it doesn't expand the label to accommodate the longer + // text. The end result is that the text gets needlessly truncated. We fix + // this by triggering a re-layout whenever we change the text. + + [self setNeedsLayout]; + } else if ([keyPath isEqual:@"photo.thumbnailImage"]) { + if (self.photo == nil) { + self.imageView.image = nil; + } else { + self.imageView.image = self.photo.thumbnailImage; + } + } else { + assert(NO); + } + } else if (context == &self->_dateFormatter) { + NSString * dateText; + + assert(object == self); + assert([keyPath isEqual:@"photo.date"] || [keyPath isEqual:@"dateFormatter"]); + + dateText = nil; + if (self.photo != nil) { + if (self.dateFormatter == nil) { + // If there's no date formatter, just use the date's description. This is + // somewhat lame, and you wouldn't want to run this code path in general. + dateText = [self.photo.date description]; + } else { + dateText = [self.dateFormatter stringFromDate:self.photo.date]; + } + } + self.detailTextLabel.text = dateText; + [self setNeedsLayout]; // see comment above + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +@end diff --git a/MVCNetworking/View Controllers/PhotoDetailViewController.h b/MVCNetworking/View Controllers/PhotoDetailViewController.h new file mode 100644 index 0000000..7010e95 --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoDetailViewController.h @@ -0,0 +1,77 @@ +/* + File: PhotoDetailViewController.h + + Contains: Shows a photo in a scroll view. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@class Photo; +@class PhotoGallery; +@class QImageScrollView; + +@interface PhotoDetailViewController : UIViewController +{ + QImageScrollView * _scrollView; + UILabel * _loadingLabel; + + Photo * _photo; + PhotoGallery * _photoGallery; +} + +@property (nonatomic, retain, readwrite) IBOutlet QImageScrollView * scrollView; +@property (nonatomic, retain, readwrite) IBOutlet UILabel * loadingLabel; + +- (id)initWithPhoto:(Photo *)photo photoGallery:(PhotoGallery *)photoGallery; + +@property (nonatomic, retain, readonly) Photo * photo; +@property (nonatomic, retain, readonly) PhotoGallery * photoGallery; + +@end diff --git a/MVCNetworking/View Controllers/PhotoDetailViewController.m b/MVCNetworking/View Controllers/PhotoDetailViewController.m new file mode 100644 index 0000000..f2eb0a2 --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoDetailViewController.m @@ -0,0 +1,256 @@ +/* + File: PhotoDetailViewController.h + + Contains: Shows a photo in a scroll view. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "PhotoDetailViewController.h" + +#import "QImageScrollView.h" + +#import "PhotoGallery.h" + +#import "Photo.h" + +#import "Logging.h" + +@implementation PhotoDetailViewController + +- (id)initWithPhoto:(Photo *)photo photoGallery:(PhotoGallery *)photoGallery +{ + assert(photo != nil); + assert(photoGallery != nil); + self = [super initWithNibName:@"PhotoDetailViewController" bundle:nil]; + if (self != nil) { + self->_photo = [photo retain]; + self->_photoGallery = [photoGallery retain]; + + [self.photo addObserver:self forKeyPath:@"displayName" options:NSKeyValueObservingOptionInitial context:&self->_photo]; + } + return self; +} + +- (void)dealloc +{ + [self.photo removeObserver:self forKeyPath:@"displayName"]; + + [self->_scrollView release]; + [self->_loadingLabel release]; + + [self->_photo release]; + [self->_photoGallery release]; + + [super dealloc]; +} + +#pragma mark * Keeping everything up-to-date + +@synthesize photo = _photo; +@synthesize photoGallery = _photoGallery; + +- (void)photoWasDeleted + // If the underlying photos was deleted while we're displaying it (typically + // because a sync ran), we just pop ourselves off the view controller stack. +{ + if ([self.navigationController.viewControllers containsObject:self]) { + [self.navigationController popToViewController:self animated:NO]; + [self.navigationController popViewControllerAnimated:YES]; + } +} + +- (void)contextChanged:(NSNotification *)note + // This notification is issued by the NSManagedObjectContext that controls the photo + // object we're displaying. If that phono object is deleted (as can happen if a sync + // occurs while we're on screen), we call -photoWasDeleted (which pops us off the + // navigation controller stack). +{ + NSSet * deletedObjects; + + deletedObjects = [[note userInfo] objectForKey:NSDeletedObjectsKey]; + if (deletedObjects != nil) { + assert([deletedObjects isKindOfClass:[NSSet class]]); + + if ([deletedObjects containsObject:self.photo]) { + [self photoWasDeleted]; + } + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == &self->_photo) { + + // Called when various properties of our photo change. We update our UI + // accordingly. + + assert(object == self.photo); + if ([keyPath isEqual:@"displayName"]) { + + // Sync the photo name into the navigation item title. + + self.title = self.photo.displayName; + } else if (self.isViewLoaded) { + if ([keyPath isEqual:@"photoImage"]) { + UIImage * image; + + // If the photo changed, update our UI. All of the hard work is done + // by the QImageScrollView class. + + image = self.photo.photoImage; + self.scrollView.image = image; + self.scrollView.hidden = (image == nil); + self.loadingLabel.hidden = (image != nil); + } else if ([keyPath isEqual:@"photoGetting"]) { + + // Update our loading label as the photo hits the network. + + if (self.photo.photoGetting) { + self.loadingLabel.text = @"Loading…"; + } else { + // This assert isn't valid because if we get bad photo data we don't + // detect that at the time of the get, we detect that when we try to + // create a UIImage from the file on disk. In that case photoImage + // will be nil but photoGetError will also be nil. This doesn't materially + // affect our code; we still want to display "Load failed". + // + // assert( (self.photo.photoImage != nil) || (self.photo.photoGetError != nil) ); + self.loadingLabel.text = @"Load failed"; + } + } else { + assert(NO); + } + } + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark * View controller stuff + +@synthesize scrollView = _scrollView; +@synthesize loadingLabel = _loadingLabel; + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + assert([self.scrollView isKindOfClass:[QImageScrollView class]]); + assert(self.loadingLabel != nil); + + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + + self.scrollView = nil; + self.loadingLabel = nil; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // Tell the model object that we want it to keep the photo image up-to-date. + + [self.photo assertPhotoNeeded]; + + // Configure our view. We hide the scroll view, which leaves the loading label + // visible. + + self.scrollView.hidden = YES; + + [self.navigationController setToolbarHidden:YES animated:animated]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + // Add the observers here so that the initial call sees the correct size + // of the scroll view (that is, after the toolbar has hidden). + + [self.photo addObserver:self forKeyPath:@"photoImage" options:NSKeyValueObservingOptionInitial context:&self->_photo]; + [self.photo addObserver:self forKeyPath:@"photoGetting" options:NSKeyValueObservingOptionInitial context:&self->_photo]; + + // Unfortunately -[NSManagedObject isDeleted] doesn't really do what I want + // here, so I just watch the context directly. + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.photo.managedObjectContext]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + + // Undo the stuff we did in -viewDidAppear. + + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextObjectsDidChangeNotification object:self.photo.managedObjectContext]; + + [self.photo removeObserver:self forKeyPath:@"photoImage"]; + [self.photo removeObserver:self forKeyPath:@"photoGetting"]; + + // We show the navigation controller's toolbar here, so that you + // can see the animation. + + [self.navigationController setToolbarHidden:NO animated:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + + // Tell the model object is no longer needs to keep the photo image up-to-date. + + [self.photo deassertPhotoNeeded]; +} + +@end diff --git a/MVCNetworking/View Controllers/PhotoDetailViewController.xib b/MVCNetworking/View Controllers/PhotoDetailViewController.xib new file mode 100644 index 0000000..0bbd33a --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoDetailViewController.xib @@ -0,0 +1,400 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + + + 298 + {{20, 194}, {280, 30}} + + NO + YES + 7 + NO + IBCocoaTouchFramework + Loading… + + Helvetica-Bold + 24 + 16 + + + 1 + MC4yOTgwMzkyMTU3IDAuMzM3MjU0OTAyIDAuNDIzNTI5NDExOAA + + + 3 + MQA + + + 3 + MSAwLjUAA + + {0, 1} + 1 + 10 + 1 + + + + 274 + {320, 416} + + + YES + YES + IBCocoaTouchFramework + + + {320, 416} + + + + 1 + MCAwIDAAA + + + + NO + + IBCocoaTouchFramework + + + + + + + view + + + + 19 + + + + scrollView + + + + 20 + + + + loadingLabel + + + + 21 + + + + + + 0 + + + + + + 1 + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + + Scroll View + + + 17 + + + Label - Label + + + + + PhotoDetailViewController + UIResponder + {{546, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + QImageScrollView + + + + + + 21 + + + + + PhotoDetailViewController + UIViewController + + UILabel + QImageScrollView + + + + loadingLabel + UILabel + + + scrollView + QImageScrollView + + + + IBProjectSource + View Controllers/PhotoDetailViewController.h + + + + QImageScrollView + UIScrollView + + IBProjectSource + View Controllers/QImageScrollView.h + + + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + ../MVCNetworking.xcodeproj + 3 + 123 + + diff --git a/MVCNetworking/View Controllers/PhotoGalleryViewController.h b/MVCNetworking/View Controllers/PhotoGalleryViewController.h new file mode 100644 index 0000000..122c73e --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoGalleryViewController.h @@ -0,0 +1,82 @@ +/* + File: PhotoGalleryViewController.h + + Contains: Shows a list of all the photos in a gallery. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +#import + +@class PhotoGallery; + +@interface PhotoGalleryViewController : UITableViewController +{ + UIBarButtonItem * _stopBarButtonItem; + UIBarButtonItem * _refreshBarButtonItem; + UIBarButtonItem * _fixedBarButtonItem; + UIBarButtonItem * _flexBarButtonItem; + UIBarButtonItem * _statusBarButtonItem; + + PhotoGallery * _photoGallery; + NSFetchedResultsController * _fetcher; + NSDateFormatter * _dateFormatter; +} + +- (id)initWithPhotoGallery:(PhotoGallery *)photoGallery; + // Creates a view controller to show the photos in the specified gallery. + // + // IMPORTANT: photoGallery may be nil, in which case it simply displays + // a placeholder UI. + +@property (nonatomic, retain, readwrite) PhotoGallery * photoGallery; + // The client can change the gallery being shown by setting this property. + +@end \ No newline at end of file diff --git a/MVCNetworking/View Controllers/PhotoGalleryViewController.m b/MVCNetworking/View Controllers/PhotoGalleryViewController.m new file mode 100644 index 0000000..e5eef84 --- /dev/null +++ b/MVCNetworking/View Controllers/PhotoGalleryViewController.m @@ -0,0 +1,588 @@ +/* + File: PhotoGalleryViewController.h + + Contains: Shows a list of all the photos in a gallery. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "PhotoGalleryViewController.h" + +#import "PhotoCell.h" + +#import "PhotoDetailViewController.h" + +#import "PhotoGallery.h" +#import "Photo.h" + +#import "QLogViewer.h" +#import "QLog.h" + +@interface PhotoGalleryViewController () + +// private properties + +@property (nonatomic, retain, readwrite) UIBarButtonItem * stopBarButtonItem; +@property (nonatomic, retain, readwrite) UIBarButtonItem * refreshBarButtonItem; +@property (nonatomic, retain, readwrite) UIBarButtonItem * fixedBarButtonItem; +@property (nonatomic, retain, readwrite) UIBarButtonItem * flexBarButtonItem; +@property (nonatomic, retain, readwrite) UIBarButtonItem * statusBarButtonItem; + +@property (nonatomic, retain, readwrite) NSFetchedResultsController * fetcher; + +@property (nonatomic, copy, readwrite) NSDateFormatter * dateFormatter; + +// forward declarations + +- (void)setupStatusLabel; +- (void)setupSyncBarButtonItem; + +@end + +@implementation PhotoGalleryViewController + +- (id)initWithPhotoGallery:(PhotoGallery *)photoGallery + // See comment in header. +{ + // photoGallery may be nil + self = [super initWithNibName:nil bundle:nil]; + if (self != nil) { + UILabel * statusLabel; + + self->_photoGallery = [photoGallery retain]; + + self.title = @"Photos"; + + // Set up a raft of bar button items. + + self->_stopBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(stopAction:)]; + self->_refreshBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshAction:)]; + self->_fixedBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; + self->_fixedBarButtonItem.width = 25.0f; + self->_flexBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + + statusLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 250.0f, 32.0f)] autorelease]; + assert(statusLabel != nil); + + statusLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; + statusLabel.textColor = [UIColor whiteColor]; + statusLabel.textAlignment = UITextAlignmentCenter; + statusLabel.backgroundColor = [UIColor clearColor]; + statusLabel.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]]; + + self->_statusBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:statusLabel]; + + // Add an observer to the QLog's showViewer property to update whether we show our + // "Log" button in the left bar button position of the navigation bar. + + [[QLog log] addObserver:self forKeyPath:@"showViewer" options:NSKeyValueObservingOptionInitial context:NULL]; + + // Add an observer for our own photoGallery property, so that we can adjust our UI + // when it changes. Note that we set NSKeyValueObservingOptionPrior so that we + // get called before /and/ after the change, allowing us to shut down our UI before + // the change and bring it up again afterwards. + + [self addObserver:self forKeyPath:@"photoGallery" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionPrior context:&self->_photoGallery]; + } + return self; +} + +- (void)dealloc +{ + // There's no intrinsic reason why this class shouldn't support -dealloc, + // but in this application the following code never runs, and so is untested, + // and hence has a leading assert. + + assert(NO); + + // Remove all our KVO observers. + + if (self->_photoGallery != nil) { + [self->_photoGallery removeObserver:self forKeyPath:@"syncing"]; + [self->_photoGallery removeObserver:self forKeyPath:@"syncStatus"]; + [self->_photoGallery removeObserver:self forKeyPath:@"standardDateFormatter"]; + } + [self removeObserver:self forKeyPath:@"photoGallery"]; + [[QLog log] removeObserver:self forKeyPath:@"showViewer"]; + + // Release our ivars. + + [self->_stopBarButtonItem release]; + [self->_refreshBarButtonItem release]; + [self->_fixedBarButtonItem release]; + [self->_flexBarButtonItem release]; + [self->_statusBarButtonItem release]; + + [self->_photoGallery release]; + if (self->_fetcher != nil) { + self->_fetcher.delegate = nil; + [self->_fetcher release]; + } + [self->_dateFormatter release]; + + [super dealloc]; +} + +- (void)startFetcher + // Starts the fetch results controller that provides the data for our table. +{ + BOOL success; + NSError * error; + NSFetchRequest * fetchRequest; + NSSortDescriptor * sortDescriptor; + + assert(self.photoGallery != nil); + assert(self.photoGallery.managedObjectContext != nil); + + sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES] autorelease]; + assert(sortDescriptor != nil); + + fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; + assert(fetchRequest != nil); + + [fetchRequest setEntity:self.photoGallery.photoEntity]; + [fetchRequest setFetchBatchSize:20]; + [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; + + assert(self.fetcher == nil); + self.fetcher = [[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.photoGallery.managedObjectContext sectionNameKeyPath:nil cacheName:nil] autorelease]; + assert(self.fetcher != nil); + + self.fetcher.delegate = self; + + success = [self.fetcher performFetch:&error]; + if ( ! success ) { + [[QLog log] logWithFormat:@"viewer fetch failed %@", error]; + } +} + +- (void)reloadTable + // Forces a reload of the table if the view is loaded. +{ + if (self.isViewLoaded) { + [self.tableView reloadData]; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == &self->_stopBarButtonItem) { + + // Set up the Refresh/Stop button in the toolbar based on the syncing state of + // the photo gallery. + + assert([keyPath isEqual:@"syncing"]); + assert(object == self.photoGallery); + [self setupSyncBarButtonItem]; + + } else if (context == &self->_statusBarButtonItem) { + + // Set the status label in the toolbar based on the syncing status from the + // the photo gallery. + + assert([keyPath isEqual:@"syncStatus"]); + assert(object == self.photoGallery); + [self setupStatusLabel]; + + } else if (context == &self->_photoGallery) { + assert([keyPath isEqual:@"photoGallery"]); + assert(object == self); + + if ( (change != nil) && [[change objectForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue] ) { + if (self.photoGallery != nil) { + + // The gallery is about to go away. Remove our observers and shut down the fetched results + // controller that provides the data for our table. + + [self.photoGallery removeObserver:self forKeyPath:@"syncing"]; + [self.photoGallery removeObserver:self forKeyPath:@"syncStatus"]; + [self.photoGallery removeObserver:self forKeyPath:@"standardDateFormatter"]; + + self.fetcher.delegate = nil; + self.fetcher = nil; + } + } else { + if (self.photoGallery == nil) { + + // There's no new gallery. We call -setupStatusLabel and -setupSyncBarButtonItem directly, + // and these methods configure us to display the placeholder UI. + + [self setupStatusLabel]; + [self setupSyncBarButtonItem]; + } else { + // Install a bunch of KVO observers to track various chunks of state and update our UI + // accordingly. Note that these have NSKeyValueObservingOptionInitial set, so our + // -observeValueForKeyPath:xxx method is called immediately to set up the initial + // state. + + [self.photoGallery addObserver:self forKeyPath:@"syncing" options:NSKeyValueObservingOptionInitial context:&self->_stopBarButtonItem]; + [self.photoGallery addObserver:self forKeyPath:@"syncStatus" options:NSKeyValueObservingOptionInitial context:&self->_statusBarButtonItem]; + [self.photoGallery addObserver:self forKeyPath:@"standardDateFormatter" options:NSKeyValueObservingOptionInitial context:&self->_dateFormatter]; + + // Set up the fetched results controller that provides the data for our table. + + [self startFetcher]; + } + + // And reload the table to account for any possible change. + + [self reloadTable]; + } + } else if (context == &self->_dateFormatter) { + + // Called when the standardDateFormatter property of the gallery changes (which typically + // happens when the user changes their locale or time zone settings). We apply this change + // to ourselves and then reload the table so that all our cells pick up the new formatter. + + assert([keyPath isEqual:@"standardDateFormatter"]); + assert(object == self.photoGallery); + self.dateFormatter = self.photoGallery.standardDateFormatter; + [self reloadTable]; + + } else if ( (context == NULL) && [keyPath isEqual:@"showViewer"] ) { + + // Called when the showViewer property of QLog changes (typically because the user has + // toggled the setting in the Settings application). We set the left bar button position + // of our navigation item accordingly. + + assert(object == [QLog log]); + if ( [QLog log].showViewer ) { + self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Log" style:UIBarButtonItemStyleBordered target:self action:@selector(showLogAction:)] autorelease]; + assert(self.navigationItem.leftBarButtonItem != nil); + } else { + self.navigationItem.leftBarButtonItem = nil; + } + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark * View controller stuff + +@synthesize stopBarButtonItem = _stopBarButtonItem; +@synthesize refreshBarButtonItem = _refreshBarButtonItem; +@synthesize fixedBarButtonItem = _fixedBarButtonItem; +@synthesize flexBarButtonItem = _flexBarButtonItem; +@synthesize statusBarButtonItem = _statusBarButtonItem; + +@synthesize photoGallery = _photoGallery; +@synthesize fetcher = _fetcher; +@synthesize dateFormatter = _dateFormatter; + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // Configure the table view itself. + + self.tableView.rowHeight = kThumbnailSize + 3.0f; + + // If our view got unloaded, and hence our fetcher got nixed, we reestablish it + // on the reload. + + if ( (self.photoGallery != nil) && (self.fetcher == nil) ) { + [self startFetcher]; + } +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + + // There no point having a fetched results controller around if the view is unloaded. + + self.fetcher.delegate = nil; + self.fetcher = nil; +} + +#pragma mark * Table view callbacks + +- (BOOL)hasNoPhotos + // Returns YES if there are no photos to display. The table view callbacks use this extensively + // to determine whether to show a placeholder ("No photos") or real content. +{ + BOOL result; + NSArray * sections; + NSUInteger sectionCount; + + result = YES; + if (self.fetcher != nil) { + sections = [self.fetcher sections]; + sectionCount = [sections count]; + if (sectionCount > 0) { + if ( (sectionCount > 1) || ([[sections objectAtIndex:0] numberOfObjects] != 0) ) { + result = NO; + } + } + } + + return result; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv +{ + NSInteger result; + + assert(tv == self.tableView); + #pragma unused(tv) + if ( [self hasNoPhotos] ) { + result = 1; // if there's no photos, there's 1 section with 1 row that is the placeholder UI + } else { + result = [[self.fetcher sections] count]; // if there's photos, base this off the fetcher results controller + } + return result; +} + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + NSInteger result; + + assert(tv == self.tableView); + + if ( [self hasNoPhotos] ) { + result = 1; // if there's no photos, there's 1 section with 1 row that is the placeholder UI + } else { + NSArray * sections; // if there's photos, base this off the fetcher results controller + + sections = [self.fetcher sections]; + assert(sections != nil); + assert(section >= 0); + assert( (NSUInteger) section < [sections count] ); + result = [[sections objectAtIndex:section] numberOfObjects]; + } + return result; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + UITableViewCell * result; + + assert(tv == self.tableView); + assert(indexPath != NULL); + + if ( [self hasNoPhotos] ) { + + // There are no photos to display; return a cell that simple says "No photos". + + result = [self.tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (result == nil) { + result = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"] autorelease]; + assert(result != nil); + + result.textLabel.text = @"No photos"; + result.textLabel.textColor = [UIColor darkGrayColor]; + result.textLabel.textAlignment = UITextAlignmentCenter; + } + result.selectionStyle = UITableViewCellSelectionStyleNone; + } else { + PhotoCell * cell; + Photo * photo; + + // Return a cell that displays the appropriate photo. Note that we just tell + // the cell what photo to display, and it takes care of displaying the right + // stuff (via the miracle of KVO). + + photo = [self.fetcher objectAtIndexPath:indexPath]; + assert([photo isKindOfClass:[Photo class]]); + + cell = (PhotoCell *) [self.tableView dequeueReusableCellWithIdentifier:@"PhotoCell"]; + if (cell != nil) { + assert([cell isKindOfClass:[PhotoCell class]]); + } else { + cell = [[[PhotoCell alloc] initWithReuseIdentifier:@"PhotoCell"] autorelease]; + assert(cell != nil); + + assert(cell.selectionStyle == UITableViewCellSelectionStyleBlue); + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + cell.photo = photo; + cell.dateFormatter = self.dateFormatter; + + result = cell; + } + + return result; +} + +- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + + assert(tv == self.tableView); + assert(indexPath != NULL); + // assert(indexPath.section == 0); + // assert(indexPath.row < ?); + + if ( [self hasNoPhotos] ) { + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + } else { + Photo * photo; + PhotoDetailViewController * vc; + + // Push a photo detail view controller to display the bigger version + // of the photo. + + photo = [self.fetcher objectAtIndexPath:indexPath]; + assert([photo isKindOfClass:[Photo class]]); + + vc = [[[PhotoDetailViewController alloc] initWithPhoto:photo photoGallery:self.photoGallery] autorelease]; + assert(vc != nil); + + [self.navigationController pushViewController:vc animated:YES]; + } +} + +#pragma mark * Fetched results controller callbacks + +- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath + // A delegate callback called by the fetched results controller when its content + // changes. If anything interesting happens (that is, an insert, delete or move), we + // respond by reloading the entire table. This is rather a heavy-handed approach, but + // I found it difficult to correctly handle the updates. Also, the insert, delete and + // move aren't on the critical performance path (which is scrolling through the list + // loading thumbnails), so I can afford to keep it simple. +{ + assert(controller == self.fetcher); + #pragma unused(controller) + #pragma unused(anObject) + #pragma unused(indexPath) + #pragma unused(newIndexPath) + + switch (type) { + case NSFetchedResultsChangeInsert: { + [self reloadTable]; + } break; + case NSFetchedResultsChangeDelete: { + [self reloadTable]; + } break; + case NSFetchedResultsChangeMove: { + [self reloadTable]; + } break; + case NSFetchedResultsChangeUpdate: { + // do nothing + } break; + default: { + assert(NO); + } break; + } +} + +#pragma mark * UI wrangling + +- (void)setupStatusLabel + // Set the status label in the toolbar based on the syncing status from the + // the photo gallery. +{ + UILabel * statusLabel; + + assert(self.statusBarButtonItem != nil); + + statusLabel = (UILabel *) self.statusBarButtonItem.customView; + assert([statusLabel isKindOfClass:[UILabel class]]); + + if (self.photoGallery == nil) { + statusLabel.text = @"Tap Setup to configure"; + } else { + statusLabel.text = self.photoGallery.syncStatus; + } +} + +- (void)setupSyncBarButtonItem + // Set up the Refresh/Stop button in the toolbar based on the syncing state of + // the photo gallery. +{ + assert(self.fixedBarButtonItem != nil); + assert(self.statusBarButtonItem != nil); + assert(self.flexBarButtonItem != nil); + assert(self.stopBarButtonItem != nil); + + if ( (self.photoGallery != nil) && self.photoGallery.isSyncing ) { + self.toolbarItems = [NSArray arrayWithObjects:self.fixedBarButtonItem, self.statusBarButtonItem, self.flexBarButtonItem, self.stopBarButtonItem, nil]; + } else { + self.refreshBarButtonItem.enabled = (self.photoGallery != nil); + self.toolbarItems = [NSArray arrayWithObjects:self.fixedBarButtonItem, self.statusBarButtonItem, self.flexBarButtonItem, self.refreshBarButtonItem, nil]; + } +} + +#pragma mark * Actions + +- (void)showLogAction:(id)sender + // Called when the user taps the Log button. It just presents the log + // view controller. +{ + #pragma unused(sender) + QLogViewer * vc; + + vc = [[[QLogViewer alloc] init] autorelease]; + assert(vc != nil); + + [vc presentModallyOn:self animated:YES]; +} + +- (IBAction)stopAction:(id)sender + // Called when the user taps the Stop button. It just passes the command + // on to the photo gallery. +{ + #pragma unused(sender) + [self.photoGallery stopSync]; +} + +- (IBAction)refreshAction:(id)sender + // Called when the user taps the Refresh button. It just passes the command + // on to the photo gallery. +{ + #pragma unused(sender) + [self.photoGallery startSync]; +} + +@end diff --git a/MVCNetworking/View Controllers/QImageScrollView.h b/MVCNetworking/View Controllers/QImageScrollView.h new file mode 100644 index 0000000..760e480 --- /dev/null +++ b/MVCNetworking/View Controllers/QImageScrollView.h @@ -0,0 +1,81 @@ +/* + File: QImageScrollView.m + + Contains: A simplified image view scroller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +/* + QImageScrollView is a simplified image scroller based to a large degree on the code + from the PhotoScroller sample. + + + + It's simplified because a) it does not support rotation, b) it does not support tiling + (and uses a hackish workaround on old school hardware, where non-tiled performance is + way too slow), and c) it ignores the Retina display. It's possible to fix all of these, + but such UI complexity is the scope of this /networking/ sample code. If you want to see + how to do this stuff properly, you should check out the PhotoScroller sample code and + WWDC 2010 Session 104 "Designing Apps with Scroll Views". + + +*/ + +@interface QImageScrollView : UIScrollView +{ + UIImage * _image; + UIImageView * _imageView; + BOOL _limitImageSize; +} + +@property (nonatomic, retain, readwrite) UIImage * image; + +@end diff --git a/MVCNetworking/View Controllers/QImageScrollView.m b/MVCNetworking/View Controllers/QImageScrollView.m new file mode 100644 index 0000000..39197f1 --- /dev/null +++ b/MVCNetworking/View Controllers/QImageScrollView.m @@ -0,0 +1,294 @@ +/* + File: QImageScrollView.m + + Contains: A simplified image view scroller. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "QImageScrollView.h" + +#import "Logging.h" + +#include + +@interface QImageScrollView () + +@property (nonatomic, retain, readwrite) UIImageView * imageView; + +@end + +@implementation QImageScrollView + +static BOOL LimitImageSize(void) + // Returns YES if the hardware we're running on is not capable of handling + // large images. For more information about this, see the comments where + // _limitImageSize is used, later in this file. +{ + BOOL result; + int err; + char value[32]; + size_t valueLen; + + result = NO; + + // Note that sysctlbyname will fail if value is too small. That's fine by + // us. The model numbers we're specifically looking will all fit. Anything + // with a longer name should be more capable, and hence not need a limited size. + + valueLen = sizeof(value); + err = sysctlbyname("hw.machine", value, &valueLen, NULL, 0); + if (err == 0) { + result = + (strcmp(value, "iPhone1,1") == 0) // iPhone + || (strcmp(value, "iPhone1,2") == 0) // iPhone 3G + || (strcmp(value, "iPod1,1" ) == 0) // iPod touch + || (strcmp(value, "iPod2,1" ) == 0) // iPod touch (second generation) + || (strcmp(value, "iPod2,2" ) == 0) // iPod touch (second generation) + ; + } + return result; +} + +- (void)initCommon + // Common initialisation called by both -initWithFrame: and -initWithCoder:. +{ + // If the delegate isn't already wired up courtesy of the NIB, wire it up + // ourselves. + + if (self.delegate == nil) { + self.delegate = self; + } + + // Determine if we need to limit the image size. For more information about this, + // see the comments where _limitImageSize is used, later in this file. + + self->_limitImageSize = LimitImageSize(); + + [[QLog log] logWithFormat:@"image scroll limit size %s", self->_limitImageSize ? "limited" : "unlimited"]; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self != nil) { + [self initCommon]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self != nil) { + [self initCommon]; + } + return self; +} + +- (void)dealloc +{ + [self->_image release]; + [self->_imageView release]; + [super dealloc]; +} + +#pragma mark * Overrides + +- (void)layoutSubviews + // We override -layoutSubviews so that, if the image is smaller than the scroll view, + // it ends up centred within the scroll view (rather than stuck at the top left). +{ + CGRect imageViewFrame; + CGSize boundsSize; + + [super layoutSubviews]; + + if (self.imageView != nil) { + boundsSize = self.bounds.size; + + // get the frame + + imageViewFrame = self.imageView.frame; + + // if it's smaller than the scroll view, centre it horizontally + + if (imageViewFrame.size.width < boundsSize.width) { + imageViewFrame.origin.x = (boundsSize.width - imageViewFrame.size.width) / 2.0f; + } else { + imageViewFrame.origin.x = 0.0f; + } + + // if it's smaller than the scroll view, centre it vertically + + if (imageViewFrame.size.height < boundsSize.height) { + imageViewFrame.origin.y = (boundsSize.height - imageViewFrame.size.height) / 2.0f; + } else { + imageViewFrame.origin.y = 0.0f; + } + + // set it back + + self.imageView.frame = imageViewFrame; + } +} + +#pragma mark * Scroll view delegate callbacks + +- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView +{ + assert(scrollView == self); + #pragma unused(scrollView) + return self.imageView; +} + +#pragma mark * Properties + +@synthesize image = _image; +@synthesize imageView = _imageView; + +- (void)setImage:(UIImage *)newValue +{ + if (newValue != self->_image) { + + // If we had a previous image view, clean it up. + + if (self.imageView != nil) { + [self.imageView removeFromSuperview]; + self.imageView = nil; + } + + // Reset our zooming back to the default before doing further calculations. + + self.zoomScale = 1.0; + self.minimumZoomScale = 1.0; + assert(self.maximumZoomScale == 1.0f); + + // Complete the setter. + + [self->_image release]; + self->_image = [newValue retain]; + + // If there is a new image, make an image view for it. + + if (newValue != nil) { + CGSize boundsSize; + CGSize imageSize; + CGFloat widthScale; + CGFloat heightScale; + + // If we're on old school hardware and the image is bigger than 1000 pixels in either + // dimension, resize it. This has a number of benefits: + // + // o it limits the amount of memory we consume + // o it gives us acceptable drag-to-scroll performance + // o it avoids a bug in iOS 3.x that causes images of certain widths to render as garbage + // + // Note that resizing the image down locks up the UI for a second or two. This isn't + // so bad because there's a "Loading…" on screen and the lock up isn't too + // long. In a real application, I'd probably do this via an NSOperation. + // + // Actually, in a real application I'd probably use some sort of tiling mechanism to + // solve this problem properly. However, this is just sample code remember, and + // networking sample code at that. So this is as good as it's going to get here. + + if (self->_limitImageSize) { + CGRect smallerImageFrame; + + smallerImageFrame = CGRectZero; + smallerImageFrame.size = newValue.size; + + if ( (smallerImageFrame.size.width > 1000.0f) || (smallerImageFrame.size.height > 1000.0f) ) { + if (smallerImageFrame.size.height > smallerImageFrame.size.width) { + // tall image + smallerImageFrame.size.width = smallerImageFrame.size.width / smallerImageFrame.size.height * 1000.0f; + smallerImageFrame.size.height = 1000.0f; + } else { + // wide image + smallerImageFrame.size.height = smallerImageFrame.size.height / smallerImageFrame.size.width * 1000.0f; + smallerImageFrame.size.width = 1000.0f; + } + + UIGraphicsBeginImageContext(smallerImageFrame.size); + [newValue drawInRect:smallerImageFrame]; + newValue = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + } + } + + boundsSize = self.bounds.size; + imageSize = [newValue size]; + + // Set up the image view. + + self.imageView = [[[UIImageView alloc] initWithImage:newValue] autorelease]; + [self addSubview:self.imageView]; + + // Calculate the width and height zoom scales, and then use the + // lesser one at minimum zoom scale. + + widthScale = boundsSize.width / imageSize.width; + heightScale = boundsSize.height / imageSize.height; + + self.contentSize = imageSize; + if (widthScale < heightScale) { + self.minimumZoomScale = widthScale; + } else { + self.minimumZoomScale = heightScale; + } + assert(self.maximumZoomScale == 1.0f); + + // And set the current zoom scale to be the minimum (that is, we can see + // the entire image). + + self.zoomScale = self.minimumZoomScale; + } + } +} + +@end diff --git a/MVCNetworking/View Controllers/SetupViewController.h b/MVCNetworking/View Controllers/SetupViewController.h new file mode 100644 index 0000000..f72a24b --- /dev/null +++ b/MVCNetworking/View Controllers/SetupViewController.h @@ -0,0 +1,91 @@ +/* + File: SetupViewController.h + + Contains: Lets the user configure the gallery to view. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +@protocol SetupViewControllerDelegate; + +@interface SetupViewController : UITableViewController +{ + id _delegate; + NSMutableArray * _choices; + BOOL _choicesDirty; + NSUInteger _choiceIndex; + NSString * _otherChoice; + UITextField * _activeTextField; +} + ++ (void)resetChoices; + // Resets the list of choices back to their default values. Called on application + // startup if the user enables the appropriate setting. + +- (id)initWithGalleryURLString:(NSString *)galleryURLString; + // galleryURLString may be nil, implying that no gallery is currently selected. + +@property (nonatomic, assign, readwrite) id delegate; + +- (void)presentModallyOn:(UIViewController *)parent animated:(BOOL)animated; + +@end + +@protocol SetupViewControllerDelegate + +@required + +- (void)setupViewController:(SetupViewController *)controller didChooseString:(NSString *)string; + // string may be empty, to indicate no gallery + +- (void)setupViewControllerDidCancel:(SetupViewController *)controller; + +@end + \ No newline at end of file diff --git a/MVCNetworking/View Controllers/SetupViewController.m b/MVCNetworking/View Controllers/SetupViewController.m new file mode 100644 index 0000000..f79f709 --- /dev/null +++ b/MVCNetworking/View Controllers/SetupViewController.m @@ -0,0 +1,628 @@ +/* + File: SetupViewController.h + + Contains: Lets the user configure the gallery to view. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import "SetupViewController.h" + +#import "NetworkManager.h" + +@interface SetupViewController () + +// private properties + +@property (nonatomic, assign, readonly ) BOOL canSave; +@property (nonatomic, retain, readonly ) NSMutableArray * choices; +@property (nonatomic, assign, readwrite) BOOL choicesDirty; +@property (nonatomic, assign, readwrite) NSUInteger choiceIndex; +@property (nonatomic, copy, readwrite) NSString * otherChoice; +@property (nonatomic, retain, readwrite) UITextField * activeTextField; + +// forward declarations + +- (NSString *)smartURLStringForString:(NSString *)str; +- (IBAction)saveAction:(id)sender; + +@end + +@implementation SetupViewController + ++ (void)resetChoices + // See comment in header. +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"setupChoices"]; +} + +- (id)initWithGalleryURLString:(NSString *)galleryURLString +{ + // galleryURLString may be nil + + self = [super initWithStyle:UITableViewStylePlain]; + if (self != nil) { + NSUInteger choiceIndex; + NSUInteger choiceCount; + + // Get the current list of choices, or start with the defaults. + + self->_choices = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"setupChoices"] mutableCopy]; + if (self->_choices == nil) { + #if TARGET_IPHONE_SIMULATOR + #define HOSTNAME "localhost" + #else + #define HOSTNAME "worker.local." + #endif + self->_choices = [[NSMutableArray alloc] initWithObjects: + @"https://" HOSTNAME "/TestGallery/index.xml", + @"https://" HOSTNAME "/TestGallery/index2.xml", + @"https://" HOSTNAME "/TestGallery/index-empty.xml", + @"https://" HOSTNAME "/TestGallery/index-big.xml", + @"https://" HOSTNAME "/TestGallery/index-giant.xml", + @"https://" HOSTNAME "/TestGallery/oddballs.xml", + @"https://" HOSTNAME "/TestGallery/changes.xml", + @"https://" HOSTNAME "/TestGallery/broken-empty.xml", + @"https://" HOSTNAME "/TestGallery/broken-html.html", + @"https://" HOSTNAME "/TestGallery/broken-html.xml", + @"https://" HOSTNAME "/TestGallery/broken-text.txt", + @"https://" HOSTNAME "/TestGallery/broken-text.xml", + @"https://" HOSTNAME "/TestGallery/broken-xml.xml", + @"https://" HOSTNAME "/TestGallery/broken-attributes.xml", + @"https://" HOSTNAME "/TestGallery/broken-images.xml", + nil + ]; + } + assert(self->_choices != nil); + + // Eliminate anything that doesn't look like a URL. + + choiceCount = [self->_choices count]; + for (choiceIndex = 0; choiceIndex < choiceCount; choiceIndex++) { + NSString * tmp; + + tmp = [self->_choices objectAtIndex:choiceIndex]; + if ( ! [tmp isKindOfClass:[NSString class]] ) { + tmp = nil; + } else { + tmp = [self smartURLStringForString:tmp]; + } + if ( (tmp == nil) || ([tmp length] == 0) ) { + [self->_choices removeObjectAtIndex:choiceIndex]; + choiceIndex -= 1; + choiceCount -= 1; + } else { + [self->_choices replaceObjectAtIndex:choiceIndex withObject:tmp]; + } + } + + // Get the current choice. If there is no current choice, we select the "other" + // row. If there is a current choice, set up choiceIndex to point to it. + // If the current choice isn't in the the choices list, add an item in that + // list to make it so (and set choicesDirty so that we save back the new + // list of the user taps Save). + + if (galleryURLString == nil) { + self->_choiceIndex = [self->_choices count]; + } else { + self->_choiceIndex = [self->_choices indexOfObject:galleryURLString]; + if (self->_choiceIndex == NSNotFound) { + self->_choiceIndex = [self->_choices count]; + [self->_choices addObject:[[galleryURLString copy] autorelease]]; + self->_choicesDirty = YES; + } + } + + // Add an observer to update the enabled state on the Save button. + + [self addObserver:self forKeyPath:@"canSave" options:NSKeyValueObservingOptionInitial context:&self->_choiceIndex]; + } + return self; +} + +- (void)dealloc +{ + [self removeObserver:self forKeyPath:@"canSave"]; + [self->_choices release]; + [self->_otherChoice release]; + [self->_activeTextField release]; + [super dealloc]; +} + +@synthesize delegate = _delegate; + +@synthesize choices = _choices; +@synthesize choicesDirty = _choicesDirty; +@synthesize choiceIndex = _choiceIndex; +@synthesize otherChoice = _otherChoice; +@synthesize activeTextField = _activeTextField; + +- (NSString *)smartURLStringForString:(NSString *)str + // Returns a URL string for the specified string, handling all sorts of edge cases. + // This can returns one of three different types of result: + // + // o If str is empty (or nil), it returns the empty string (@""). + // o If str is an invalid URL, it returns nil. + // o If string is a valid URL, it returns a non-nil, non-empty string. +{ + NSString * result; + NSRange schemeMarkerRange; + NSString * scheme; + + result = nil; + + // Treat nil as empty and then trim any whitespace. + + if (str == nil) { + str = @""; + } + str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if ( (str == nil) || ([str length] == 0) ) { + result = @""; + } else { + NSURL * resultURL; + + schemeMarkerRange = [str rangeOfString:@"://"]; + + resultURL = nil; + if (schemeMarkerRange.location == NSNotFound) { + // If the string does not contain "://", add the "https://" prefix. + resultURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@", str]]; + } else { + // Check the scheme to see if it's one we support. + scheme = [str substringWithRange:NSMakeRange(0, schemeMarkerRange.location)]; + assert(scheme != nil); + + if ( ([scheme compare:@"http" options:NSCaseInsensitiveSearch] == NSOrderedSame) + || ([scheme compare:@"https" options:NSCaseInsensitiveSearch] == NSOrderedSame) ) { + resultURL = [NSURL URLWithString:str]; + } else { + // It looks like this is some unsupported URL scheme. + } + } + + // If we managed to create a URL, get the result string from that. + + if (resultURL != nil) { + if ( [resultURL host] != nil ) { + result = [resultURL absoluteString]; + } + } + } + + assert( (result == nil) || ([result length] == 0) || ([NSURL URLWithString:result] != nil) ); + + return result; +} + +- (NSString *)effectiveChoice + // Returns the current choice displayed in the UI, which is either one of the selected + // choices or the string from the "other" row. This has the same post condition as + // -smartURLStringForString:. +{ + NSString * result; + + if (self.choiceIndex < [self.choices count]) { + result = [self.choices objectAtIndex:self.choiceIndex]; + assert( [NSURL URLWithString:result] != nil ); + } else { + result = [self smartURLStringForString:self.otherChoice]; + } + assert( (result == nil) || ([result length] == 0) || ([NSURL URLWithString:result] != nil) ); + return result; +} + ++ (NSSet *)keyPathsForValuesAffectingCanSave +{ + return [NSSet setWithObjects:@"otherChoice", @"choiceIndex", nil]; +} + +- (BOOL)canSave + // Returns YES if the current choice displayed in the UI is valid enough to be saved. +{ + BOOL result; + + result = (self.choiceIndex != [self.choices count]); + if ( ! result ) { + result = ([self effectiveChoice] != nil); + } + return result; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == &self->_choiceIndex) { + + // Called as our canSave property changes. We respond by enabling or disabling + // the Save bar button item. + + assert([keyPath isEqual:@"canSave"]); + assert(object == self); + self.navigationItem.rightBarButtonItem.enabled = self.canSave; + } else if (NO) { // Disabled because the super class does nothing useful with it. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark * View controller stuff + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + assert(self.activeTextField == nil); // We shouldn't disappear with an active text field. +} + +#pragma mark * Table view callbacks + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section +{ + #pragma unused(tv) + #pragma unused(section) + assert(tv == self.tableView); + assert(section == 0); + + return [self.choices count] + 1; // +1 to account for "other" row +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + BOOL otherCell; + NSString * cellID; + UITableViewCell * cell; + UITextField * textField; + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < ([self.choices count] + 1)); + + // Use one cell identifier for the "other" row, and another for all the normal rows. + + otherCell = (indexPath.row == [self.choices count]); + if (otherCell) { + cellID = @"otherCell"; + } else { + cellID = @"cell"; + } + + // Create the cell itself. Doing this for the "other" row is a little complex (-: + + cell = [self.tableView dequeueReusableCellWithIdentifier:cellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease]; + assert(cell != nil); + + if (otherCell) { + CGRect frame; + + frame = CGRectZero; + frame.size = cell.contentView.frame.size; + frame.origin.x += 10.0f; + frame.size.width -= 20.0f; + frame.origin.y = 6.0f; + frame.size.height -= 12.0f; + textField = [[[UITextField alloc] initWithFrame:frame] autorelease]; + assert(textField != nil); + + textField.tag = 666; + textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + textField.autoresizingMask = UIViewAutoresizingFlexibleWidth; + textField.placeholder = @"other"; + textField.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]]; + textField.autocapitalizationType = UITextAutocapitalizationTypeNone; + textField.autocorrectionType = UITextAutocorrectionTypeNo; + textField.keyboardType = UIKeyboardTypeURL; + textField.clearButtonMode = UITextFieldViewModeWhileEditing; + textField.delegate = self; + + [cell.contentView addSubview:textField]; + } else { + cell.textLabel.lineBreakMode = UILineBreakModeMiddleTruncation; + cell.textLabel.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]]; + } + } + + // Set up the cell. + + if (indexPath.row < [self.choices count]) { + + // A standard cell. Just set the text label to the corresponding element + // of the choices array. + + cell.textLabel.text = [self.choices objectAtIndex:indexPath.row]; + } else { + + // The "other" cell. Find the text field embedded in the cell and set its + // text to the current other choice. + + textField = (UITextField *) [cell.contentView viewWithTag:666]; + assert([textField isKindOfClass:[UITextField class]]); + + textField.text = self.otherChoice; + } + cell.accessoryType = indexPath.row == self.choiceIndex ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; + + return cell; +} + +- (void)chooseRow:(NSUInteger)row + // Choose the specified row. This updates both the UI (that is, the checkmark + // accessory view) and our choiceIndex property. +{ + UITableViewCell * cell; + + if (row != self.choiceIndex) { + + // If we're leaving the "other" row, take the keyboard focus away from it. + + if ( (row < [self.choices count]) && (self.activeTextField != nil) ) { + [self.activeTextField resignFirstResponder]; + } + + // Uncheck the currently checked cell, change the choice, and then recheck the newly checked cell. + + cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:self.choiceIndex inSection:0]]; + if (cell != nil) { + cell.accessoryType = UITableViewCellAccessoryNone; + } + self.choiceIndex = row; + cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:self.choiceIndex inSection:0]]; + if (cell != nil) { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + } +} + +- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + #pragma unused(tv) + #pragma unused(indexPath) + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < ([self.choices count] + 1)); + + [self chooseRow:indexPath.row]; + + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tv editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath + // While there's no way to put the table view in edit mode, we still support + // "swipe to delete" for everything except the "other" row. +{ + #pragma unused(tv) + #pragma unused(indexPath) + + assert(tv == self.tableView); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < ([self.choices count] + 1)); + + return (indexPath.row < [self.choices count]) ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleNone; +} + +- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath + // Implement the mechanics of "swipe to delete". +{ + #pragma unused(tv) + #pragma unused(editingStyle) + #pragma unused(indexPath) + + assert(tv == self.tableView); + assert(editingStyle == UITableViewCellEditingStyleDelete); + assert(indexPath != NULL); + assert(indexPath.section == 0); + assert(indexPath.row < [self.choices count]); + + // If the user is deleting the currently chosen row, choose another one. There + // are three cases: + // + // o If this is the last remaining normal choice, choose the "other" row. + // o If this is the last normal choice, choose the row before this. + // o Otherwise, choose the row after this row. + + if (indexPath.row == self.choiceIndex) { + assert([self.choices count] != 0); // because the user has swiped to delete, and that's only possible for normal choices + if ( [self.choices count] == 1 ) { + [self chooseRow:1]; // We're about to delete the last remaining normal choice; switch to the "other" choice. + } else if (indexPath.row == ([self.choices count] - 1)) { + [self chooseRow:indexPath.row - 1]; // We're about to delete the last normal choice; switch to the previous choice. + } else { + [self chooseRow:indexPath.row + 1]; // We're about to delete some common-or-garden normal chocie; switch to the next choice. + } + } + + [self.choices removeObjectAtIndex:indexPath.row]; + [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; + + // If the choice index is after the row we just deleted, step it back by one. + + assert(indexPath.row != self.choiceIndex); // because we moved away from it in the previous code + if (indexPath.row < self.choiceIndex) { + self.choiceIndex -= 1; + } + + self.choicesDirty = YES; +} + +#pragma mark * Text field callbacks + +- (void)textFieldDidBeginEditing:(UITextField *)textField + // There are there things to do here: + // + // o record the active text field so that we have a reference to it for + // other purposes (like tell it to resignFirstResponder if the user + // taps on another row) + // o choose the "other" row so that the UI and chosenIndex reflect that + // o add an observer for the UITextFieldTextDidChangeNotification so that + // we can track the content of the text field in order to enable and + // disable our Save button +{ + self.activeTextField = textField; + [self chooseRow:[self.choices count]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) name:UITextFieldTextDidChangeNotification object:self.activeTextField]; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField +{ + NSString * finalString; + NSString * urlStr; + + assert(textField == self.activeTextField); + #pragma unused(textField) + + // Push the text field value back to our property. In the process, + // if it's a valid URL, put the full URL string back into the text field. + // This allows the user to type "foo.com" and, when they're done, see + // "http://foo.com". + + finalString = self.activeTextField.text; + urlStr = [self smartURLStringForString:finalString]; + if (urlStr != nil) { + finalString = urlStr; + self.activeTextField.text = finalString; + } + self.otherChoice = finalString; + + // Undo two of the three things done in -textFieldDidBeginEditing:. It's not + // necessary to undo the last one; whether we choose a row other than the "other" + // row is determined by other factors. + + [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:self.activeTextField]; + self.activeTextField = nil; +} + +- (void)textFieldDidChange:(NSNotification *)note + // As the text field in the "other" row changes, reflect that change to our + // otherChoice property, which updates the Save button state via KVO. +{ + assert([note object] == self.activeTextField); + #pragma unused(note) + self.otherChoice = self.activeTextField.text; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField +{ + [self saveAction:textField]; + return NO; +} + +#pragma mark * Actions + +- (IBAction)saveAction:(id)sender + // Called when the user taps the Save button. +{ + #pragma unused(sender) + NSString * value; + NSMutableArray * newChoices; + + // The following is necessary to flush the final URL string out to self.otherChoice. + + if (self.activeTextField != nil) { + [self.activeTextField resignFirstResponder]; + } + + // Get the value we're going to save. + + value = [self effectiveChoice]; + assert(value != nil); // Save should be disabled in this case. + + // If the value is from the "other" field, add it to the choices array + // (if appropriate). + + newChoices = [[self.choices mutableCopy] autorelease]; + assert(newChoices != nil); + + if (self.choiceIndex == [self.choices count]) { + if ([value length] != 0) { // don't add the empty string + if ( ! [self.choices containsObject:value] ) { // don't repeat an existing value + [newChoices addObject:value]; + self.choicesDirty = YES; + } + } + } + + // If the choices list is dirty, save it back to the user defaults. + + if (self.choicesDirty) { + [[NSUserDefaults standardUserDefaults] setObject:newChoices forKey:@"setupChoices"]; + self.choicesDirty = NO; + } + + // Commit the choice of gallery to the network manager. This triggers a world + // of reconfiguration via KVO. + + [self.delegate setupViewController:self didChooseString:value]; +} + +- (IBAction)cancelAction:(id)sender + // Called when the user taps the Cancel button. We just tell our delegate about it. +{ + #pragma unused(sender) + [self.delegate setupViewControllerDidCancel:self]; +} + +- (void)presentModallyOn:(UIViewController *)parent animated:(BOOL)animated +{ + UINavigationController * navController; + + navController = [[[UINavigationController alloc] initWithRootViewController:self] autorelease]; + assert(navController != nil); + + self.navigationItem.title = @"Setup"; + self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveAction:) ] autorelease]; + self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction:)] autorelease]; + + [parent presentModalViewController:navController animated:animated]; +} + +@end diff --git a/MVCNetworking/main.m b/MVCNetworking/main.m new file mode 100644 index 0000000..50299bc --- /dev/null +++ b/MVCNetworking/main.m @@ -0,0 +1,69 @@ +/* + File: main.m + + Contains: Application main. + + Written by: DTS + + Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of + these terms. If you do not agree with these terms, please do + not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following + terms, and subject to these terms, Apple grants you a personal, + non-exclusive license, under Apple's copyrights in this + original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or + without modifications, in source and/or binary forms; provided + that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the + following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks + or logos of Apple Inc. may be used to endorse or promote + products derived from the Apple Software without specific prior + written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or + by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. + APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING + THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY + OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY + OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +*/ + +#import + +int main(int argc, char **argv) +{ + int retVal; + NSAutoreleasePool * pool; + + pool = [[NSAutoreleasePool alloc] init]; + assert(pool != nil); + + retVal = UIApplicationMain(argc, argv, nil, nil); + + [pool drain]; + + return retVal; +} diff --git a/MailComposer.zip b/MailComposer.zip new file mode 100644 index 0000000..44e1a43 Binary files /dev/null and b/MailComposer.zip differ diff --git a/MailComposer/Classes/MailComposerAppDelegate.h b/MailComposer/Classes/MailComposerAppDelegate.h new file mode 100644 index 0000000..be3ce13 --- /dev/null +++ b/MailComposer/Classes/MailComposerAppDelegate.h @@ -0,0 +1,62 @@ +/* + File: MailComposerAppDelegate.h + Abstract: + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class MailComposerViewController; + +@interface MailComposerAppDelegate : NSObject +{ + UIWindow *window; + MailComposerViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet MailComposerViewController *viewController; + +@end + diff --git a/MailComposer/Classes/MailComposerAppDelegate.m b/MailComposer/Classes/MailComposerAppDelegate.m new file mode 100644 index 0000000..8bec898 --- /dev/null +++ b/MailComposer/Classes/MailComposerAppDelegate.m @@ -0,0 +1,72 @@ +/* + File: MailComposerAppDelegate.m + Abstract: + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MailComposerAppDelegate.h" +#import "MailComposerViewController.h" + +@implementation MailComposerAppDelegate +@synthesize window; +@synthesize viewController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // Override point for customization after app launch + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc +{ + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/MailComposer/Classes/MailComposerViewController.h b/MailComposer/Classes/MailComposerViewController.h new file mode 100644 index 0000000..a3c1b44 --- /dev/null +++ b/MailComposer/Classes/MailComposerViewController.h @@ -0,0 +1,64 @@ +/* + File: MailComposerViewController.h + Abstract: + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import + +@interface MailComposerViewController : UIViewController +{ + IBOutlet UILabel *message; +} + +@property (nonatomic, retain) IBOutlet UILabel *message; + +-(IBAction)showPicker:(id)sender; +-(void)displayComposerSheet; +-(void)launchMailAppOnDevice; + +@end + diff --git a/MailComposer/Classes/MailComposerViewController.m b/MailComposer/Classes/MailComposerViewController.m new file mode 100644 index 0000000..69a6136 --- /dev/null +++ b/MailComposer/Classes/MailComposerViewController.m @@ -0,0 +1,179 @@ +/* + File: MailComposerViewController.m + Abstract: + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MailComposerViewController.h" + +@implementation MailComposerViewController +@synthesize message; + +-(IBAction)showPicker:(id)sender +{ + // This sample can run on devices running iPhone OS 2.0 or later + // The MFMailComposeViewController class is only available in iPhone OS 3.0 or later. + // So, we must verify the existence of the above class and provide a workaround for devices running + // earlier versions of the iPhone OS. + // We display an email composition interface if MFMailComposeViewController exists and the device can send emails. + // We launch the Mail application on the device, otherwise. + + Class mailClass = (NSClassFromString(@"MFMailComposeViewController")); + if (mailClass != nil) + { + // We must always check whether the current device is configured for sending emails + if ([mailClass canSendMail]) + { + [self displayComposerSheet]; + } + else + { + [self launchMailAppOnDevice]; + } + } + else + { + [self launchMailAppOnDevice]; + } +} + + +#pragma mark - +#pragma mark Compose Mail + +// Displays an email composition interface inside the application. Populates all the Mail fields. +-(void)displayComposerSheet +{ + MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; + picker.mailComposeDelegate = self; + + [picker setSubject:@"Hello from California!"]; + + + // Set up recipients + NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"]; + NSArray *ccRecipients = [NSArray arrayWithObjects:@"second@example.com", @"third@example.com", nil]; + NSArray *bccRecipients = [NSArray arrayWithObject:@"fourth@example.com"]; + + [picker setToRecipients:toRecipients]; + [picker setCcRecipients:ccRecipients]; + [picker setBccRecipients:bccRecipients]; + + // Attach an image to the email + NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"png"]; + NSData *myData = [NSData dataWithContentsOfFile:path]; + [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"rainy"]; + + // Fill out the email body text + NSString *emailBody = @"It is raining in sunny California!"; + [picker setMessageBody:emailBody isHTML:NO]; + + [self presentModalViewController:picker animated:YES]; + [picker release]; +} + + +// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation. +- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error +{ + message.hidden = NO; + // Notifies users about errors associated with the interface + switch (result) + { + case MFMailComposeResultCancelled: + message.text = @"Result: canceled"; + break; + case MFMailComposeResultSaved: + message.text = @"Result: saved"; + break; + case MFMailComposeResultSent: + message.text = @"Result: sent"; + break; + case MFMailComposeResultFailed: + message.text = @"Result: failed"; + break; + default: + message.text = @"Result: not sent"; + break; + } + [self dismissModalViewControllerAnimated:YES]; +} + + +#pragma mark - +#pragma mark Workaround + +// Launches the Mail application on the device. +-(void)launchMailAppOnDevice +{ + NSString *recipients = @"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Hello from California!"; + NSString *body = @"&body=It is raining in sunny California!"; + + NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body]; + email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]]; +} + + +#pragma mark - +#pragma mark Unload views + +- (void)viewDidUnload +{ + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.message = nil; +} + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc +{ + [message release]; + [super dealloc]; +} + +@end diff --git a/MailComposer/MailComposer-Info.plist b/MailComposer/MailComposer-Info.plist new file mode 100644 index 0000000..20fe35d --- /dev/null +++ b/MailComposer/MailComposer-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/MailComposer/MailComposer.xcodeproj/lindaouandji.mode1v3 b/MailComposer/MailComposer.xcodeproj/lindaouandji.mode1v3 new file mode 100644 index 0000000..6b00c80 --- /dev/null +++ b/MailComposer/MailComposer.xcodeproj/lindaouandji.mode1v3 @@ -0,0 +1,1403 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /iPhoneWorkshop/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + EB00F7250F69E57700C36C0E + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 195 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FBAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {195, 841}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {212, 859}} + GroupTreeTableConfiguration + + MainColumn + 195 + + RubberWindowFrame + 92 128 1321 900 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 212pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + MailComposerViewController.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + MailComposerViewController.m + _historyCapacity + 0 + bookmark + EBCA1AB20FA0FB4100F5A322 + history + + EBE9FD190F6B1D6600A8C335 + EBE9FD1A0F6B1D6600A8C335 + EB2120FA0F6B1DA500860EAD + EB7DAD900F9D1151001E24BB + EB7DAD910F9D1151001E24BB + EB704B9B0F9E3A0600D24E5C + EB704B9C0F9E3A0600D24E5C + EB3CDB920FA0F7620041A5E7 + EB3CDBC00FA0F88D0041A5E7 + EBCA1AB00FA0FB4100F5A322 + EB3CDBC20FA0F88D0041A5E7 + + prevStack + + EB0D9DE30F6B090C002782F0 + EB0D9DE40F6B090C002782F0 + EB0D9DE70F6B090C002782F0 + EB0D9DEA0F6B090C002782F0 + EB0D9E620F6B1073002782F0 + EB725D290F6B1C2800DD8279 + EB725D2D0F6B1C2800DD8279 + EB2120FD0F6B1DA500860EAD + EB704BA10F9E3A0600D24E5C + EB3CDB950FA0F7620041A5E7 + EB3CDBC50FA0F88D0041A5E7 + EBCA1AB10FA0FB4100F5A322 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1104, 766}} + RubberWindowFrame + 92 128 1321 900 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 766pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 771}, {1104, 88}} + RubberWindowFrame + 92 128 1321 900 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 88pt + + + Proportion + 1104pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + EBCA1A910FA0FAF600F5A322 + 1CE0B1FE06471DED0097A5F4 + EBCA1A920FA0FAF600F5A322 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/iPhoneWorkshop/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + EB0D9DD20F6B08ED002782F0 + /Users/lindaouandji/MailComposer/MailComposer.xcodeproj + + WindowString + 92 128 1321 900 0 0 1680 1028 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 167 505 500 500 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 167 505 500 500 0 0 1680 1028 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + EB0D9DD20F6B08ED002782F0 + EBCA1AB30FA0FB4100F5A322 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowString + 167 505 500 500 0 0 1680 1028 + WindowToolGUID + EB0D9DD20F6B08ED002782F0 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 299 583 694 422 0 0 1680 1028 + + RubberWindowFrame + 299 583 694 422 0 0 1680 1028 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + EB3CDB860FA0F71B0041A5E7 + 1C162984064C10D400B95A72 + EB3CDB870FA0F71B0041A5E7 + EB3CDB880FA0F71B0041A5E7 + EB3CDB890FA0F71B0041A5E7 + EB3CDB8A0FA0F71B0041A5E7 + EB3CDB8B0FA0F71B0041A5E7 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 299 583 694 422 0 0 1680 1028 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {845, 323}} + RubberWindowFrame + 590 447 845 581 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 845pt + + + Proportion + 323pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 328}, {845, 212}} + RubberWindowFrame + 590 447 845 581 0 0 1680 1028 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 540pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + EB0D9E910F6B119F002782F0 + EB0D9E920F6B119F002782F0 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 590 447 845 581 0 0 1680 1028 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {749, 479}} + RubberWindowFrame + 175 485 749 520 0 0 1680 1028 + + Module + PBXDebugCLIModule + Proportion + 479pt + + + Proportion + 479pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + EB3CDB8C0FA0F71B0041A5E7 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 175 485 749 520 0 0 1680 1028 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/MailComposer/MailComposer.xcodeproj/project.pbxproj b/MailComposer/MailComposer.xcodeproj/project.pbxproj new file mode 100755 index 0000000..b050a87 --- /dev/null +++ b/MailComposer/MailComposer.xcodeproj/project.pbxproj @@ -0,0 +1,318 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 184F5FE911D1492B00B9AF43 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE111D1492B00B9AF43 /* Icon-72.png */; }; + 184F5FEA11D1492B00B9AF43 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE211D1492B00B9AF43 /* Icon-Small-50.png */; }; + 184F5FEB11D1492B00B9AF43 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE311D1492B00B9AF43 /* Icon-Small.png */; }; + 184F5FEC11D1492B00B9AF43 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE411D1492B00B9AF43 /* Icon-Small@2x.png */; }; + 184F5FED11D1492B00B9AF43 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE511D1492B00B9AF43 /* Icon.png */; }; + 184F5FEE11D1492B00B9AF43 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE611D1492B00B9AF43 /* Icon@2x.png */; }; + 184F5FEF11D1492B00B9AF43 /* iTunesArtwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE711D1492B00B9AF43 /* iTunesArtwork.png */; }; + 184F5FF011D1492B00B9AF43 /* rainy.png in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FE811D1492B00B9AF43 /* rainy.png */; }; + 184F5FF511D1494200B9AF43 /* MailComposerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FF111D1494200B9AF43 /* MailComposerViewController.xib */; }; + 184F5FF611D1494200B9AF43 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 184F5FF311D1494200B9AF43 /* MainWindow.xib */; }; + 1D3623260D0F684500981E51 /* MailComposerAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MailComposerAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 28D7ACF80DDB3853001CB0EB /* MailComposerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* MailComposerViewController.m */; }; + EB0D9DDB0F6B08FE002782F0 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB0D9DDA0F6B08FE002782F0 /* MessageUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + EB0D9E540F6B0FD2002782F0 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = EB0D9E530F6B0FD2002782F0 /* ReadMe.txt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 184F5FE111D1492B00B9AF43 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 184F5FE211D1492B00B9AF43 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 184F5FE311D1492B00B9AF43 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 184F5FE411D1492B00B9AF43 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 184F5FE511D1492B00B9AF43 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 184F5FE611D1492B00B9AF43 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 184F5FE711D1492B00B9AF43 /* iTunesArtwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iTunesArtwork.png; path = images/iTunesArtwork.png; sourceTree = ""; }; + 184F5FE811D1492B00B9AF43 /* rainy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = rainy.png; path = images/rainy.png; sourceTree = ""; }; + 184F5FF211D1494200B9AF43 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MailComposerViewController.xib; sourceTree = ""; }; + 184F5FF411D1494200B9AF43 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* MailComposerAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MailComposerAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* MailComposerAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MailComposerAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* MailComposer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MailComposer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28D7ACF60DDB3853001CB0EB /* MailComposerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MailComposerViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* MailComposerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MailComposerViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* MailComposer_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MailComposer_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* MailComposer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MailComposer-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + EB0D9DDA0F6B08FE002782F0 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; + EB0D9E530F6B0FD2002782F0 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + EB0D9DDB0F6B08FE002782F0 /* MessageUI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* MailComposerAppDelegate.h */, + 1D3623250D0F684500981E51 /* MailComposerAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* MailComposerViewController.h */, + 28D7ACF70DDB3853001CB0EB /* MailComposerViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MailComposer.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + EB0D9DDA0F6B08FE002782F0 /* MessageUI.framework */, + EB0D9E530F6B0FD2002782F0 /* ReadMe.txt */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* MailComposer_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 184F5FF111D1494200B9AF43 /* MailComposerViewController.xib */, + 184F5FF311D1494200B9AF43 /* MainWindow.xib */, + 184F5FE111D1492B00B9AF43 /* Icon-72.png */, + 184F5FE211D1492B00B9AF43 /* Icon-Small-50.png */, + 184F5FE311D1492B00B9AF43 /* Icon-Small.png */, + 184F5FE411D1492B00B9AF43 /* Icon-Small@2x.png */, + 184F5FE511D1492B00B9AF43 /* Icon.png */, + 184F5FE611D1492B00B9AF43 /* Icon@2x.png */, + 184F5FE711D1492B00B9AF43 /* iTunesArtwork.png */, + 184F5FE811D1492B00B9AF43 /* rainy.png */, + 8D1107310486CEB800E47090 /* MailComposer-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MailComposer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MailComposer" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MailComposer; + productName = MailComposer; + productReference = 1D6058910D05DD3D006BFB54 /* MailComposer.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MailComposer" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MailComposer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB0D9E540F6B0FD2002782F0 /* ReadMe.txt in Resources */, + 184F5FE911D1492B00B9AF43 /* Icon-72.png in Resources */, + 184F5FEA11D1492B00B9AF43 /* Icon-Small-50.png in Resources */, + 184F5FEB11D1492B00B9AF43 /* Icon-Small.png in Resources */, + 184F5FEC11D1492B00B9AF43 /* Icon-Small@2x.png in Resources */, + 184F5FED11D1492B00B9AF43 /* Icon.png in Resources */, + 184F5FEE11D1492B00B9AF43 /* Icon@2x.png in Resources */, + 184F5FEF11D1492B00B9AF43 /* iTunesArtwork.png in Resources */, + 184F5FF011D1492B00B9AF43 /* rainy.png in Resources */, + 184F5FF511D1494200B9AF43 /* MailComposerViewController.xib in Resources */, + 184F5FF611D1494200B9AF43 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* MailComposerAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* MailComposerViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 184F5FF111D1494200B9AF43 /* MailComposerViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 184F5FF211D1494200B9AF43 /* en */, + ); + name = MailComposerViewController.xib; + sourceTree = ""; + }; + 184F5FF311D1494200B9AF43 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 184F5FF411D1494200B9AF43 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MailComposer_Prefix.pch; + INFOPLIST_FILE = "MailComposer-Info.plist"; + PRODUCT_NAME = MailComposer; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MailComposer_Prefix.pch; + INFOPLIST_FILE = "MailComposer-Info.plist"; + PRODUCT_NAME = MailComposer; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MailComposer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MailComposer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MailComposer/MailComposer_Prefix.pch b/MailComposer/MailComposer_Prefix.pch new file mode 100644 index 0000000..6aae466 --- /dev/null +++ b/MailComposer/MailComposer_Prefix.pch @@ -0,0 +1,51 @@ +/* + File: MailComposer_Prefix.pch + Abstract: + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/MailComposer/ReadMe.txt b/MailComposer/ReadMe.txt new file mode 100644 index 0000000..b4bb52d --- /dev/null +++ b/MailComposer/ReadMe.txt @@ -0,0 +1,79 @@ +MailComposer demonstrates how to target older OS versions while building with newly released APIs. This sample also shows how to use the MessageUI framework to create and send email messages from within your application. + +The iPhone OS SDK 3.0 introduces the MFMailComposeViewController class (in the MessageUI framework). This class manages a user interface that allows users to compose and send email messages from within their applications. + +MailComposer displays a button labeled "Compose Mail." When users tap "Compose Mail," this application either shows an email composition interface +or launches the Mail application on the device. +It shows an email composition interface if MFMailComposeViewController exists and the device is configured for sending emails. It launches the Mail application on the device, otherwise. + + +MailComposer runs on earlier and later releases of the iPhone OS and uses new APIs introduced in iPhone SDK 3.0. See below for steps that describe how to target earlier 0S versions while building with newly released APIs. + + +1. Set your iPhone OS Deployment Target setting to your application's target iPhone OS release +This setting indicates the earliest iPhone OS on which your application can run. We set it to iPhone OS 2.0. + + +2. Set the Base SDK to the desired iPhone SDK +This setting indicates what release of the iPhone SDK will be used to build your application. We set it to iPhone SDK 3.0 in order to take advantage of all the features of the new MessageUI framework. + + +3. Make MessageUI a weak framework (set its role to Weak) +An application will fail to launch or proceed if it attempts to load a framework on devices where this framework is absent. +With weak linking, an application does not fail, but proceeds when a symbol or framework is not present at runtime. All weak-linked symbols are set to NULL on devices without them. + +To designate MessageUI as weak-linked, select the target's Link Binary With Libraries build phase, then change MessageUI's role from Required to Weak in the detail view. + + +4. Check for the existence of APIs before calling them +MailComposer will crash if it attempts to use non-existent weak-linked symbols. The showPicker method checks whether MFMailComposeViewController exists (is non-NULL) before using it. + + +5. Provide a workaround for non-existent APIs +The showPicker method calls the launchMailAppOnDevice method if MFMailComposeViewController does not exist. launchMailAppOnDevice opens the Mail application on devices running earlier releases of the iPhone OS. + + +Further Reading +Setting Your Application's Target iPhone OS Release and Setting the Active SDK of the iPhone Development Guide + + +Frameworks and Weak Linking + + + +Build Requirements: +iOS 4.0 SDK + + +Runtime Requirements: +iPhone OS 3.2 or later + + +Using the Sample +Build and run the sample using Xcode 3.1.3 or later. +Tap the "Compose Mail" button to display an email composition interface if the device is running iPhone OS 3.0 or launch the Mail application, otherwise. + + + +Packaging List +main.m - Main source file for this sample. + +MailComposerAppDelegate.h +MailComposerAppDelegate.m +The application's delegate to setup its window and content. + + +MailComposerViewController.h +MailComposerViewController.m +A view controller for managing the MailComposer view. + +MainWindow.xib +The nib file containing the main window. + +MailComposerViewController.xib +The view controller's nib file. + +Versions: +1.1 - Upgraded project to build with the iOS 4.0 SDK. + +Copyright (c) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/MailComposer/en.lproj/MailComposerViewController.xib b/MailComposer/en.lproj/MailComposerViewController.xib new file mode 100644 index 0000000..ef9830d --- /dev/null +++ b/MailComposer/en.lproj/MailComposerViewController.xib @@ -0,0 +1,246 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 292 + {{97, 212}, {126, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + Compose Mail + Compose Mail + Compose Mail + Compose Mail + + 1 + MSAxIDEAA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + -2147483356 + {{20, 261}, {280, 117}} + + NO + YES + NO + Error + + Helvetica + 1.500000e+01 + 16 + + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + 7 + 1 + + + {320, 460} + + + 3 + MC43NQA + + 2 + + + NO + + + + + + YES + + + view + + + + 7 + + + + showPicker: + + + 7 + + 11 + + + + message + + + + 12 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 6 + + + YES + + + + + + + 9 + + + + + 10 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 9.IBPluginDependency + + + YES + MailComposerViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{438, 347}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 12 + + + + YES + + MailComposerViewController + UIViewController + + showPicker: + id + + + message + UILabel + + + IBProjectSource + Classes/MailComposerViewController.h + + + + + 0 + MailComposer.xcodeproj + 3 + + diff --git a/MailComposer/en.lproj/MainWindow.xib b/MailComposer/en.lproj/MainWindow.xib new file mode 100644 index 0000000..95ec105 --- /dev/null +++ b/MailComposer/en.lproj/MainWindow.xib @@ -0,0 +1,218 @@ + + + + 768 + 10A288 + 715 + 1010 + 411.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 46 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + MailComposerViewController + + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + viewController + + + + 11 + + + + window + + + + 14 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + MailComposer App Delegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + MailComposerViewController + {{512, 351}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MailComposerAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 14 + + + + YES + + MailComposerAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + MailComposerViewController + UIWindow + + + + IBProjectSource + Classes/MailComposerAppDelegate.h + + + + MailComposerAppDelegate + NSObject + + IBUserSource + + + + + MailComposerViewController + UIViewController + + IBProjectSource + Classes/MailComposerViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + MailComposer.xcodeproj + 3 + + diff --git a/MailComposer/images/Icon-72.png b/MailComposer/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/MailComposer/images/Icon-72.png differ diff --git a/MailComposer/images/Icon-Small-50.png b/MailComposer/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/MailComposer/images/Icon-Small-50.png differ diff --git a/MailComposer/images/Icon-Small.png b/MailComposer/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/MailComposer/images/Icon-Small.png differ diff --git a/MailComposer/images/Icon-Small@2x.png b/MailComposer/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/MailComposer/images/Icon-Small@2x.png differ diff --git a/MailComposer/images/Icon.png b/MailComposer/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/MailComposer/images/Icon.png differ diff --git a/MailComposer/images/Icon@2x.png b/MailComposer/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/MailComposer/images/Icon@2x.png differ diff --git a/MailComposer/images/iTunesArtwork.png b/MailComposer/images/iTunesArtwork.png new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/MailComposer/images/iTunesArtwork.png differ diff --git a/MailComposer/images/rainy.png b/MailComposer/images/rainy.png new file mode 100644 index 0000000..a56eec2 Binary files /dev/null and b/MailComposer/images/rainy.png differ diff --git a/MailComposer/main.m b/MailComposer/main.m new file mode 100644 index 0000000..7a1289d --- /dev/null +++ b/MailComposer/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/MapCallouts.zip b/MapCallouts.zip new file mode 100644 index 0000000..a7236d2 Binary files /dev/null and b/MapCallouts.zip differ diff --git a/MapCallouts/AppDelegate.h b/MapCallouts/AppDelegate.h new file mode 100755 index 0000000..87f5453 --- /dev/null +++ b/MapCallouts/AppDelegate.h @@ -0,0 +1,59 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for installing our navigation controller. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *myNavController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *myNavController; + +@end diff --git a/MapCallouts/AppDelegate.m b/MapCallouts/AppDelegate.m new file mode 100755 index 0000000..c88bd19 --- /dev/null +++ b/MapCallouts/AppDelegate.m @@ -0,0 +1,70 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for installing our navigation controller. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MapViewController.h" + +@implementation AppDelegate; + +@synthesize window, myNavController; + +- (void)dealloc +{ + [myNavController release]; + [window release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + [window addSubview:myNavController.view]; + [window makeKeyAndVisible]; +} + +@end diff --git a/MapCallouts/BridgeAnnotation.h b/MapCallouts/BridgeAnnotation.h new file mode 100755 index 0000000..c3f617f --- /dev/null +++ b/MapCallouts/BridgeAnnotation.h @@ -0,0 +1,55 @@ +/* + File: BridgeAnnotation.h + Abstract: The custom MKAnnotation object representing the Golden Gate Bridge. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface BridgeAnnotation : NSObject +{ + +} + +@end \ No newline at end of file diff --git a/MapCallouts/BridgeAnnotation.m b/MapCallouts/BridgeAnnotation.m new file mode 100755 index 0000000..eeb6437 --- /dev/null +++ b/MapCallouts/BridgeAnnotation.m @@ -0,0 +1,77 @@ +/* + File: BridgeAnnotation.m + Abstract: The custom MKAnnotation object representing the Golden Gate Bridge. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "BridgeAnnotation.h" + +@implementation BridgeAnnotation + +- (CLLocationCoordinate2D)coordinate; +{ + CLLocationCoordinate2D theCoordinate; + theCoordinate.latitude = 37.810000; + theCoordinate.longitude = -122.477989; + return theCoordinate; +} + +// required if you set the MKPinAnnotationView's "canShowCallout" property to YES +- (NSString *)title +{ + return @"Golden Gate Bridge"; +} + +// optional +- (NSString *)subtitle +{ + return @"Opened: May 27, 1937"; +} + +- (void)dealloc +{ + [super dealloc]; +} + +@end \ No newline at end of file diff --git a/MapCallouts/DetailViewController.h b/MapCallouts/DetailViewController.h new file mode 100644 index 0000000..81fcd2d --- /dev/null +++ b/MapCallouts/DetailViewController.h @@ -0,0 +1,55 @@ +/* + File: DetailViewController.h + Abstract: The detail view controller used for displaying the Golden Gate Bridge. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface DetailViewController : UIViewController +{ + +} + +@end diff --git a/MapCallouts/DetailViewController.m b/MapCallouts/DetailViewController.m new file mode 100644 index 0000000..9a833cb --- /dev/null +++ b/MapCallouts/DetailViewController.m @@ -0,0 +1,70 @@ +/* + File: DetailViewController.m + Abstract: The detail view controller used for displaying the Golden Gate Bridge. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "DetailViewController.h" + +@implementation DetailViewController + +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib +- (void)viewDidLoad +{ + [super viewDidLoad]; +} + +- (void)viewDidUnload +{ + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +- (void)dealloc +{ + [super dealloc]; +} + + +@end diff --git a/MapCallouts/Info.plist b/MapCallouts/Info.plist new file mode 100755 index 0000000..69a629a --- /dev/null +++ b/MapCallouts/Info.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon-72.png + Icon@2x.png + Icon-Small.png + Icon-Small@2x.png + Icon-Small-50.png + + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + NSMainNibFile + MainWindow + + diff --git a/MapCallouts/MapCallouts.xcodeproj/project.pbxproj b/MapCallouts/MapCallouts.xcodeproj/project.pbxproj new file mode 100755 index 0000000..98e6da4 --- /dev/null +++ b/MapCallouts/MapCallouts.xcodeproj/project.pbxproj @@ -0,0 +1,376 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 5321F1870F7AE57A00EC9E3A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5321F1840F7AE57A00EC9E3A /* AppDelegate.m */; }; + 5321F18F0F7AE5BA00EC9E3A /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5321F18D0F7AE5BA00EC9E3A /* MainWindow.xib */; }; + 533D375B10B329010057E53B /* SFAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 533D375A10B329010057E53B /* SFAnnotation.m */; }; + 533D37F410B32D500057E53B /* MapViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 533D37F210B32D500057E53B /* MapViewController.xib */; }; + 534BB35210B4A47500C8BE22 /* BridgeAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 534BB35110B4A47500C8BE22 /* BridgeAnnotation.m */; }; + 536EE47A10B358610080A190 /* MapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 536EE47910B358610080A190 /* MapViewController.m */; }; + 5376EF070F7AE77A005C5273 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5376EF060F7AE77A005C5273 /* MapKit.framework */; }; + 537DA6BA1108F80B0045D54C /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 537DA6B91108F80B0045D54C /* DetailViewController.m */; }; + 537DA6BE1108F8460045D54C /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537DA6BC1108F8460045D54C /* DetailViewController.xib */; }; + CB6C7CB111D53FDA00AC7FA8 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CA511D53FDA00AC7FA8 /* Default.png */; }; + CB6C7CB211D53FDA00AC7FA8 /* flag.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CA611D53FDA00AC7FA8 /* flag.png */; }; + CB6C7CB311D53FDA00AC7FA8 /* GoldenGate.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CA711D53FDA00AC7FA8 /* GoldenGate.png */; }; + CB6C7CB411D53FDA00AC7FA8 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CA811D53FDA00AC7FA8 /* Icon-72.png */; }; + CB6C7CB511D53FDA00AC7FA8 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CA911D53FDA00AC7FA8 /* Icon-Small-50.png */; }; + CB6C7CB611D53FDA00AC7FA8 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CAA11D53FDA00AC7FA8 /* Icon-Small.png */; }; + CB6C7CB711D53FDA00AC7FA8 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CAB11D53FDA00AC7FA8 /* Icon-Small@2x.png */; }; + CB6C7CB811D53FDA00AC7FA8 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CAC11D53FDA00AC7FA8 /* Icon.png */; }; + CB6C7CB911D53FDA00AC7FA8 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CAD11D53FDA00AC7FA8 /* Icon@2x.png */; }; + CB6C7CBB11D53FDA00AC7FA8 /* Location.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CAF11D53FDA00AC7FA8 /* Location.png */; }; + CB6C7CBC11D53FDA00AC7FA8 /* SFIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CB011D53FDA00AC7FA8 /* SFIcon.png */; }; + CB6C7CBE11D5400200AC7FA8 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7CBD11D5400200AC7FA8 /* iTunesArtwork */; }; + CB8F294A11D176F900E84C56 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = CB8F294911D176F900E84C56 /* ReadMe.txt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* MapCallouts.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MapCallouts.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5321F1840F7AE57A00EC9E3A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5321F1850F7AE57A00EC9E3A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5321F1880F7AE58700EC9E3A /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 5321F18E0F7AE5BA00EC9E3A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 5321F1900F7AE5BE00EC9E3A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 533D375910B329010057E53B /* SFAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFAnnotation.h; sourceTree = ""; }; + 533D375A10B329010057E53B /* SFAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SFAnnotation.m; sourceTree = ""; }; + 533D37F310B32D500057E53B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MapViewController.xib; sourceTree = ""; }; + 533D38CB10B352230057E53B /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 534BB35010B4A47500C8BE22 /* BridgeAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BridgeAnnotation.h; sourceTree = ""; }; + 534BB35110B4A47500C8BE22 /* BridgeAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BridgeAnnotation.m; sourceTree = ""; }; + 536EE47810B358610080A190 /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapViewController.h; sourceTree = ""; }; + 536EE47910B358610080A190 /* MapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewController.m; sourceTree = ""; }; + 5376EF060F7AE77A005C5273 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 537DA6B81108F80B0045D54C /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + 537DA6B91108F80B0045D54C /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; + 537DA6BD1108F8460045D54C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController.xib; sourceTree = ""; }; + CB6C7CA511D53FDA00AC7FA8 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + CB6C7CA611D53FDA00AC7FA8 /* flag.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flag.png; sourceTree = ""; }; + CB6C7CA711D53FDA00AC7FA8 /* GoldenGate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = GoldenGate.png; sourceTree = ""; }; + CB6C7CA811D53FDA00AC7FA8 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + CB6C7CA911D53FDA00AC7FA8 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + CB6C7CAA11D53FDA00AC7FA8 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + CB6C7CAB11D53FDA00AC7FA8 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + CB6C7CAC11D53FDA00AC7FA8 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + CB6C7CAD11D53FDA00AC7FA8 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + CB6C7CAF11D53FDA00AC7FA8 /* Location.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Location.png; sourceTree = ""; }; + CB6C7CB011D53FDA00AC7FA8 /* SFIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SFIcon.png; sourceTree = ""; }; + CB6C7CBD11D5400200AC7FA8 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = ../iTunesArtwork; sourceTree = ""; }; + CB8F294911D176F900E84C56 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 5376EF070F7AE77A005C5273 /* MapKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MapCallouts.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + CB8F294911D176F900E84C56 /* ReadMe.txt */, + CB6C7CA311D53FA900AC7FA8 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 5321F1880F7AE58700EC9E3A /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + CB6C7CA411D53FDA00AC7FA8 /* images */, + 5321F1900F7AE5BE00EC9E3A /* Info.plist */, + 5321F18D0F7AE5BA00EC9E3A /* MainWindow.xib */, + 533D37F210B32D500057E53B /* MapViewController.xib */, + 537DA6BC1108F8460045D54C /* DetailViewController.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 533D38CB10B352230057E53B /* CoreLocation.framework */, + 5376EF060F7AE77A005C5273 /* MapKit.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CB6C7CA311D53FA900AC7FA8 /* Classes */ = { + isa = PBXGroup; + children = ( + 5321F1850F7AE57A00EC9E3A /* AppDelegate.h */, + 5321F1840F7AE57A00EC9E3A /* AppDelegate.m */, + 536EE47810B358610080A190 /* MapViewController.h */, + 536EE47910B358610080A190 /* MapViewController.m */, + 537DA6B81108F80B0045D54C /* DetailViewController.h */, + 537DA6B91108F80B0045D54C /* DetailViewController.m */, + 533D375910B329010057E53B /* SFAnnotation.h */, + 533D375A10B329010057E53B /* SFAnnotation.m */, + 534BB35010B4A47500C8BE22 /* BridgeAnnotation.h */, + 534BB35110B4A47500C8BE22 /* BridgeAnnotation.m */, + ); + name = Classes; + sourceTree = ""; + }; + CB6C7CA411D53FDA00AC7FA8 /* images */ = { + isa = PBXGroup; + children = ( + CB6C7CBD11D5400200AC7FA8 /* iTunesArtwork */, + CB6C7CA511D53FDA00AC7FA8 /* Default.png */, + CB6C7CA611D53FDA00AC7FA8 /* flag.png */, + CB6C7CA711D53FDA00AC7FA8 /* GoldenGate.png */, + CB6C7CA811D53FDA00AC7FA8 /* Icon-72.png */, + CB6C7CA911D53FDA00AC7FA8 /* Icon-Small-50.png */, + CB6C7CAA11D53FDA00AC7FA8 /* Icon-Small.png */, + CB6C7CAB11D53FDA00AC7FA8 /* Icon-Small@2x.png */, + CB6C7CAC11D53FDA00AC7FA8 /* Icon.png */, + CB6C7CAD11D53FDA00AC7FA8 /* Icon@2x.png */, + CB6C7CAF11D53FDA00AC7FA8 /* Location.png */, + CB6C7CB011D53FDA00AC7FA8 /* SFIcon.png */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MapCallouts */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MapCallouts" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MapCallouts; + productName = CPView; + productReference = 1D6058910D05DD3D006BFB54 /* MapCallouts.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MapCallouts" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MapCallouts */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5321F18F0F7AE5BA00EC9E3A /* MainWindow.xib in Resources */, + 533D37F410B32D500057E53B /* MapViewController.xib in Resources */, + 537DA6BE1108F8460045D54C /* DetailViewController.xib in Resources */, + CB8F294A11D176F900E84C56 /* ReadMe.txt in Resources */, + CB6C7CB111D53FDA00AC7FA8 /* Default.png in Resources */, + CB6C7CB211D53FDA00AC7FA8 /* flag.png in Resources */, + CB6C7CB311D53FDA00AC7FA8 /* GoldenGate.png in Resources */, + CB6C7CB411D53FDA00AC7FA8 /* Icon-72.png in Resources */, + CB6C7CB511D53FDA00AC7FA8 /* Icon-Small-50.png in Resources */, + CB6C7CB611D53FDA00AC7FA8 /* Icon-Small.png in Resources */, + CB6C7CB711D53FDA00AC7FA8 /* Icon-Small@2x.png in Resources */, + CB6C7CB811D53FDA00AC7FA8 /* Icon.png in Resources */, + CB6C7CB911D53FDA00AC7FA8 /* Icon@2x.png in Resources */, + CB6C7CBB11D53FDA00AC7FA8 /* Location.png in Resources */, + CB6C7CBC11D53FDA00AC7FA8 /* SFIcon.png in Resources */, + CB6C7CBE11D5400200AC7FA8 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 5321F1870F7AE57A00EC9E3A /* AppDelegate.m in Sources */, + 533D375B10B329010057E53B /* SFAnnotation.m in Sources */, + 536EE47A10B358610080A190 /* MapViewController.m in Sources */, + 534BB35210B4A47500C8BE22 /* BridgeAnnotation.m in Sources */, + 537DA6BA1108F80B0045D54C /* DetailViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5321F18D0F7AE5BA00EC9E3A /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 5321F18E0F7AE5BA00EC9E3A /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 533D37F210B32D500057E53B /* MapViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 533D37F310B32D500057E53B /* en */, + ); + name = MapViewController.xib; + sourceTree = ""; + }; + 537DA6BC1108F8460045D54C /* DetailViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 537DA6BD1108F8460045D54C /* en */, + ); + name = DetailViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CODE_SIGN_RESOURCE_RULES_PATH = ""; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = MapCallouts; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CODE_SIGN_RESOURCE_RULES_PATH = ""; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = MapCallouts; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MapCallouts" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MapCallouts" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MapCallouts/MapViewController.h b/MapCallouts/MapViewController.h new file mode 100644 index 0000000..5417f4f --- /dev/null +++ b/MapCallouts/MapViewController.h @@ -0,0 +1,72 @@ +/* + File: MapViewController.h + Abstract: The primary view controller containing the MKMapView, adding and removing both MKPinAnnotationViews through its toolbar. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@class DetailViewController; + +@interface MapViewController : UIViewController +{ + MKMapView *mapView; + DetailViewController *detailViewController; + NSMutableArray *mapAnnotations; +} + +@property (nonatomic, retain) IBOutlet MKMapView *mapView; +@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController; + +@property (nonatomic, retain) NSMutableArray *mapAnnotations; + ++ (CGFloat)annotationPadding; ++ (CGFloat)calloutHeight; + +- (IBAction)cityAction:(id)sender; +- (IBAction)bridgeAction:(id)sender; +- (IBAction)allAction:(id)sender; + +@end diff --git a/MapCallouts/MapViewController.m b/MapCallouts/MapViewController.m new file mode 100644 index 0000000..b5e8da8 --- /dev/null +++ b/MapCallouts/MapViewController.m @@ -0,0 +1,267 @@ +/* + File: MapViewController.m + Abstract: The primary view controller containing the MKMapView, adding and removing both MKPinAnnotationViews through its toolbar. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MapViewController.h" +#import "DetailViewController.h" +#import "SFAnnotation.h" +#import "BridgeAnnotation.h" + +enum +{ + kCityAnnotationIndex = 0, + kBridgeAnnotationIndex +}; + +@implementation MapViewController + +@synthesize mapView, detailViewController, mapAnnotations; + + +#pragma mark - + ++ (CGFloat)annotationPadding; +{ + return 10.0f; +} ++ (CGFloat)calloutHeight; +{ + return 40.0f; +} + +- (void)gotoLocation +{ + // start off by default in San Francisco + MKCoordinateRegion newRegion; + newRegion.center.latitude = 37.786996; + newRegion.center.longitude = -122.440100; + newRegion.span.latitudeDelta = 0.112872; + newRegion.span.longitudeDelta = 0.109863; + + [self.mapView setRegion:newRegion animated:YES]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + // bring back the toolbar + [self.navigationController setToolbarHidden:NO animated:NO]; +} + +- (void)viewDidLoad +{ + self.mapView.mapType = MKMapTypeStandard; // also MKMapTypeSatellite or MKMapTypeHybrid + + // create a custom navigation bar button and set it to always says "Back" + UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init]; + temporaryBarButtonItem.title = @"Back"; + self.navigationItem.backBarButtonItem = temporaryBarButtonItem; + [temporaryBarButtonItem release]; + + // create out annotations array (in this example only 2) + self.mapAnnotations = [[NSMutableArray alloc] initWithCapacity:2]; + + // annotation for the City of San Francisco + SFAnnotation *sfAnnotation = [[SFAnnotation alloc] init]; + [self.mapAnnotations insertObject:sfAnnotation atIndex:kCityAnnotationIndex]; + [sfAnnotation release]; + + // annotation for Golden Gate Bridge + BridgeAnnotation *bridgeAnnotation = [[BridgeAnnotation alloc] init]; + [self.mapAnnotations insertObject:bridgeAnnotation atIndex:kBridgeAnnotationIndex]; + [bridgeAnnotation release]; + + [self gotoLocation]; // finally goto San Francisco +} + +- (void)viewDidUnload +{ + self.mapAnnotations = nil; + self.detailViewController = nil; + self.mapView = nil; +} + +- (void)dealloc +{ + [mapView release]; + [detailViewController release]; + [mapAnnotations release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark ButtonActions + +- (IBAction)cityAction:(id)sender +{ + [self gotoLocation];//•• avoid this by checking its region from ours?? + + [self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist + + [self.mapView addAnnotation:[self.mapAnnotations objectAtIndex:kCityAnnotationIndex]]; +} + +- (IBAction)bridgeAction:(id)sender +{ + [self gotoLocation]; + [self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist + + [self.mapView addAnnotation:[self.mapAnnotations objectAtIndex:kBridgeAnnotationIndex]]; +} + +- (IBAction)allAction:(id)sender +{ + [self gotoLocation]; + [self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist + + [self.mapView addAnnotations:self.mapAnnotations]; +} + +#pragma mark - +#pragma mark MKMapViewDelegate + +- (void)showDetails:(id)sender +{ + // the detail view does not want a toolbar so hide it + [self.navigationController setToolbarHidden:YES animated:NO]; + + [self.navigationController pushViewController:self.detailViewController animated:YES]; +} + +- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id )annotation +{ + // if it's the user location, just return nil. + if ([annotation isKindOfClass:[MKUserLocation class]]) + return nil; + + // handle our two custom annotations + // + if ([annotation isKindOfClass:[BridgeAnnotation class]]) // for Golden Gate Bridge + { + // try to dequeue an existing pin view first + static NSString* BridgeAnnotationIdentifier = @"bridgeAnnotationIdentifier"; + MKPinAnnotationView* pinView = (MKPinAnnotationView *) + [mapView dequeueReusableAnnotationViewWithIdentifier:BridgeAnnotationIdentifier]; + if (!pinView) + { + // if an existing pin view was not available, create one + MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc] + initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease]; + customPinView.pinColor = MKPinAnnotationColorPurple; + customPinView.animatesDrop = YES; + customPinView.canShowCallout = YES; + + // add a detail disclosure button to the callout which will open a new view controller page + // + // note: you can assign a specific call out accessory view, or as MKMapViewDelegate you can implement: + // - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control; + // + UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; + [rightButton addTarget:self + action:@selector(showDetails:) + forControlEvents:UIControlEventTouchUpInside]; + customPinView.rightCalloutAccessoryView = rightButton; + + return customPinView; + } + else + { + pinView.annotation = annotation; + } + return pinView; + } + else if ([annotation isKindOfClass:[SFAnnotation class]]) // for City of San Francisco + { + static NSString* SFAnnotationIdentifier = @"SFAnnotationIdentifier"; + MKPinAnnotationView* pinView = + (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:SFAnnotationIdentifier]; + if (!pinView) + { + MKAnnotationView *annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation + reuseIdentifier:SFAnnotationIdentifier] autorelease]; + annotationView.canShowCallout = YES; + + UIImage *flagImage = [UIImage imageNamed:@"flag.png"]; + + CGRect resizeRect; + + resizeRect.size = flagImage.size; + CGSize maxSize = CGRectInset(self.view.bounds, + [MapViewController annotationPadding], + [MapViewController annotationPadding]).size; + maxSize.height -= self.navigationController.navigationBar.frame.size.height + [MapViewController calloutHeight]; + if (resizeRect.size.width > maxSize.width) + resizeRect.size = CGSizeMake(maxSize.width, resizeRect.size.height / resizeRect.size.width * maxSize.width); + if (resizeRect.size.height > maxSize.height) + resizeRect.size = CGSizeMake(resizeRect.size.width / resizeRect.size.height * maxSize.height, maxSize.height); + + resizeRect.origin = (CGPoint){0.0f, 0.0f}; + UIGraphicsBeginImageContext(resizeRect.size); + [flagImage drawInRect:resizeRect]; + UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + annotationView.image = resizedImage; + annotationView.opaque = NO; + + UIImageView *sfIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SFIcon.png"]]; + annotationView.leftCalloutAccessoryView = sfIconView; + [sfIconView release]; + + return annotationView; + } + else + { + pinView.annotation = annotation; + } + return pinView; + } + + return nil; +} + +@end diff --git a/MapCallouts/Prefix.pch b/MapCallouts/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/MapCallouts/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/MapCallouts/ReadMe.txt b/MapCallouts/ReadMe.txt new file mode 100644 index 0000000..fe9ad46 --- /dev/null +++ b/MapCallouts/ReadMe.txt @@ -0,0 +1,51 @@ +MapCallouts + +=========================================================================== +ABSTRACT + +Demonstrates the use of the MapKit framework, displaying a map view with custom MKAnnotations each with custom callouts. An annotation object on a map is any object that conforms to the MKAnnotation protocol and is displayed on the screen as a MKAnnotationView. Through the use of the MKAnnotation protocol and MKAnnotationView, this application shows how you can extend annotations with custom strings and left/right calloutAccessoryViews. + +=========================================================================== +DISCUSSION + +This sample implements two different variations of MKPinAnnotationViews each with their own specific information. One shows how to use a rightCalloutAccessoryView with a UIButtonTypeDetailDisclosure button and other with leftCalloutAccessoryView containing an image. + +Important: +The MapKit framework uses Google services to provide map data. Use of this class and the associated interfaces binds you to the Google Maps/Google Earth API terms of service. You can find these terms of service mentioned in the header section of "MKMapView.h". + +=========================================================================== +BUILD REQUIREMENTS + +iOS 4.0 SDK or later + +=========================================================================== +RUNTIME REQUIREMENTS + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST + +AppDelegate +Configures and displays the application window and navigation controller. + +MapViewController +The primary view controller containing the MKMapView, adding and removing both MKPinAnnotationViews through its toolbar. + +BrideAnnotation +The custom MKAnnotation object representing the Golden Gate Bridge. + +SFAnnotation +The custom MKAnnotation object representing the city of San Francisco. + +DetailViewController +The detail view controller used for displaying the Golden Gate Bridge. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS + +1.2 Updated icons and artwork. Upgraded project to build with the iOS 4 SDK. +1.0 Initial version published. + +=========================================================================== +Copyright (C) 2010 Apple Inc. All rights reserved. diff --git a/MapCallouts/SFAnnotation.h b/MapCallouts/SFAnnotation.h new file mode 100755 index 0000000..9f67b1e --- /dev/null +++ b/MapCallouts/SFAnnotation.h @@ -0,0 +1,63 @@ +/* + File: SFAnnotation.h + Abstract: The custom MKAnnotation object representing the city of San Francisco. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface SFAnnotation : NSObject +{ + UIImage *image; + NSNumber *latitude; + NSNumber *longitude; +} + +@property (nonatomic, retain) UIImage *image; +@property (nonatomic, retain) NSNumber *latitude; +@property (nonatomic, retain) NSNumber *longitude; + +@end + + diff --git a/MapCallouts/SFAnnotation.m b/MapCallouts/SFAnnotation.m new file mode 100755 index 0000000..457f590 --- /dev/null +++ b/MapCallouts/SFAnnotation.m @@ -0,0 +1,82 @@ +/* + File: SFAnnotation.m + Abstract: The custom MKAnnotation object representing the city of San Francisco. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SFAnnotation.h" + +@implementation SFAnnotation + +@synthesize image; +@synthesize latitude; +@synthesize longitude; + + +- (CLLocationCoordinate2D)coordinate; +{ + CLLocationCoordinate2D theCoordinate; + theCoordinate.latitude = 37.786996; + theCoordinate.longitude = -122.419281; + return theCoordinate; +} + +- (void)dealloc +{ + [image release]; + [super dealloc]; +} + +- (NSString *)title +{ + return @"San Francisco"; +} + +// optional +- (NSString *)subtitle +{ + return @"Founded: June 29, 1776"; +} + +@end diff --git a/MapCallouts/en.lproj/DetailViewController.xib b/MapCallouts/en.lproj/DetailViewController.xib new file mode 100644 index 0000000..9147903 --- /dev/null +++ b/MapCallouts/en.lproj/DetailViewController.xib @@ -0,0 +1,371 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 460} + + NO + NO + 4 + NO + + NSImage + GoldenGate.png + + + + {320, 460} + + + 3 + MQA + + NO + + + + + YES + + + view + + + + 3 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + 5 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 5.IBPluginDependency + + + YES + DetailViewController + UIResponder + {{0, 535}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 5 + + + + YES + + DetailViewController + UIViewController + + IBProjectSource + DetailViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../MapCallouts.xcodeproj + 3 + 3.1 + + diff --git a/MapCallouts/en.lproj/MainWindow.xib b/MapCallouts/en.lproj/MainWindow.xib new file mode 100644 index 0000000..112c480 --- /dev/null +++ b/MapCallouts/en.lproj/MainWindow.xib @@ -0,0 +1,665 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + 2 + + + + + 256 + {0, 0} + NO + YES + YES + 2 + + + + 256 + {{0, 416}, {320, 44}} + NO + YES + 4 + YES + 2 + + + YES + + + YES + + City + 1 + + + + Bridge + 1 + + + + + 5 + + + All + 1 + + + + + + MapCallouts + + + MapViewController + + + + + NO + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + myNavController + + + + 60 + + + + cityAction: + + + + 74 + + + + bridgeAction: + + + + 75 + + + + allAction: + + + + 76 + + + + + YES + + 0 + + + + + + 2 + + + + + -1 + + + File's Owner + + + 3 + + + AppDelegate + + + -2 + + + + + 55 + + + YES + + + + + + + + 57 + + + + + 65 + + + + + 68 + + + YES + + + + + + + + MapViewController + + + 69 + + + NavigationItem + + + 70 + + + + + 71 + + + + + 72 + + + + + 73 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 55.IBEditorWindowLastContentRect + 55.IBPluginDependency + 55.IBViewEditorWindowController.showingLayoutRectangles + 57.IBPluginDependency + 68.CustomClassName + 68.IBEditorWindowLastContentRect + 68.IBPluginDependency + 70.IBPluginDependency + 71.IBPluginDependency + 72.IBPluginDependency + 73.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{75, 354}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MapViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 76 + + + + YES + + AppDelegate + NSObject + + YES + + YES + myNavController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + DetailViewController + UIViewController + + IBProjectSource + DetailViewController.h + + + + MapViewController + UIViewController + + YES + + YES + allAction: + bridgeAction: + cityAction: + + + YES + id + id + id + + + + YES + + YES + detailViewController + mapView + + + YES + DetailViewController + MKMapView + + + + IBProjectSource + MapViewController.h + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../MapCallouts.xcodeproj + 3 + 3.1 + + diff --git a/MapCallouts/en.lproj/MapViewController.xib b/MapCallouts/en.lproj/MapViewController.xib new file mode 100644 index 0000000..ec094b3 --- /dev/null +++ b/MapCallouts/en.lproj/MapViewController.xib @@ -0,0 +1,525 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 268 + {320, 480} + + NO + YES + 4 + YES + + + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + Golden Gate Bridge + DetailViewController + + + + Bridge + 1 + + + City + 1 + + + Item + 1 + + + + + YES + + + mapView + + + + 25 + + + + delegate + + + + 27 + + + + view + + + + 31 + + + + detailViewController + + + + 32 + + + + allAction: + + + + 39 + + + + cityAction: + + + + 40 + + + + bridgeAction: + + + + 41 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 9 + + + YES + + + + + + 23 + + + + + 29 + + + DetailViewController + + + 33 + + + BridgeButton + + + 34 + + + CityButton + + + 37 + + + AllButton + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 23.IBPluginDependency + 29.CustomClassName + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 33.IBPluginDependency + 34.IBPluginDependency + 37.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + 9.IBViewEditorWindowController.showingLayoutRectangles + + + YES + MapViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DetailViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{191, 485}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + YES + + + YES + + + + + YES + + + YES + + + + 41 + + + + YES + + DetailViewController + UIViewController + + IBProjectSource + DetailViewController.h + + + + MapViewController + UIViewController + + YES + + YES + allAction: + bridgeAction: + cityAction: + + + YES + id + id + id + + + + YES + + YES + detailViewController + mapView + + + YES + DetailViewController + MKMapView + + + + IBProjectSource + MapViewController.h + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../MapCallouts.xcodeproj + 3 + 3.1 + + diff --git a/MapCallouts/iTunesArtwork b/MapCallouts/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/MapCallouts/iTunesArtwork differ diff --git a/MapCallouts/images/Default.png b/MapCallouts/images/Default.png new file mode 100644 index 0000000..8f0f90f Binary files /dev/null and b/MapCallouts/images/Default.png differ diff --git a/MapCallouts/images/GoldenGate.png b/MapCallouts/images/GoldenGate.png new file mode 100644 index 0000000..51cc697 Binary files /dev/null and b/MapCallouts/images/GoldenGate.png differ diff --git a/MapCallouts/images/Icon-72.png b/MapCallouts/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/MapCallouts/images/Icon-72.png differ diff --git a/MapCallouts/images/Icon-Small-50.png b/MapCallouts/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/MapCallouts/images/Icon-Small-50.png differ diff --git a/MapCallouts/images/Icon-Small.png b/MapCallouts/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/MapCallouts/images/Icon-Small.png differ diff --git a/MapCallouts/images/Icon-Small@2x.png b/MapCallouts/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/MapCallouts/images/Icon-Small@2x.png differ diff --git a/MapCallouts/images/Icon.png b/MapCallouts/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/MapCallouts/images/Icon.png differ diff --git a/MapCallouts/images/Icon@2x.png b/MapCallouts/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/MapCallouts/images/Icon@2x.png differ diff --git a/MapCallouts/images/Location.png b/MapCallouts/images/Location.png new file mode 100644 index 0000000..1ccadc6 Binary files /dev/null and b/MapCallouts/images/Location.png differ diff --git a/MapCallouts/images/SFIcon.png b/MapCallouts/images/SFIcon.png new file mode 100644 index 0000000..0ce8381 Binary files /dev/null and b/MapCallouts/images/SFIcon.png differ diff --git a/MapCallouts/images/flag.png b/MapCallouts/images/flag.png new file mode 100644 index 0000000..c93d086 Binary files /dev/null and b/MapCallouts/images/flag.png differ diff --git a/MapCallouts/main.m b/MapCallouts/main.m new file mode 100755 index 0000000..19f0949 --- /dev/null +++ b/MapCallouts/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/MessageComposer.zip b/MessageComposer.zip new file mode 100644 index 0000000..500d147 Binary files /dev/null and b/MessageComposer.zip differ diff --git a/MessageComposer/Classes/MessageComposerAppDelegate.h b/MessageComposer/Classes/MessageComposerAppDelegate.h new file mode 100644 index 0000000..0a47fe2 --- /dev/null +++ b/MessageComposer/Classes/MessageComposerAppDelegate.h @@ -0,0 +1,61 @@ +/* + File: MessageComposerAppDelegate.h + Abstract: Application delegate that sets up a view controller with a button and feedback message label. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class MessageComposerViewController; + +@interface MessageComposerAppDelegate : NSObject { + UIWindow *window; + MessageComposerViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet MessageComposerViewController *viewController; + +@end \ No newline at end of file diff --git a/MessageComposer/Classes/MessageComposerAppDelegate.m b/MessageComposer/Classes/MessageComposerAppDelegate.m new file mode 100644 index 0000000..246e883 --- /dev/null +++ b/MessageComposer/Classes/MessageComposerAppDelegate.m @@ -0,0 +1,73 @@ +/* + File: MessageComposerAppDelegate.m + Abstract: Application delegate that sets up a view controller with a button and feedback message label. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MessageComposerAppDelegate.h" +#import "MessageComposerViewController.h" + +@implementation MessageComposerAppDelegate + +@synthesize window; +@synthesize viewController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // Override point for customization after app launch + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/MessageComposer/Classes/MessageComposerViewController.h b/MessageComposer/Classes/MessageComposerViewController.h new file mode 100644 index 0000000..66e2486 --- /dev/null +++ b/MessageComposer/Classes/MessageComposerViewController.h @@ -0,0 +1,69 @@ +/* + File: MessageComposerViewController.h + Abstract: UIViewController that includes a UIButton and a UILabel. + The button responds to an IBAction that will bring up the MFMessageCOmposeViewController for composing a new SMS text message. The label will show a feedback message of whether the SMS text message has been sent. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import + +@interface MessageComposerViewController : UIViewController { + + IBOutlet UILabel *feedbackMsg; +} + +@property (nonatomic, retain) IBOutlet UILabel *feedbackMsg; + +-(IBAction)showMailPicker:(id)sender; +-(IBAction)showSMSPicker:(id)sender; +-(void)displayMailComposerSheet; +-(void)displaySMSComposerSheet; + + +@end + diff --git a/MessageComposer/Classes/MessageComposerViewController.m b/MessageComposer/Classes/MessageComposerViewController.m new file mode 100644 index 0000000..1344feb --- /dev/null +++ b/MessageComposer/Classes/MessageComposerViewController.m @@ -0,0 +1,237 @@ +/* + File: MessageComposerViewController.m + Abstract: UIViewController that includes a UIButton and a UILabel. + The button responds to an IBAction that will bring up the MFMessageCOmposeViewController for composing a new SMS text message. The label will show a feedback message of whether the SMS text message has been sent. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MessageComposerViewController.h" + +@implementation MessageComposerViewController +@synthesize feedbackMsg; + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [feedbackMsg release]; + [super dealloc]; +} + + +#pragma mark - +#pragma mark Views lifecycle + +- (void)viewDidUnload { + self.feedbackMsg = nil; +} + + +// Support all orientations except for portrait upside-down. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); +} + + +#pragma mark - +#pragma mark Show Mail/SMS picker + +-(IBAction)showMailPicker:(id)sender { + // The MFMailComposeViewController class is only available in iPhone OS 3.0 or later. + // So, we must verify the existence of the above class and provide a workaround for devices running + // earlier versions of the iPhone OS. + // We display an email composition interface if MFMailComposeViewController exists and the device + // can send emails. Display feedback message, otherwise. + Class mailClass = (NSClassFromString(@"MFMailComposeViewController")); + + if (mailClass != nil) { + //[self displayMailComposerSheet]; + // We must always check whether the current device is configured for sending emails + if ([mailClass canSendMail]) { + [self displayMailComposerSheet]; + } + else { + feedbackMsg.hidden = NO; + feedbackMsg.text = @"Device not configured to send mail."; + } + } + else { + feedbackMsg.hidden = NO; + feedbackMsg.text = @"Device not configured to send mail."; + } +} + + +-(IBAction)showSMSPicker:(id)sender { +// The MFMessageComposeViewController class is only available in iPhone OS 4.0 or later. +// So, we must verify the existence of the above class and log an error message for devices +// running earlier versions of the iPhone OS. Set feedbackMsg if device doesn't support +// MFMessageComposeViewController API. + Class messageClass = (NSClassFromString(@"MFMessageComposeViewController")); + + if (messageClass != nil) { + // Check whether the current device is configured for sending SMS messages + if ([messageClass canSendText]) { + [self displaySMSComposerSheet]; + } + else { + feedbackMsg.hidden = NO; + feedbackMsg.text = @"Device not configured to send SMS."; + + } + } + else { + feedbackMsg.hidden = NO; + feedbackMsg.text = @"Device not configured to send SMS."; + } +} + + +#pragma mark - +#pragma mark Compose Mail/SMS + +// Displays an email composition interface inside the application. Populates all the Mail fields. +-(void)displayMailComposerSheet +{ + MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; + picker.mailComposeDelegate = self; + + [picker setSubject:@"Hello from California!"]; + + + // Set up recipients + NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"]; + NSArray *ccRecipients = [NSArray arrayWithObjects:@"second@example.com", @"third@example.com", nil]; + NSArray *bccRecipients = [NSArray arrayWithObject:@"fourth@example.com"]; + + [picker setToRecipients:toRecipients]; + [picker setCcRecipients:ccRecipients]; + [picker setBccRecipients:bccRecipients]; + + // Attach an image to the email + NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"jpg"]; + NSData *myData = [NSData dataWithContentsOfFile:path]; + [picker addAttachmentData:myData mimeType:@"image/jpeg" fileName:@"rainy"]; + + // Fill out the email body text + NSString *emailBody = @"It is raining in sunny California!"; + [picker setMessageBody:emailBody isHTML:NO]; + + [self presentModalViewController:picker animated:YES]; + [picker release]; +} + + +// Displays an SMS composition interface inside the application. +-(void)displaySMSComposerSheet +{ + MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init]; + picker.messageComposeDelegate = self; + + [self presentModalViewController:picker animated:YES]; + [picker release]; +} + + +#pragma mark - +#pragma mark Dismiss Mail/SMS view controller + +// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the +// message field with the result of the operation. +- (void)mailComposeController:(MFMailComposeViewController*)controller + didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { + + feedbackMsg.hidden = NO; + // Notifies users about errors associated with the interface + switch (result) + { + case MFMailComposeResultCancelled: + feedbackMsg.text = @"Result: Mail sending canceled"; + break; + case MFMailComposeResultSaved: + feedbackMsg.text = @"Result: Mail saved"; + break; + case MFMailComposeResultSent: + feedbackMsg.text = @"Result: Mail sent"; + break; + case MFMailComposeResultFailed: + feedbackMsg.text = @"Result: Mail sending failed"; + break; + default: + feedbackMsg.text = @"Result: Mail not sent"; + break; + } + [self dismissModalViewControllerAnimated:YES]; +} + + +// Dismisses the message composition interface when users tap Cancel or Send. Proceeds to update the +// feedback message field with the result of the operation. +- (void)messageComposeViewController:(MFMessageComposeViewController *)controller + didFinishWithResult:(MessageComposeResult)result { + + feedbackMsg.hidden = NO; + // Notifies users about errors associated with the interface + switch (result) + { + case MessageComposeResultCancelled: + feedbackMsg.text = @"Result: SMS sending canceled"; + break; + case MessageComposeResultSent: + feedbackMsg.text = @"Result: SMS sent"; + break; + case MessageComposeResultFailed: + feedbackMsg.text = @"Result: SMS sending failed"; + break; + default: + feedbackMsg.text = @"Result: SMS not sent"; + break; + } + [self dismissModalViewControllerAnimated:YES]; +} + + +@end diff --git a/MessageComposer/Images/Default.png b/MessageComposer/Images/Default.png new file mode 100644 index 0000000..2f56b8e Binary files /dev/null and b/MessageComposer/Images/Default.png differ diff --git a/MessageComposer/Images/Icon-72.png b/MessageComposer/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/MessageComposer/Images/Icon-72.png differ diff --git a/MessageComposer/Images/Icon-Small-50.png b/MessageComposer/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/MessageComposer/Images/Icon-Small-50.png differ diff --git a/MessageComposer/Images/Icon-Small.png b/MessageComposer/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/MessageComposer/Images/Icon-Small.png differ diff --git a/MessageComposer/Images/Icon-Small@2x.png b/MessageComposer/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/MessageComposer/Images/Icon-Small@2x.png differ diff --git a/MessageComposer/Images/Icon.png b/MessageComposer/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/MessageComposer/Images/Icon.png differ diff --git a/MessageComposer/Images/Icon@2x.png b/MessageComposer/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/MessageComposer/Images/Icon@2x.png differ diff --git a/MessageComposer/Images/iTunesArtwork b/MessageComposer/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/MessageComposer/Images/iTunesArtwork differ diff --git a/MessageComposer/Images/rainy.jpg b/MessageComposer/Images/rainy.jpg new file mode 100644 index 0000000..fe62072 Binary files /dev/null and b/MessageComposer/Images/rainy.jpg differ diff --git a/MessageComposer/MessageComposer-Info.plist b/MessageComposer/MessageComposer-Info.plist new file mode 100644 index 0000000..5c65286 --- /dev/null +++ b/MessageComposer/MessageComposer-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/MessageComposer/MessageComposer.xcodeproj/project.pbxproj b/MessageComposer/MessageComposer.xcodeproj/project.pbxproj new file mode 100755 index 0000000..db8707d --- /dev/null +++ b/MessageComposer/MessageComposer.xcodeproj/project.pbxproj @@ -0,0 +1,328 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* MessageComposerAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MessageComposerAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 28D7ACF80DDB3853001CB0EB /* MessageComposerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* MessageComposerViewController.m */; }; + 7E19D3E811D1898D000002E9 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 7E19D3E711D1898D000002E9 /* iTunesArtwork */; }; + 7E311C6811D157E300EB2D81 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C5F11D157E300EB2D81 /* Default.png */; }; + 7E311C6911D157E300EB2D81 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C6011D157E300EB2D81 /* Icon-72.png */; }; + 7E311C6A11D157E300EB2D81 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C6111D157E300EB2D81 /* Icon-Small-50.png */; }; + 7E311C6B11D157E300EB2D81 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C6211D157E300EB2D81 /* Icon-Small.png */; }; + 7E311C6C11D157E300EB2D81 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C6311D157E300EB2D81 /* Icon-Small@2x.png */; }; + 7E311C6D11D157E300EB2D81 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C6411D157E300EB2D81 /* Icon.png */; }; + 7E311C6E11D157E300EB2D81 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E311C6511D157E300EB2D81 /* Icon@2x.png */; }; + 7E5328ED1198CF9900BCC65C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7E5328E91198CF9900BCC65C /* MainWindow.xib */; }; + 7E5328EE1198CF9900BCC65C /* MessageComposerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7E5328EB1198CF9900BCC65C /* MessageComposerViewController.xib */; }; + 7E8EEBBC119764BF0073914C /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E8EEBBB119764BF0073914C /* MessageUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + EDA2139E1278CF9E003F0221 /* rainy.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EDA2139D1278CF9E003F0221 /* rainy.jpg */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* MessageComposerAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageComposerAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* MessageComposerAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageComposerAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* MessageComposer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessageComposer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28D7ACF60DDB3853001CB0EB /* MessageComposerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageComposerViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* MessageComposerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageComposerViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* MessageComposer_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageComposer_Prefix.pch; sourceTree = ""; }; + 7E19D3E711D1898D000002E9 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; + 7E311C5F11D157E300EB2D81 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Images/Default.png; sourceTree = ""; }; + 7E311C6011D157E300EB2D81 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + 7E311C6111D157E300EB2D81 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + 7E311C6211D157E300EB2D81 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + 7E311C6311D157E300EB2D81 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + 7E311C6411D157E300EB2D81 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + 7E311C6511D157E300EB2D81 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + 7E5328EA1198CF9900BCC65C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 7E5328EC1198CF9900BCC65C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MessageComposerViewController.xib; sourceTree = ""; }; + 7E8EEBBB119764BF0073914C /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; + 8D1107310486CEB800E47090 /* MessageComposer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MessageComposer-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + EDA2139D1278CF9E003F0221 /* rainy.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = rainy.jpg; path = Images/rainy.jpg; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 7E8EEBBC119764BF0073914C /* MessageUI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* MessageComposerAppDelegate.h */, + 1D3623250D0F684500981E51 /* MessageComposerAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* MessageComposerViewController.h */, + 28D7ACF70DDB3853001CB0EB /* MessageComposerViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MessageComposer.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* MessageComposer_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 7E311C5D11D157D600EB2D81 /* Images */, + 7E5328E91198CF9900BCC65C /* MainWindow.xib */, + 7E5328EB1198CF9900BCC65C /* MessageComposerViewController.xib */, + 8D1107310486CEB800E47090 /* MessageComposer-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7E8EEBBB119764BF0073914C /* MessageUI.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7E311C5D11D157D600EB2D81 /* Images */ = { + isa = PBXGroup; + children = ( + 7E19D3E711D1898D000002E9 /* iTunesArtwork */, + 7E311C5F11D157E300EB2D81 /* Default.png */, + 7E311C6011D157E300EB2D81 /* Icon-72.png */, + 7E311C6111D157E300EB2D81 /* Icon-Small-50.png */, + 7E311C6211D157E300EB2D81 /* Icon-Small.png */, + 7E311C6311D157E300EB2D81 /* Icon-Small@2x.png */, + 7E311C6411D157E300EB2D81 /* Icon.png */, + 7E311C6511D157E300EB2D81 /* Icon@2x.png */, + EDA2139D1278CF9E003F0221 /* rainy.jpg */, + ); + name = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MessageComposer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MessageComposer" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MessageComposer; + productName = MessageComposer; + productReference = 1D6058910D05DD3D006BFB54 /* MessageComposer.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MessageComposer" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MessageComposer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7E5328ED1198CF9900BCC65C /* MainWindow.xib in Resources */, + 7E5328EE1198CF9900BCC65C /* MessageComposerViewController.xib in Resources */, + 7E311C6811D157E300EB2D81 /* Default.png in Resources */, + 7E311C6911D157E300EB2D81 /* Icon-72.png in Resources */, + 7E311C6A11D157E300EB2D81 /* Icon-Small-50.png in Resources */, + 7E311C6B11D157E300EB2D81 /* Icon-Small.png in Resources */, + 7E311C6C11D157E300EB2D81 /* Icon-Small@2x.png in Resources */, + 7E311C6D11D157E300EB2D81 /* Icon.png in Resources */, + 7E311C6E11D157E300EB2D81 /* Icon@2x.png in Resources */, + 7E19D3E811D1898D000002E9 /* iTunesArtwork in Resources */, + EDA2139E1278CF9E003F0221 /* rainy.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* MessageComposerAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* MessageComposerViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 7E5328E91198CF9900BCC65C /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 7E5328EA1198CF9900BCC65C /* en */, + ); + name = MainWindow.xib; + sourceTree = SOURCE_ROOT; + }; + 7E5328EB1198CF9900BCC65C /* MessageComposerViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 7E5328EC1198CF9900BCC65C /* en */, + ); + name = MessageComposerViewController.xib; + sourceTree = SOURCE_ROOT; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MessageComposer_Prefix.pch; + INFOPLIST_FILE = "MessageComposer-Info.plist"; + PRODUCT_NAME = MessageComposer; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MessageComposer_Prefix.pch; + INFOPLIST_FILE = "MessageComposer-Info.plist"; + PRODUCT_NAME = MessageComposer; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MessageComposer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MessageComposer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MessageComposer/MessageComposer_Prefix.pch b/MessageComposer/MessageComposer_Prefix.pch new file mode 100644 index 0000000..6094e7d --- /dev/null +++ b/MessageComposer/MessageComposer_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'MessageComposer' target in the 'MessageComposer' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/MessageComposer/ReadMe.txt b/MessageComposer/ReadMe.txt new file mode 100644 index 0000000..df92a60 --- /dev/null +++ b/MessageComposer/ReadMe.txt @@ -0,0 +1,104 @@ +### MessageComposer ### + +================================================================================ +DESCRIPTION: + +MessageComposer demonstrates how to target older OS versions while building +with newly released APIs. It also illustrates how to use the MessageUI framework to compose and send email and SMS messages from within your application. +This application uses the MFMailComposeViewController and MFMessageComposeViewController classes of the MessageUI framework, which were respectively introduced in iPhone SDK 3.0 and iPhone SDK 4.0. These two classes manage user interfaces that allows users to compose and send email and SMS messages from within their applications, respectively. + +MessageComposer displays two buttons labeled "Compose Mail" and "Compose SMS." +When users tap on "Compose Mail" and "Compose SMS," the application respectively shows an email composition interface and an SMS composition interface. +The application shows either of these composition interfaces if their respective classes exist and the device is configured for sending email or SMS. It provides a feedback message, otherwise. + +MessageComposer runs on earlier and later releases of the iOS and uses +new APIs introduced in iPhone SDK 4.0. See below for steps that describe how to target earlier 0S versions while building with newly released APIs. + + +1. Set your iOS Deployment Target setting to your application's target +iOS release +This setting indicates the earliest iOS on which your application can +run. We set it to iOS 3.0. + + +2. Set the Base SDK to the desired iPhone SDK +This setting indicates what release of the iPhone SDK will be used to build +your application. We set it to iPhone SDK 3.0 in order to take advantage of all +the features of the new MessageUI framework. + + +3. Make MessageUI a weak framework (set its role to Weak) +An application will fail to launch or proceed if it attempts to load a +framework on devices where this framework is absent. +With weak linking, an application does not fail, but proceeds when a symbol or +framework is not present at runtime. All weak-linked symbols are set to NULL on +devices without them. + +To designate MessageUI as weak-linked, select the target's Link Binary With +Libraries build phase, then change MessageUI's role from Required to Weak in the +detail view. + + +4. Check for the existence of APIs before calling them +MessageComposer will crash if it attempts to use non-existent weak-linked symbols. +The showPicker method checks whether +MFMailComposeViewController/MFMessageComposeViewController exists (is non-NULL) +before using it. + + +5. Provide a workaround for non-existent APIs +If MFMailComposeViewController/MFMessageComposeViewController does not exist, +it shows a feedback message informing that the device is not configured to send +email or SMS. + + +Further Reading +Running Applications section of the iPhone Development Guide + + + +Frameworks and Weak Linking + + +================================================================================ +BUILD REQUIREMENTS: + +Mac OS X 10.6 or later, Xcode 3.2 or later, iOS 4.1 + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.0 or later + +Using the Sample +Build and run the sample using Xcode 3.2 or later. +Tap the "Compose Mail" button to display an email composition interface if your device is running iOS 3.0; tap the "Compose SMS" button to display an SMS composition interface if your device is running iOS 4.0. Otherwise display feedback message. + +================================================================================ +PACKAGING LIST: + +Application Configuration +------------------------- + +MessageComposerAppDelegate.{h,m} +MainWindow.xib +Application delegate that sets up a UIViewController with two UIButton's and a +UILabel. + + +View Controllers +------------------------ + +MessageComposerViewController.{h,m} +MessageComposerViewController.xib +UIViewController that includes two UIButton's and a UILabel. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: +Version 1.1 +- Changed the rainy.png image into JPEG format, because PNG-optimization made it unreadable on some platforms when sent as an attachment. +Version 1.0 +- First version (Formerly known as MailComposer). + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/MessageComposer/en.lproj/MainWindow.xib b/MessageComposer/en.lproj/MainWindow.xib new file mode 100644 index 0000000..4bd3bf0 --- /dev/null +++ b/MessageComposer/en.lproj/MainWindow.xib @@ -0,0 +1,488 @@ + + + + 1024 + 10D573 + 783 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 107 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + MessageComposerViewController + + + 1 + + IBCocoaTouchFramework + NO + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + IBCocoaTouchFramework + YES + YES + + + + + YES + + + delegate + + + + 18 + + + + viewController + + + + 19 + + + + window + + + + 20 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + MessageComposerAppDelegate + + + -2 + + + + + 10 + + + MessageComposerViewController + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + MessageComposerViewController + {{587, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MessageComposerAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 20 + + + + YES + + MessageComposerAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + MessageComposerViewController + UIWindow + + + + YES + + YES + viewController + window + + + YES + + viewController + MessageComposerViewController + + + window + UIWindow + + + + + IBProjectSource + Classes/MessageComposerAppDelegate.h + + + + MessageComposerViewController + UIViewController + + YES + + YES + showMailPicker: + showSMSPicker: + + + YES + id + id + + + + YES + + YES + showMailPicker: + showSMSPicker: + + + YES + + showMailPicker: + id + + + showSMSPicker: + id + + + + + feedbackMsg + UILabel + + + feedbackMsg + + feedbackMsg + UILabel + + + + IBProjectSource + Classes/MessageComposerViewController.h + + + + UIWindow + UIView + + IBUserSource + + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../MessageComposer.xcodeproj + 3 + 107 + + diff --git a/MessageComposer/en.lproj/MessageComposerViewController.xib b/MessageComposer/en.lproj/MessageComposerViewController.xib new file mode 100644 index 0000000..1a47de3 --- /dev/null +++ b/MessageComposer/en.lproj/MessageComposerViewController.xib @@ -0,0 +1,523 @@ + + + + 1024 + 10D573 + 785 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 110 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 292 + {{20, 197}, {135, 37}} + + NO + NO + IBCocoaTouchFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + Compose Mail + + 1 + MSAxIDEAA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MAA + + + + + 292 + {{163, 197}, {137, 37}} + + NO + NO + IBCocoaTouchFramework + 0 + 0 + + 1 + Compose SMS + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + -2147483356 + {{20, 269}, {280, 117}} + + NO + YES + NO + IBCocoaTouchFramework + Error + + Helvetica + 15 + 16 + + + 1 + MCAwIDAAA + + + 1 + 10 + 7 + 1 + + + {320, 460} + + + 3 + MC43NQA + + 2 + + + NO + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 7 + + + + feedbackMsg + + + + 11 + + + + showMailPicker: + + + 7 + + 18 + + + + showSMSPicker: + + + 7 + + 19 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + YES + + + + + + + + 8 + + + + + 9 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 12.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + MsgWriterViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{163, 33}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 19 + + + + YES + + MsgWriterViewController + UIViewController + + YES + + YES + showMailPicker: + showSMSPicker: + + + YES + id + id + + + + YES + + YES + showMailPicker: + showSMSPicker: + + + YES + + showMailPicker: + id + + + showSMSPicker: + id + + + + + feedbackMsg + UILabel + + + feedbackMsg + + feedbackMsg + UILabel + + + + IBProjectSource + Classes/MsgWriterViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../MsgWriter.xcodeproj + 3 + 110 + + diff --git a/MessageComposer/main.m b/MessageComposer/main.m new file mode 100644 index 0000000..c06d3d3 --- /dev/null +++ b/MessageComposer/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Default main.m + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/MixerHost.zip b/MixerHost.zip new file mode 100644 index 0000000..2dc0b91 Binary files /dev/null and b/MixerHost.zip differ diff --git a/MixerHost/Classes/MixerHostAppDelegate.h b/MixerHost/Classes/MixerHostAppDelegate.h new file mode 100644 index 0000000..7554aa3 --- /dev/null +++ b/MixerHost/Classes/MixerHostAppDelegate.h @@ -0,0 +1,62 @@ +/* + File: MixerHostAppDelegate.h +Abstract: Application delegate. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class MixerHostViewController; + +@interface MixerHostAppDelegate : NSObject { + + UIWindow *window; + MixerHostViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet MixerHostViewController *viewController; + +@end + diff --git a/MixerHost/Classes/MixerHostAppDelegate.m b/MixerHost/Classes/MixerHostAppDelegate.m new file mode 100644 index 0000000..a0178f0 --- /dev/null +++ b/MixerHost/Classes/MixerHostAppDelegate.m @@ -0,0 +1,128 @@ +/* + File: MixerHostAppDelegate.m +Abstract: Application delegate. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import "MixerHostAppDelegate.h" +#import "MixerHostViewController.h" + +@implementation MixerHostAppDelegate + +@synthesize window; +@synthesize viewController; + + +- (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) options { + + // The status bar is hidden for this app through the "Status bar is initially hidden" key + // in the MixerHost-Info.plist file. + + [window addSubview: viewController.view]; + [window makeKeyAndVisible]; + + return YES; +} + + +// This app doesn't need to do anything special during these transitions. The method stubs are left here +// for your use if you extend this app. +- (void) applicationWillResignActive: (UIApplication *) application { + /* + Sent when the application is about to move from active to inactive state. This can occur for certain types + of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the + application and it begins the transition to the background state. + + Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games + should use this method to pause the game. + */ +} + + +- (void) applicationDidEnterBackground: (UIApplication *) application { + /* + Use this method to release shared resources, save user data, invalidate timers, and store enough application + state information to restore your application to its current state in case it is terminated later. + + If your application supports background execution, called instead of applicationWillTerminate: when the user + quits. + */ +} + + +- (void) applicationWillEnterForeground: (UIApplication *) application { + /* + Called as part of transition from the background to the inactive state: here you can undo many of the + changes made on entering the background. + */ +} + + +- (void) applicationDidBecomeActive: (UIApplication *) application { + /* + Restart any tasks that were paused (or not yet started) while the application was inactive. If the + application was previously in the background, optionally refresh the user interface. + */ +} + + +- (void) applicationWillTerminate: (UIApplication *) application { + /* + Called when the application is about to terminate. + + See also applicationDidEnterBackground:. + */ +} + + +- (void) dealloc { + + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/MixerHost/Classes/MixerHostAudio.h b/MixerHost/Classes/MixerHostAudio.h new file mode 100644 index 0000000..67faca2 --- /dev/null +++ b/MixerHost/Classes/MixerHostAudio.h @@ -0,0 +1,109 @@ +/* + File: MixerHostAudio.h +Abstract: Audio object: Handles all audio tasks for the application. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import +#import + +#define NUM_FILES 2 + +// Data structure for mono or stereo sound, to pass to the application's render callback function, +// which gets invoked by a Mixer unit input bus when it needs more audio to play. +typedef struct { + + BOOL isStereo; // set to true if there is data in the audioDataRight member + UInt32 frameCount; // the total number of frames in the audio data + UInt32 sampleNumber; // the next audio sample to play + AudioUnitSampleType *audioDataLeft; // the complete left (or mono) channel of audio data read from an audio file + AudioUnitSampleType *audioDataRight; // the complete right channel of audio data read from an audio file + +} soundStruct, *soundStructPtr; + +@interface MixerHostAudio : NSObject { + + Float64 graphSampleRate; + CFURLRef sourceURLArray[NUM_FILES]; + soundStruct soundStructArray[NUM_FILES]; + + // Before using an AudioStreamBasicDescription struct you must initialize it to 0. However, because these ASBDs + // are declared in external storage, they are automatically initialized to 0. + AudioStreamBasicDescription stereoStreamFormat; + AudioStreamBasicDescription monoStreamFormat; + AUGraph processingGraph; + BOOL playing; + BOOL interruptedDuringPlayback; + AudioUnit mixerUnit; +} + +@property (readwrite) AudioStreamBasicDescription stereoStreamFormat; +@property (readwrite) AudioStreamBasicDescription monoStreamFormat; +@property (readwrite) Float64 graphSampleRate; +@property (getter = isPlaying) BOOL playing; +@property BOOL interruptedDuringPlayback; +@property AudioUnit mixerUnit; + +- (void) obtainSoundFileURLs; +- (void) setupAudioSession; +- (void) setupStereoStreamFormat; +- (void) setupMonoStreamFormat; + +- (void) readAudioFilesIntoMemory; + +- (void) configureAndInitializeAudioProcessingGraph; +- (void) startAUGraph; +- (void) stopAUGraph; + +- (void) enableMixerInput: (UInt32) inputBus isOn: (AudioUnitParameterValue) isONValue; +- (void) setMixerInput: (UInt32) inputBus gain: (AudioUnitParameterValue) inputGain; +- (void) setMixerOutputGain: (AudioUnitParameterValue) outputGain; + +- (void) printASBD: (AudioStreamBasicDescription) asbd; +- (void) printErrorMessage: (NSString *) errorString withStatus: (OSStatus) result; + +@end + + diff --git a/MixerHost/Classes/MixerHostAudio.m b/MixerHost/Classes/MixerHostAudio.m new file mode 100644 index 0000000..e233663 --- /dev/null +++ b/MixerHost/Classes/MixerHostAudio.m @@ -0,0 +1,971 @@ +/* + File: MixerHostAudio.m +Abstract: Audio object: Handles all audio tasks for the application. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import "MixerHostAudio.h" + +#pragma mark Mixer input bus render callback + +// This callback is invoked each time a Multichannel Mixer unit input bus requires more audio +// samples. In this app, the mixer unit has two input buses. Each of them has its own render +// callback function and its own interleaved audio data buffer to read from. +// +// This callback is written for an inRefCon parameter that can point to two noninterleaved +// buffers (for a stereo sound) or to one mono buffer (for a mono sound). +// +// Audio unit input render callbacks are invoked on a realtime priority thread (the highest +// priority on the system). To work well, to not make the system unresponsive, and to avoid +// audio artifacts, a render callback must not: +// +// * allocate memory +// * access the file system or a network connection +// * take locks +// * waste time +// +// In addition, it's usually best to avoid sending Objective-C messages in a render callback. +// +// Declared as AURenderCallback in AudioUnit/AUComponent.h. See Audio Unit Component Services Reference. +static OSStatus inputRenderCallback ( + + void *inRefCon, // A pointer to a struct containing the complete audio data + // to play, as well as state information such as the + // first sample to play on this invocation of the callback. + AudioUnitRenderActionFlags *ioActionFlags, // Unused here. When generating audio, use ioActionFlags to indicate silence + // between sounds; for silence, also memset the ioData buffers to 0. + const AudioTimeStamp *inTimeStamp, // Unused here. + UInt32 inBusNumber, // The mixer unit input bus that is requesting some new + // frames of audio data to play. + UInt32 inNumberFrames, // The number of frames of audio to provide to the buffer(s) + // pointed to by the ioData parameter. + AudioBufferList *ioData // On output, the audio data to play. The callback's primary + // responsibility is to fill the buffer(s) in the + // AudioBufferList. +) { + + soundStructPtr soundStructPointerArray = (soundStructPtr) inRefCon; + UInt32 frameTotalForSound = soundStructPointerArray[inBusNumber].frameCount; + BOOL isStereo = soundStructPointerArray[inBusNumber].isStereo; + + // Declare variables to point to the audio buffers. Their data type must match the buffer data type. + AudioUnitSampleType *dataInLeft; + AudioUnitSampleType *dataInRight; + + dataInLeft = soundStructPointerArray[inBusNumber].audioDataLeft; + if (isStereo) dataInRight = soundStructPointerArray[inBusNumber].audioDataRight; + + // Establish pointers to the memory into which the audio from the buffers should go. This reflects + // the fact that each Multichannel Mixer unit input bus has two channels, as specified by this app's + // graphStreamFormat variable. + AudioUnitSampleType *outSamplesChannelLeft; + AudioUnitSampleType *outSamplesChannelRight; + + outSamplesChannelLeft = (AudioUnitSampleType *) ioData->mBuffers[0].mData; + if (isStereo) outSamplesChannelRight = (AudioUnitSampleType *) ioData->mBuffers[1].mData; + + // Get the sample number, as an index into the sound stored in memory, + // to start reading data from. + UInt32 sampleNumber = soundStructPointerArray[inBusNumber].sampleNumber; + + // Fill the buffer or buffers pointed at by *ioData with the requested number of samples + // of audio from the sound stored in memory. + for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) { + + outSamplesChannelLeft[frameNumber] = dataInLeft[sampleNumber]; + if (isStereo) outSamplesChannelRight[frameNumber] = dataInRight[sampleNumber]; + + sampleNumber++; + + // After reaching the end of the sound stored in memory--that is, after + // (frameTotalForSound / inNumberFrames) invocations of this callback--loop back to the + // start of the sound so playback resumes from there. + if (sampleNumber >= frameTotalForSound) sampleNumber = 0; + } + + // Update the stored sample number so, the next time this callback is invoked, playback resumes + // at the correct spot. + soundStructPointerArray[inBusNumber].sampleNumber = sampleNumber; + + return noErr; +} + +#pragma mark - +#pragma mark Audio route change listener callback + +// Audio session callback function for responding to audio route changes. If playing back audio and +// the user unplugs a headset or headphones, or removes the device from a dock connector for hardware +// that supports audio playback, this callback detects that and stops playback. +// +// Refer to AudioSessionPropertyListener in Audio Session Services Reference. +void audioRouteChangeListenerCallback ( + void *inUserData, + AudioSessionPropertyID inPropertyID, + UInt32 inPropertyValueSize, + const void *inPropertyValue +) { + + // Ensure that this callback was invoked because of an audio route change + if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; + + // This callback, being outside the implementation block, needs a reference to the MixerHostAudio + // object, which it receives in the inUserData parameter. You provide this reference when + // registering this callback (see the call to AudioSessionAddPropertyListener). + MixerHostAudio *audioObject = (MixerHostAudio *) inUserData; + + // if application sound is not playing, there's nothing to do, so return. + if (NO == audioObject.isPlaying) { + + NSLog (@"Audio route change while application audio is stopped."); + return; + + } else { + + // Determine the specific type of audio route change that occurred. + CFDictionaryRef routeChangeDictionary = inPropertyValue; + + CFNumberRef routeChangeReasonRef = + CFDictionaryGetValue ( + routeChangeDictionary, + CFSTR (kAudioSession_AudioRouteChangeKey_Reason) + ); + + SInt32 routeChangeReason; + + CFNumberGetValue ( + routeChangeReasonRef, + kCFNumberSInt32Type, + &routeChangeReason + ); + + // "Old device unavailable" indicates that a headset or headphones were unplugged, or that + // the device was removed from a dock connector that supports audio output. In such a case, + // pause or stop audio (as advised by the iOS Human Interface Guidelines). + if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) { + + NSLog (@"Audio output device was removed; stopping audio playback."); + NSString *MixerHostAudioObjectPlaybackStateDidChangeNotification = @"MixerHostAudioObjectPlaybackStateDidChangeNotification"; + [[NSNotificationCenter defaultCenter] postNotificationName: MixerHostAudioObjectPlaybackStateDidChangeNotification object: audioObject]; + + } else { + + NSLog (@"A route change occurred that does not require stopping application audio."); + } + } +} + + +#pragma mark - +@implementation MixerHostAudio + +@synthesize stereoStreamFormat; // stereo format for use in buffer and mixer input for "guitar" sound +@synthesize monoStreamFormat; // mono format for use in buffer and mixer input for "beats" sound +@synthesize graphSampleRate; // sample rate to use throughout audio processing chain +@synthesize mixerUnit; // the Multichannel Mixer unit +@synthesize playing; // Boolean flag to indicate whether audio is playing or not +@synthesize interruptedDuringPlayback; // Boolean flag to indicate whether audio was playing when an interruption arrived + +#pragma mark - +#pragma mark Initialize + +// Get the app ready for playback. +- (id) init { + + self = [super init]; + + if (!self) return nil; + + self.interruptedDuringPlayback = NO; + + [self setupAudioSession]; + [self obtainSoundFileURLs]; + [self setupStereoStreamFormat]; + [self setupMonoStreamFormat]; + [self readAudioFilesIntoMemory]; + [self configureAndInitializeAudioProcessingGraph]; + + return self; +} + + +#pragma mark - +#pragma mark Audio set up + +- (void) setupAudioSession { + + AVAudioSession *mySession = [AVAudioSession sharedInstance]; + + // Specify that this object is the delegate of the audio session, so that + // this object's endInterruption method will be invoked when needed. + [mySession setDelegate: self]; + + // Assign the Playback category to the audio session. + NSError *audioSessionError = nil; + [mySession setCategory: AVAudioSessionCategoryPlayback + error: &audioSessionError]; + + if (audioSessionError != nil) { + + NSLog (@"Error setting audio session category."); + return; + } + + // Request the desired hardware sample rate. + self.graphSampleRate = 44100.0; // Hertz + + [mySession setPreferredHardwareSampleRate: graphSampleRate + error: &audioSessionError]; + + if (audioSessionError != nil) { + + NSLog (@"Error setting preferred hardware sample rate."); + return; + } + + // Activate the audio session + [mySession setActive: YES + error: &audioSessionError]; + + if (audioSessionError != nil) { + + NSLog (@"Error activating audio session during initial setup."); + return; + } + + // Obtain the actual hardware sample rate and store it for later use in the audio processing graph. + self.graphSampleRate = [mySession currentHardwareSampleRate]; + + // Register the audio route change listener callback function with the audio session. + AudioSessionAddPropertyListener ( + kAudioSessionProperty_AudioRouteChange, + audioRouteChangeListenerCallback, + self + ); +} + + +- (void) obtainSoundFileURLs { + + // Create the URLs for the source audio files. The URLForResource:withExtension: method is new in iOS 4.0. + NSURL *guitarLoop = [[NSBundle mainBundle] URLForResource: @"guitarStereo" + withExtension: @"caf"]; + + NSURL *beatsLoop = [[NSBundle mainBundle] URLForResource: @"beatsMono" + withExtension: @"caf"]; + + // ExtAudioFileRef objects expect CFURLRef URLs, so cast to CRURLRef here + sourceURLArray[0] = (CFURLRef) [guitarLoop retain]; + sourceURLArray[1] = (CFURLRef) [beatsLoop retain]; +} + + +- (void) setupStereoStreamFormat { + + // The AudioUnitSampleType data type is the recommended type for sample data in audio + // units. This obtains the byte size of the type for use in filling in the ASBD. + size_t bytesPerSample = sizeof (AudioUnitSampleType); + + // Fill the application audio format struct's fields to define a linear PCM, + // stereo, noninterleaved stream at the hardware sample rate. + stereoStreamFormat.mFormatID = kAudioFormatLinearPCM; + stereoStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; + stereoStreamFormat.mBytesPerPacket = bytesPerSample; + stereoStreamFormat.mFramesPerPacket = 1; + stereoStreamFormat.mBytesPerFrame = bytesPerSample; + stereoStreamFormat.mChannelsPerFrame = 2; // 2 indicates stereo + stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample; + stereoStreamFormat.mSampleRate = graphSampleRate; + + + NSLog (@"The stereo stream format for the \"guitar\" mixer input bus:"); + [self printASBD: stereoStreamFormat]; +} + + +- (void) setupMonoStreamFormat { + + // The AudioUnitSampleType data type is the recommended type for sample data in audio + // units. This obtains the byte size of the type for use in filling in the ASBD. + size_t bytesPerSample = sizeof (AudioUnitSampleType); + + // Fill the application audio format struct's fields to define a linear PCM, + // stereo, noninterleaved stream at the hardware sample rate. + monoStreamFormat.mFormatID = kAudioFormatLinearPCM; + monoStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; + monoStreamFormat.mBytesPerPacket = bytesPerSample; + monoStreamFormat.mFramesPerPacket = 1; + monoStreamFormat.mBytesPerFrame = bytesPerSample; + monoStreamFormat.mChannelsPerFrame = 1; // 1 indicates mono + monoStreamFormat.mBitsPerChannel = 8 * bytesPerSample; + monoStreamFormat.mSampleRate = graphSampleRate; + + NSLog (@"The mono stream format for the \"beats\" mixer input bus:"); + [self printASBD: monoStreamFormat]; + +} + + +#pragma mark - +#pragma mark Read audio files into memory + +- (void) readAudioFilesIntoMemory { + + for (int audioFile = 0; audioFile < NUM_FILES; ++audioFile) { + + NSLog (@"readAudioFilesIntoMemory - file %i", audioFile); + + // Instantiate an extended audio file object. + ExtAudioFileRef audioFileObject = 0; + + // Open an audio file and associate it with the extended audio file object. + OSStatus result = ExtAudioFileOpenURL (sourceURLArray[audioFile], &audioFileObject); + + if (noErr != result || NULL == audioFileObject) {[self printErrorMessage: @"ExtAudioFileOpenURL" withStatus: result]; return;} + + // Get the audio file's length in frames. + UInt64 totalFramesInFile = 0; + UInt32 frameLengthPropertySize = sizeof (totalFramesInFile); + + result = ExtAudioFileGetProperty ( + audioFileObject, + kExtAudioFileProperty_FileLengthFrames, + &frameLengthPropertySize, + &totalFramesInFile + ); + + if (noErr != result) {[self printErrorMessage: @"ExtAudioFileGetProperty (audio file length in frames)" withStatus: result]; return;} + + // Assign the frame count to the soundStructArray instance variable + soundStructArray[audioFile].frameCount = totalFramesInFile; + + // Get the audio file's number of channels. + AudioStreamBasicDescription fileAudioFormat = {0}; + UInt32 formatPropertySize = sizeof (fileAudioFormat); + + result = ExtAudioFileGetProperty ( + audioFileObject, + kExtAudioFileProperty_FileDataFormat, + &formatPropertySize, + &fileAudioFormat + ); + + if (noErr != result) {[self printErrorMessage: @"ExtAudioFileGetProperty (file audio format)" withStatus: result]; return;} + + UInt32 channelCount = fileAudioFormat.mChannelsPerFrame; + + // Allocate memory in the soundStructArray instance variable to hold the left channel, + // or mono, audio data + soundStructArray[audioFile].audioDataLeft = + (AudioUnitSampleType *) calloc (totalFramesInFile, sizeof (AudioUnitSampleType)); + + AudioStreamBasicDescription importFormat = {0}; + if (2 == channelCount) { + + soundStructArray[audioFile].isStereo = YES; + // Sound is stereo, so allocate memory in the soundStructArray instance variable to + // hold the right channel audio data + soundStructArray[audioFile].audioDataRight = + (AudioUnitSampleType *) calloc (totalFramesInFile, sizeof (AudioUnitSampleType)); + importFormat = stereoStreamFormat; + + } else if (1 == channelCount) { + + soundStructArray[audioFile].isStereo = NO; + importFormat = monoStreamFormat; + + } else { + + NSLog (@"*** WARNING: File format not supported - wrong number of channels"); + ExtAudioFileDispose (audioFileObject); + return; + } + + // Assign the appropriate mixer input bus stream data format to the extended audio + // file object. This is the format used for the audio data placed into the audio + // buffer in the SoundStruct data structure, which is in turn used in the + // inputRenderCallback callback function. + + result = ExtAudioFileSetProperty ( + audioFileObject, + kExtAudioFileProperty_ClientDataFormat, + sizeof (importFormat), + &importFormat + ); + + if (noErr != result) {[self printErrorMessage: @"ExtAudioFileSetProperty (client data format)" withStatus: result]; return;} + + // Set up an AudioBufferList struct, which has two roles: + // + // 1. It gives the ExtAudioFileRead function the configuration it + // needs to correctly provide the data to the buffer. + // + // 2. It points to the soundStructArray[audioFile].audioDataLeft buffer, so + // that audio data obtained from disk using the ExtAudioFileRead function + // goes to that buffer + + // Allocate memory for the buffer list struct according to the number of + // channels it represents. + AudioBufferList *bufferList; + + bufferList = (AudioBufferList *) malloc ( + sizeof (AudioBufferList) + sizeof (AudioBuffer) * (channelCount - 1) + ); + + if (NULL == bufferList) {NSLog (@"*** malloc failure for allocating bufferList memory"); return;} + + // initialize the mNumberBuffers member + bufferList->mNumberBuffers = channelCount; + + // initialize the mBuffers member to 0 + AudioBuffer emptyBuffer = {0}; + size_t arrayIndex; + for (arrayIndex = 0; arrayIndex < channelCount; arrayIndex++) { + bufferList->mBuffers[arrayIndex] = emptyBuffer; + } + + // set up the AudioBuffer structs in the buffer list + bufferList->mBuffers[0].mNumberChannels = 1; + bufferList->mBuffers[0].mDataByteSize = totalFramesInFile * sizeof (AudioUnitSampleType); + bufferList->mBuffers[0].mData = soundStructArray[audioFile].audioDataLeft; + + if (2 == channelCount) { + bufferList->mBuffers[1].mNumberChannels = 1; + bufferList->mBuffers[1].mDataByteSize = totalFramesInFile * sizeof (AudioUnitSampleType); + bufferList->mBuffers[1].mData = soundStructArray[audioFile].audioDataRight; + } + + // Perform a synchronous, sequential read of the audio data out of the file and + // into the soundStructArray[audioFile].audioDataLeft and (if stereo) .audioDataRight members. + UInt32 numberOfPacketsToRead = (UInt32) totalFramesInFile; + + result = ExtAudioFileRead ( + audioFileObject, + &numberOfPacketsToRead, + bufferList + ); + + free (bufferList); + + if (noErr != result) { + + [self printErrorMessage: @"ExtAudioFileRead failure - " withStatus: result]; + + // If reading from the file failed, then free the memory for the sound buffer. + free (soundStructArray[audioFile].audioDataLeft); + soundStructArray[audioFile].audioDataLeft = 0; + + if (2 == channelCount) { + free (soundStructArray[audioFile].audioDataRight); + soundStructArray[audioFile].audioDataRight = 0; + } + + ExtAudioFileDispose (audioFileObject); + return; + } + + NSLog (@"Finished reading file %i into memory", audioFile); + + // Set the sample index to zero, so that playback starts at the + // beginning of the sound. + soundStructArray[audioFile].sampleNumber = 0; + + // Dispose of the extended audio file object, which also + // closes the associated file. + ExtAudioFileDispose (audioFileObject); + } +} + + +#pragma mark - +#pragma mark Audio processing graph setup + +// This method performs all the work needed to set up the audio processing graph: + + // 1. Instantiate and open an audio processing graph + // 2. Obtain the audio unit nodes for the graph + // 3. Configure the Multichannel Mixer unit + // * specify the number of input buses + // * specify the output sample rate + // * specify the maximum frames-per-slice + // 4. Initialize the audio processing graph + +- (void) configureAndInitializeAudioProcessingGraph { + + NSLog (@"Configuring and then initializing audio processing graph"); + OSStatus result = noErr; + +//............................................................................ +// Create a new audio processing graph. + result = NewAUGraph (&processingGraph); + + if (noErr != result) {[self printErrorMessage: @"NewAUGraph" withStatus: result]; return;} + + +//............................................................................ +// Specify the audio unit component descriptions for the audio units to be +// added to the graph. + + // I/O unit + AudioComponentDescription iOUnitDescription; + iOUnitDescription.componentType = kAudioUnitType_Output; + iOUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO; + iOUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple; + iOUnitDescription.componentFlags = 0; + iOUnitDescription.componentFlagsMask = 0; + + // Multichannel mixer unit + AudioComponentDescription MixerUnitDescription; + MixerUnitDescription.componentType = kAudioUnitType_Mixer; + MixerUnitDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer; + MixerUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple; + MixerUnitDescription.componentFlags = 0; + MixerUnitDescription.componentFlagsMask = 0; + + +//............................................................................ +// Add nodes to the audio processing graph. + NSLog (@"Adding nodes to audio processing graph"); + + AUNode iONode; // node for I/O unit + AUNode mixerNode; // node for Multichannel Mixer unit + + // Add the nodes to the audio processing graph + result = AUGraphAddNode ( + processingGraph, + &iOUnitDescription, + &iONode); + + if (noErr != result) {[self printErrorMessage: @"AUGraphNewNode failed for I/O unit" withStatus: result]; return;} + + + result = AUGraphAddNode ( + processingGraph, + &MixerUnitDescription, + &mixerNode + ); + + if (noErr != result) {[self printErrorMessage: @"AUGraphNewNode failed for Mixer unit" withStatus: result]; return;} + + +//............................................................................ +// Open the audio processing graph + + // Following this call, the audio units are instantiated but not initialized + // (no resource allocation occurs and the audio units are not in a state to + // process audio). + result = AUGraphOpen (processingGraph); + + if (noErr != result) {[self printErrorMessage: @"AUGraphOpen" withStatus: result]; return;} + + +//............................................................................ +// Obtain the mixer unit instance from its corresponding node. + + result = AUGraphNodeInfo ( + processingGraph, + mixerNode, + NULL, + &mixerUnit + ); + + if (noErr != result) {[self printErrorMessage: @"AUGraphNodeInfo" withStatus: result]; return;} + + +//............................................................................ +// Multichannel Mixer unit Setup + + UInt32 busCount = 2; // bus count for mixer unit input + UInt32 guitarBus = 0; // mixer unit bus 0 will be stereo and will take the guitar sound + UInt32 beatsBus = 1; // mixer unit bus 1 will be mono and will take the beats sound + + NSLog (@"Setting mixer unit input bus count to: %u", busCount); + result = AudioUnitSetProperty ( + mixerUnit, + kAudioUnitProperty_ElementCount, + kAudioUnitScope_Input, + 0, + &busCount, + sizeof (busCount) + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty (set mixer unit bus count)" withStatus: result]; return;} + + + NSLog (@"Setting kAudioUnitProperty_MaximumFramesPerSlice for mixer unit global scope"); + // Increase the maximum frames per slice allows the mixer unit to accommodate the + // larger slice size used when the screen is locked. + UInt32 maximumFramesPerSlice = 4096; + + result = AudioUnitSetProperty ( + mixerUnit, + kAudioUnitProperty_MaximumFramesPerSlice, + kAudioUnitScope_Global, + 0, + &maximumFramesPerSlice, + sizeof (maximumFramesPerSlice) + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty (set mixer unit input stream format)" withStatus: result]; return;} + + + // Attach the input render callback and context to each input bus + for (UInt16 busNumber = 0; busNumber < busCount; ++busNumber) { + + // Setup the struture that contains the input render callback + AURenderCallbackStruct inputCallbackStruct; + inputCallbackStruct.inputProc = &inputRenderCallback; + inputCallbackStruct.inputProcRefCon = soundStructArray; + + NSLog (@"Registering the render callback with mixer unit input bus %u", busNumber); + // Set a callback for the specified node's specified input + result = AUGraphSetNodeInputCallback ( + processingGraph, + mixerNode, + busNumber, + &inputCallbackStruct + ); + + if (noErr != result) {[self printErrorMessage: @"AUGraphSetNodeInputCallback" withStatus: result]; return;} + } + + + NSLog (@"Setting stereo stream format for mixer unit \"guitar\" input bus"); + result = AudioUnitSetProperty ( + mixerUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + guitarBus, + &stereoStreamFormat, + sizeof (stereoStreamFormat) + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty (set mixer unit guitar input bus stream format)" withStatus: result];return;} + + + NSLog (@"Setting mono stream format for mixer unit \"beats\" input bus"); + result = AudioUnitSetProperty ( + mixerUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + beatsBus, + &monoStreamFormat, + sizeof (monoStreamFormat) + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty (set mixer unit beats input bus stream format)" withStatus: result];return;} + + + NSLog (@"Setting sample rate for mixer unit output scope"); + // Set the mixer unit's output sample rate format. This is the only aspect of the output stream + // format that must be explicitly set. + result = AudioUnitSetProperty ( + mixerUnit, + kAudioUnitProperty_SampleRate, + kAudioUnitScope_Output, + 0, + &graphSampleRate, + sizeof (graphSampleRate) + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty (set mixer unit output stream format)" withStatus: result]; return;} + + +//............................................................................ +// Connect the nodes of the audio processing graph + NSLog (@"Connecting the mixer output to the input of the I/O unit output element"); + + result = AUGraphConnectNodeInput ( + processingGraph, + mixerNode, // source node + 0, // source node output bus number + iONode, // destination node + 0 // desintation node input bus number + ); + + if (noErr != result) {[self printErrorMessage: @"AUGraphConnectNodeInput" withStatus: result]; return;} + + +//............................................................................ +// Initialize audio processing graph + + // Diagnostic code + // Call CAShow if you want to look at the state of the audio processing + // graph. + NSLog (@"Audio processing graph state immediately before initializing it:"); + CAShow (processingGraph); + + NSLog (@"Initializing the audio processing graph"); + // Initialize the audio processing graph, configure audio data stream formats for + // each input and output, and validate the connections between audio units. + result = AUGraphInitialize (processingGraph); + + if (noErr != result) {[self printErrorMessage: @"AUGraphInitialize" withStatus: result]; return;} +} + + +#pragma mark - +#pragma mark Playback control + +// Start playback +- (void) startAUGraph { + + NSLog (@"Starting audio processing graph"); + OSStatus result = AUGraphStart (processingGraph); + if (noErr != result) {[self printErrorMessage: @"AUGraphStart" withStatus: result]; return;} + + self.playing = YES; +} + +// Stop playback +- (void) stopAUGraph { + + NSLog (@"Stopping audio processing graph"); + Boolean isRunning = false; + OSStatus result = AUGraphIsRunning (processingGraph, &isRunning); + if (noErr != result) {[self printErrorMessage: @"AUGraphIsRunning" withStatus: result]; return;} + + if (isRunning) { + + result = AUGraphStop (processingGraph); + if (noErr != result) {[self printErrorMessage: @"AUGraphStop" withStatus: result]; return;} + self.playing = NO; + } +} + + +#pragma mark - +#pragma mark Mixer unit control +// Enable or disable a specified bus +- (void) enableMixerInput: (UInt32) inputBus isOn: (AudioUnitParameterValue) isOnValue { + + NSLog (@"Bus %d now %@", (int) inputBus, isOnValue ? @"on" : @"off"); + + OSStatus result = AudioUnitSetParameter ( + mixerUnit, + kMultiChannelMixerParam_Enable, + kAudioUnitScope_Input, + inputBus, + isOnValue, + 0 + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetParameter (enable the mixer unit)" withStatus: result]; return;} + + + // Ensure that the sound loops stay in sync when reenabling an input bus + if (0 == inputBus && 1 == isOnValue) { + soundStructArray[0].sampleNumber = soundStructArray[1].sampleNumber; + } + + if (1 == inputBus && 1 == isOnValue) { + soundStructArray[1].sampleNumber = soundStructArray[0].sampleNumber; + } +} + + +// Set the mixer unit input volume for a specified bus +- (void) setMixerInput: (UInt32) inputBus gain: (AudioUnitParameterValue) newGain { + +/* + This method does *not* ensure that sound loops stay in sync if the user has + moved the volume of an input channel to zero. When a channel's input + level goes to zero, the corresponding input render callback is no longer + invoked. Consequently, the sample number for that channel remains constant + while the sample number for the other channel continues to increment. As a + workaround, the view controller Nib file specifies that the minimum input + level is 0.01, not zero. + + The enableMixerInput:isOn: method in this class, however, does ensure that the + loops stay in sync when a user disables and then reenables an input bus. +*/ + OSStatus result = AudioUnitSetParameter ( + mixerUnit, + kMultiChannelMixerParam_Volume, + kAudioUnitScope_Input, + inputBus, + newGain, + 0 + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetParameter (set mixer unit input volume)" withStatus: result]; return;} + +} + + +// Set the mxer unit output volume +- (void) setMixerOutputGain: (AudioUnitParameterValue) newGain { + + OSStatus result = AudioUnitSetParameter ( + mixerUnit, + kMultiChannelMixerParam_Volume, + kAudioUnitScope_Output, + 0, + newGain, + 0 + ); + + if (noErr != result) {[self printErrorMessage: @"AudioUnitSetParameter (set mixer unit output volume)" withStatus: result]; return;} + +} + + +#pragma mark - +#pragma mark Audio Session Delegate Methods +// Respond to having been interrupted. This method sends a notification to the +// controller object, which in turn invokes the playOrStop: toggle method. The +// interruptedDuringPlayback flag lets the endInterruptionWithFlags: method know +// whether playback was in progress at the time of the interruption. +- (void) beginInterruption { + + NSLog (@"Audio session was interrupted."); + + if (playing) { + + self.interruptedDuringPlayback = YES; + + NSString *MixerHostAudioObjectPlaybackStateDidChangeNotification = @"MixerHostAudioObjectPlaybackStateDidChangeNotification"; + [[NSNotificationCenter defaultCenter] postNotificationName: MixerHostAudioObjectPlaybackStateDidChangeNotification object: self]; + } +} + + +// Respond to the end of an interruption. This method gets invoked, for example, +// after the user dismisses a clock alarm. +- (void) endInterruptionWithFlags: (NSUInteger) flags { + + // Test if the interruption that has just ended was one from which this app + // should resume playback. + if (flags & AVAudioSessionInterruptionFlags_ShouldResume) { + + NSError *endInterruptionError = nil; + [[AVAudioSession sharedInstance] setActive: YES + error: &endInterruptionError]; + if (endInterruptionError != nil) { + + NSLog (@"Unable to reactivate the audio session after the interruption ended."); + return; + + } else { + + NSLog (@"Audio session reactivated after interruption."); + + if (interruptedDuringPlayback) { + + self.interruptedDuringPlayback = NO; + + // Resume playback by sending a notification to the controller object, which + // in turn invokes the playOrStop: toggle method. + NSString *MixerHostAudioObjectPlaybackStateDidChangeNotification = @"MixerHostAudioObjectPlaybackStateDidChangeNotification"; + [[NSNotificationCenter defaultCenter] postNotificationName: MixerHostAudioObjectPlaybackStateDidChangeNotification object: self]; + + } + } + } +} + + +#pragma mark - +#pragma mark Utility methods + +// You can use this method during development and debugging to look at the +// fields of an AudioStreamBasicDescription struct. +- (void) printASBD: (AudioStreamBasicDescription) asbd { + + char formatIDString[5]; + UInt32 formatID = CFSwapInt32HostToBig (asbd.mFormatID); + bcopy (&formatID, formatIDString, 4); + formatIDString[4] = '\0'; + + NSLog (@" Sample Rate: %10.0f", asbd.mSampleRate); + NSLog (@" Format ID: %10s", formatIDString); + NSLog (@" Format Flags: %10X", asbd.mFormatFlags); + NSLog (@" Bytes per Packet: %10d", asbd.mBytesPerPacket); + NSLog (@" Frames per Packet: %10d", asbd.mFramesPerPacket); + NSLog (@" Bytes per Frame: %10d", asbd.mBytesPerFrame); + NSLog (@" Channels per Frame: %10d", asbd.mChannelsPerFrame); + NSLog (@" Bits per Channel: %10d", asbd.mBitsPerChannel); +} + + +- (void) printErrorMessage: (NSString *) errorString withStatus: (OSStatus) result { + + char resultString[5]; + UInt32 swappedResult = CFSwapInt32HostToBig (result); + bcopy (&swappedResult, resultString, 4); + resultString[4] = '\0'; + + NSLog ( + @"*** %@ error: %d %08X %4.4s\n", + errorString, + (char*) &resultString + ); +} + + +#pragma mark - +#pragma mark Deallocate + +- (void) dealloc { + + for (int audioFile = 0; audioFile < NUM_FILES; ++audioFile) { + + if (sourceURLArray[audioFile] != NULL) CFRelease (sourceURLArray[audioFile]); + + if (soundStructArray[audioFile].audioDataLeft != NULL) { + free (soundStructArray[audioFile].audioDataLeft); + soundStructArray[audioFile].audioDataLeft = 0; + } + + if (soundStructArray[audioFile].audioDataRight != NULL) { + free (soundStructArray[audioFile].audioDataRight); + soundStructArray[audioFile].audioDataRight = 0; + } + } + + [super dealloc]; +} + +@end + diff --git a/MixerHost/Classes/MixerHostViewController.h b/MixerHost/Classes/MixerHostViewController.h new file mode 100644 index 0000000..b97312b --- /dev/null +++ b/MixerHost/Classes/MixerHostViewController.h @@ -0,0 +1,90 @@ +/* + File: MixerHostViewController.h +Abstract: View controller: Sets up the user interface and conveys UI actions +to the MixerHostAudio object. Also responds to state-change notifications from +the MixerHostAudio object. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import + +@class MixerHostAudio; + +@interface MixerHostViewController : UIViewController { + + UIBarButtonItem *playButton; + + UISwitch *mixerBus0Switch; + UISwitch *mixerBus1Switch; + + UISlider *mixerBus0LevelFader; + UISlider *mixerBus1LevelFader; + UISlider *mixerOutputLevelFader; + + MixerHostAudio *audioObject; +} + +@property (nonatomic, retain) IBOutlet UIBarButtonItem *playButton; + +@property (nonatomic, retain) IBOutlet UISwitch *mixerBus0Switch; +@property (nonatomic, retain) IBOutlet UISwitch *mixerBus1Switch; + +@property (nonatomic, retain) IBOutlet UISlider *mixerBus0LevelFader; +@property (nonatomic, retain) IBOutlet UISlider *mixerBus1LevelFader; +@property (nonatomic, retain) IBOutlet UISlider *mixerOutputLevelFader; + +@property (nonatomic, retain) MixerHostAudio *audioObject; + + +- (IBAction) enableMixerInput: (UISwitch *) sender; +- (IBAction) mixerInputGainChanged: (UISlider *) sender; +- (IBAction) mixerOutputGainChanged: (UISlider *) sender; +- (IBAction) playOrStop: (id) sender; + +- (void) handlePlaybackStateChanged: (id) notification; +- (void) initializeMixerSettingsToUI; +- (void) registerForAudioObjectNotifications; + +@end diff --git a/MixerHost/Classes/MixerHostViewController.m b/MixerHost/Classes/MixerHostViewController.m new file mode 100644 index 0000000..bb7a17b --- /dev/null +++ b/MixerHost/Classes/MixerHostViewController.m @@ -0,0 +1,262 @@ +/* + File: MixerHostViewController.m +Abstract: View controller: Sets up the user interface and conveys UI actions +to the MixerHostAudio object. Also responds to state-change notifications from +the MixerHostAudio object. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import "MixerHostViewController.h" +#import "MixerHostAudio.h" + +NSString *MixerHostAudioObjectPlaybackStateDidChangeNotification = @"MixerHostAudioObjectPlaybackStateDidChangeNotification"; + + +@implementation MixerHostViewController + +// To learn about properties, see "Declared Properties" in the "Cocoa Objects" chapter +// in Cocoa Fundamentals Guide +@synthesize playButton; +@synthesize mixerBus0Switch; +@synthesize mixerBus0LevelFader; +@synthesize mixerBus1Switch; +@synthesize mixerBus1LevelFader; +@synthesize mixerOutputLevelFader; + +@synthesize audioObject; + + +# pragma mark - +# pragma mark User interface methods +// Set the initial multichannel mixer unit parameter values according to the UI state +- (void) initializeMixerSettingsToUI { + + // Initialize mixer settings to UI + [audioObject enableMixerInput: 0 isOn: mixerBus0Switch.isOn]; + [audioObject enableMixerInput: 1 isOn: mixerBus1Switch.isOn]; + + [audioObject setMixerOutputGain: mixerOutputLevelFader.value]; + + [audioObject setMixerInput: 0 gain: mixerBus0LevelFader.value]; + [audioObject setMixerInput: 1 gain: mixerBus1LevelFader.value]; +} + +// Handle a change in the mixer output gain slider. +- (IBAction) mixerOutputGainChanged: (UISlider *) sender { + + [audioObject setMixerOutputGain: (AudioUnitParameterValue) sender.value]; +} + +// Handle a change in a mixer input gain slider. The "tag" value of the slider lets this +// method distinguish between the two channels. +- (IBAction) mixerInputGainChanged: (UISlider *) sender { + + UInt32 inputBus = sender.tag; + [audioObject setMixerInput: (UInt32) inputBus gain: (AudioUnitParameterValue) sender.value]; +} + + +#pragma mark - +#pragma mark Audio processing graph control + +// Handle a play/stop button tap +- (IBAction) playOrStop: (id) sender { + + if (audioObject.isPlaying) { + + [audioObject stopAUGraph]; + self.playButton.title = @"Play"; + + } else { + + [audioObject startAUGraph]; + self.playButton.title = @"Stop"; + } +} + +// Handle a change in playback state that resulted from an audio session interruption or end of interruption +- (void) handlePlaybackStateChanged: (id) notification { + + [self playOrStop: nil]; +} + + +#pragma mark - +#pragma mark Mixer unit control + +// Handle a Mixer unit input on/off switch action. The "tag" value of the switch lets this +// method distinguish between the two channels. +- (IBAction) enableMixerInput: (UISwitch *) sender { + + UInt32 inputBus = sender.tag; + AudioUnitParameterValue isOn = (AudioUnitParameterValue) sender.isOn; + + [audioObject enableMixerInput: inputBus isOn: isOn]; + +} + + +#pragma mark - +#pragma mark Remote-control event handling +// Respond to remote control events +- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent { + + if (receivedEvent.type == UIEventTypeRemoteControl) { + + switch (receivedEvent.subtype) { + + case UIEventSubtypeRemoteControlTogglePlayPause: + [self playOrStop: nil]; + break; + + default: + break; + } + } +} + + +#pragma mark - +#pragma mark Notification registration +// If this app's audio session is interrupted when playing audio, it needs to update its user interface +// to reflect the fact that audio has stopped. The MixerHostAudio object conveys its change in state to +// this object by way of a notification. To learn about notifications, see Notification Programming Topics. +- (void) registerForAudioObjectNotifications { + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter addObserver: self + selector: @selector (handlePlaybackStateChanged:) + name: MixerHostAudioObjectPlaybackStateDidChangeNotification + object: audioObject]; +} + + +#pragma mark - +#pragma mark Application state management + +- (void) viewDidLoad { + + [super viewDidLoad]; + + MixerHostAudio *newAudioObject = [[MixerHostAudio alloc] init]; + self.audioObject = newAudioObject; + [newAudioObject release]; + + [self registerForAudioObjectNotifications]; + [self initializeMixerSettingsToUI]; +} + + +// If using a nonmixable audio session category, as this app does, you must activate reception of +// remote-control events to allow reactivation of the audio session when running in the background. +// Also, to receive remote-control events, the app must be eligible to become the first responder. +- (void) viewDidAppear: (BOOL) animated { + + [super viewDidAppear: animated]; + [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; + [self becomeFirstResponder]; +} + +- (BOOL) canBecomeFirstResponder { + + return YES; +} + + +- (void) didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void) viewWillDisppear: (BOOL) animated { + + [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; + [self resignFirstResponder]; + + [super viewWillDisappear: animated]; +} + + +- (void) viewDidUnload { + + self.playButton = nil; + self.mixerBus0Switch = nil; + self.mixerBus1Switch = nil; + self.mixerBus0LevelFader = nil; + self.mixerBus1LevelFader = nil; + self.mixerOutputLevelFader = nil; + + [[NSNotificationCenter defaultCenter] removeObserver: self + name: MixerHostAudioObjectPlaybackStateDidChangeNotification + object: audioObject]; + + self.audioObject = nil; + [super viewDidUnload]; +} + + +- (void) dealloc { + + [playButton release]; + [mixerBus0Switch release]; + [mixerBus1Switch release]; + [mixerBus0LevelFader release]; + [mixerBus1LevelFader release]; + [mixerOutputLevelFader release]; + + [[NSNotificationCenter defaultCenter] removeObserver: self + name: MixerHostAudioObjectPlaybackStateDidChangeNotification + object: audioObject]; + + [audioObject release]; + [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; + [super dealloc]; +} + +@end diff --git a/MixerHost/Classes/untitled b/MixerHost/Classes/untitled new file mode 100644 index 0000000..e69de29 diff --git a/MixerHost/MixerHost-Info.plist b/MixerHost/MixerHost-Info.plist new file mode 100644 index 0000000..512acc8 --- /dev/null +++ b/MixerHost/MixerHost-Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarHidden + + UIBackgroundModes + + audio + + + diff --git a/MixerHost/MixerHost.xcodeproj/mrj.mode1v3 b/MixerHost/MixerHost.xcodeproj/mrj.mode1v3 new file mode 100644 index 0000000..0d9ce05 --- /dev/null +++ b/MixerHost/MixerHost.xcodeproj/mrj.mode1v3 @@ -0,0 +1,1489 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 0AFAF19B111B977100B42D9F + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-go + debugger-enable-breakpoints + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 228 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + 1C37FBAC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 2 + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {228, 581}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {245, 599}} + GroupTreeTableConfiguration + + MainColumn + 228 + + RubberWindowFrame + 334 538 1002 640 0 0 1920 1178 + + Module + PBXSmartGroupTreeModule + Proportion + 245pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + MixerHostAppDelegate.h + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + MixerHostAppDelegate.h + _historyCapacity + 0 + bookmark + 0A8821FD11F7DFCD003B5C4B + history + + 0ACE7A75118E567300C092B8 + 0AB8915D11CFCDA900D429A1 + 0A5F495811D0407000C1DE0F + 0A1DE2A511D17029006CFECE + 0A1DE2A711D17029006CFECE + 0A1DE2CE11D17D97006CFECE + 0AD84AD211D3E3220050943E + 0AD84AD411D3E3220050943E + 0AD84B1E11D415420050943E + 0ADB95B111D425CF0003FA6A + 0A5C2A3811D98F8E00CB4BAB + 0A5C2A3A11D98F8E00CB4BAB + 0A1A47B111E804F000A8CE72 + 0A1A47B211E804F000A8CE72 + 0A63D3A711ED3A5300686627 + 0AF7968A11EF80C0004FC98B + 0AC53A3411F538C700D6370A + 0AC53A3511F538C700D6370A + 0A8821E411F7DC2E003B5C4B + 0A8821E511F7DC2E003B5C4B + 0A8821FB11F7DFCD003B5C4B + 0A8821FC11F7DFCD003B5C4B + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {752, 594}} + RubberWindowFrame + 334 538 1002 640 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 594pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 599}, {752, 0}} + RubberWindowFrame + 334 538 1002 640 0 0 1920 1178 + + Module + XCDetailModule + Proportion + 0pt + + + Proportion + 752pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 0A8821FE11F7DFCD003B5C4B + 1CE0B1FE06471DED0097A5F4 + 0A8821FF11F7DFCD003B5C4B + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 0AFAF19C111B977100B42D9F + /Volumes/mrj (tallinn)/Documents/Apple/projects/Aspen/03. Sample Code Work/MixerHost/2. edit/MixerHost/MixerHost.xcodeproj + + WindowString + 334 538 1002 640 0 0 1920 1178 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1245, 305}} + RubberWindowFrame + 612 500 1245 587 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 305pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 310}, {1245, 236}} + RubberWindowFrame + 612 500 1245 587 0 0 1920 1178 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 546pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 0AFAF19C111B977100B42D9F + 0A88220011F7DFCD003B5C4B + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 612 500 1245 587 0 0 1920 1178 + WindowToolGUID + 0AFAF19C111B977100B42D9F + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {541, 363}} + {{541, 0}, {683, 363}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1224, 363}} + {{0, 363}, {1224, 318}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {1224, 681}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 356 + Value + 144 + Summary + 158 + + Frame + {{541, 0}, {683, 363}} + RubberWindowFrame + 37 456 1224 722 0 0 1920 1178 + + RubberWindowFrame + 37 456 1224 722 0 0 1920 1178 + + Module + PBXDebugSessionModule + Proportion + 681pt + + + Proportion + 681pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 0A8821EC11F7DC2E003B5C4B + 1C162984064C10D400B95A72 + 0A8821ED11F7DC2E003B5C4B + 0A8821EE11F7DC2E003B5C4B + 0A8821EF11F7DC2E003B5C4B + 0A8821F011F7DC2E003B5C4B + 0A8821F111F7DC2E003B5C4B + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 37 456 1224 722 0 0 1920 1178 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + MixerHostViewController.m + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1266, 640}} + RubberWindowFrame + -1335 1 1266 1025 -1680 0 1680 1050 + + Module + PBXNavigatorGroup + Proportion + 1266pt + + + Proportion + 640pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 645}, {1266, 339}} + RubberWindowFrame + -1335 1 1266 1025 -1680 0 1680 1050 + + Module + PBXProjectFindModule + Proportion + 339pt + + + Proportion + 984pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 0AC413B111EBF7F10005A9F3 + 0AC413B211EBF7F10005A9F3 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + -1335 1 1266 1025 -1680 0 1680 1050 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {1113, 582}} + RubberWindowFrame + -1258 339 1113 623 -1680 0 1680 1050 + + Module + PBXDebugCLIModule + Proportion + 582pt + + + Proportion + 582pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 0A8821F211F7DC2E003B5C4B + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + -1258 339 1113 623 -1680 0 1680 1050 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.snapshots + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 0ACE627A11C8467D008685C5 + PBXProjectModuleLabel + Snapshots + + GeometryConfiguration + + Frame + {{0, 0}, {1645, 953}} + RubberWindowFrame + -1668 56 1645 994 -1680 0 1680 1050 + + Module + XCSnapshotModule + Proportion + 953pt + + + Proportion + 953pt + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + + TableOfContents + + 0ACE627B11C8467D008685C5 + 0A9D26AC11D541F000E58664 + 0ACE627A11C8467D008685C5 + + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + -1668 56 1645 994 -1680 0 1680 1050 + WindowToolGUID + 0ACE627B11C8467D008685C5 + WindowToolIsVisible + + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.breakpoints + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 436 746 744 409 0 0 1920 1178 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 436 746 744 409 0 0 1920 1178 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + + TableOfContents + + 0A8DCF0511D57B2F00D89A79 + 0A8DCF0611D57B2F00D89A79 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 436 746 744 409 0 0 1920 1178 + WindowToolGUID + 0A8DCF0511D57B2F00D89A79 + WindowToolIsVisible + + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.bookmarks + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 0A9F2927118F5637002256C0 + PBXProjectModuleLabel + Bookmarks + + GeometryConfiguration + + Frame + {{0, 0}, {401, 202}} + RubberWindowFrame + 1071 934 401 222 0 0 1920 1178 + + Module + PBXBookmarksModule + Proportion + 202pt + + + Proportion + 202pt + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + + TableOfContents + + 0A9F2928118F5637002256C0 + 0ABFDFBE1194913C00AFBE9E + 0A9F2927118F5637002256C0 + + WindowString + 1071 934 401 222 0 0 1920 1178 + WindowToolGUID + 0A9F2928118F5637002256C0 + WindowToolIsVisible + + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 0AD84AE511D3E3220050943E + + GeometryConfiguration + + Frame + {{0, 0}, {750, 643}} + RubberWindowFrame + 106 471 750 684 0 0 1920 1178 + XCRefactoringSplitViewLowerHeight + 277 + XCRefactoringSplitViewTotalHeight + 560 + + Module + XCRefactoringModule + Proportion + 643pt + + + Proportion + 643pt + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + StatusbarIsVisible + + TableOfContents + + 0AD84AE611D3E3220050943E + 0AD84AE711D3E3220050943E + 0AD84AE511D3E3220050943E + + WindowString + 106 471 750 684 0 0 1920 1178 + WindowToolGUID + 0AD84AE611D3E3220050943E + WindowToolIsVisible + + + + + diff --git a/MixerHost/MixerHost.xcodeproj/project.pbxproj b/MixerHost/MixerHost.xcodeproj/project.pbxproj new file mode 100755 index 0000000..385fe8c --- /dev/null +++ b/MixerHost/MixerHost.xcodeproj/project.pbxproj @@ -0,0 +1,356 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 0A58F3D4111CB6B50075A94F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A58F3D3111CB6B50075A94F /* AudioToolbox.framework */; }; + 0A63D1C011ECEE0400686627 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D1BC11ECEE0400686627 /* MainWindow.xib */; }; + 0A63D1C111ECEE0400686627 /* MixerHostViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D1BE11ECEE0400686627 /* MixerHostViewController.xib */; }; + 0A63D29511ED1D6900686627 /* rounded_rectangle.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D29111ED1D6900686627 /* rounded_rectangle.png */; }; + 0A63D29611ED1D6900686627 /* beatsMono.caf in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D29311ED1D6900686627 /* beatsMono.caf */; }; + 0A63D29711ED1D6900686627 /* guitarStereo.caf in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D29411ED1D6900686627 /* guitarStereo.caf */; }; + 0A63D36711ED318800686627 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36011ED318800686627 /* Icon-72.png */; }; + 0A63D36811ED318800686627 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36111ED318800686627 /* Icon-Small-50.png */; }; + 0A63D36911ED318800686627 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36211ED318800686627 /* Icon-Small.png */; }; + 0A63D36A11ED318800686627 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36311ED318800686627 /* Icon-Small@2x.png */; }; + 0A63D36B11ED318800686627 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36411ED318800686627 /* Icon.png */; }; + 0A63D36C11ED318800686627 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36511ED318800686627 /* Icon@2x.png */; }; + 0A63D36D11ED318800686627 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D36611ED318800686627 /* iTunesArtwork */; }; + 0A63D37711ED322500686627 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A63D37611ED322500686627 /* Default.png */; }; + 0ACE7994118E259E00C092B8 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ACE7993118E259E00C092B8 /* AVFoundation.framework */; }; + 0AFAF1E0111B982200B42D9F /* MixerHostAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AFAF1DF111B982200B42D9F /* MixerHostAudio.m */; }; + 1D3623260D0F684500981E51 /* MixerHostAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MixerHostAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28D7ACF80DDB3853001CB0EB /* MixerHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* MixerHostViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0A58F3D3111CB6B50075A94F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 0A63D1BD11ECEE0400686627 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = MainWindow.xib; sourceTree = ""; }; + 0A63D1BF11ECEE0400686627 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = MixerHostViewController.xib; sourceTree = ""; }; + 0A63D29111ED1D6900686627 /* rounded_rectangle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = rounded_rectangle.png; sourceTree = ""; }; + 0A63D29311ED1D6900686627 /* beatsMono.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = beatsMono.caf; sourceTree = ""; }; + 0A63D29411ED1D6900686627 /* guitarStereo.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = guitarStereo.caf; sourceTree = ""; }; + 0A63D36011ED318800686627 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 0A63D36111ED318800686627 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 0A63D36211ED318800686627 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 0A63D36311ED318800686627 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 0A63D36411ED318800686627 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 0A63D36511ED318800686627 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 0A63D36611ED318800686627 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 0A63D37611ED322500686627 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 0ACE7993118E259E00C092B8 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 0AFAF1DE111B982200B42D9F /* MixerHostAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixerHostAudio.h; sourceTree = ""; }; + 0AFAF1DF111B982200B42D9F /* MixerHostAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MixerHostAudio.m; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* MixerHostAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixerHostAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* MixerHostAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MixerHostAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* MixerHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MixerHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28D7ACF60DDB3853001CB0EB /* MixerHostViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixerHostViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* MixerHostViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MixerHostViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* MixerHost_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixerHost_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* MixerHost-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MixerHost-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 0A58F3D4111CB6B50075A94F /* AudioToolbox.framework in Frameworks */, + 0ACE7994118E259E00C092B8 /* AVFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* MixerHostAppDelegate.h */, + 1D3623250D0F684500981E51 /* MixerHostAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* MixerHostViewController.h */, + 28D7ACF70DDB3853001CB0EB /* MixerHostViewController.m */, + 0AFAF1DE111B982200B42D9F /* MixerHostAudio.h */, + 0AFAF1DF111B982200B42D9F /* MixerHostAudio.m */, + ); + path = Classes; + sourceTree = ""; + }; + 0A63D1BB11ECEE0400686627 /* en.lproj */ = { + isa = PBXGroup; + children = ( + 0A63D1BC11ECEE0400686627 /* MainWindow.xib */, + 0A63D1BE11ECEE0400686627 /* MixerHostViewController.xib */, + ); + name = en.lproj; + path = Resources/en.lproj; + sourceTree = ""; + }; + 0A63D29011ED1D6900686627 /* images */ = { + isa = PBXGroup; + children = ( + 0A63D37611ED322500686627 /* Default.png */, + 0A63D36011ED318800686627 /* Icon-72.png */, + 0A63D36111ED318800686627 /* Icon-Small-50.png */, + 0A63D36211ED318800686627 /* Icon-Small.png */, + 0A63D36311ED318800686627 /* Icon-Small@2x.png */, + 0A63D36411ED318800686627 /* Icon.png */, + 0A63D36511ED318800686627 /* Icon@2x.png */, + 0A63D36611ED318800686627 /* iTunesArtwork */, + 0A63D29111ED1D6900686627 /* rounded_rectangle.png */, + ); + name = images; + path = Resources/images; + sourceTree = ""; + }; + 0A63D29211ED1D6900686627 /* sounds */ = { + isa = PBXGroup; + children = ( + 0A63D29311ED1D6900686627 /* beatsMono.caf */, + 0A63D29411ED1D6900686627 /* guitarStereo.caf */, + ); + name = sounds; + path = Resources/sounds; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MixerHost.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* MixerHost_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* MixerHost-Info.plist */, + 0A63D29011ED1D6900686627 /* images */, + 0A63D29211ED1D6900686627 /* sounds */, + 0A63D1BB11ECEE0400686627 /* en.lproj */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 0A58F3D3111CB6B50075A94F /* AudioToolbox.framework */, + 0ACE7993118E259E00C092B8 /* AVFoundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MixerHost */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MixerHost" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MixerHost; + productName = MixerHost; + productReference = 1D6058910D05DD3D006BFB54 /* MixerHost.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MixerHost" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MixerHost */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A63D1C011ECEE0400686627 /* MainWindow.xib in Resources */, + 0A63D1C111ECEE0400686627 /* MixerHostViewController.xib in Resources */, + 0A63D29511ED1D6900686627 /* rounded_rectangle.png in Resources */, + 0A63D29611ED1D6900686627 /* beatsMono.caf in Resources */, + 0A63D29711ED1D6900686627 /* guitarStereo.caf in Resources */, + 0A63D36711ED318800686627 /* Icon-72.png in Resources */, + 0A63D36811ED318800686627 /* Icon-Small-50.png in Resources */, + 0A63D36911ED318800686627 /* Icon-Small.png in Resources */, + 0A63D36A11ED318800686627 /* Icon-Small@2x.png in Resources */, + 0A63D36B11ED318800686627 /* Icon.png in Resources */, + 0A63D36C11ED318800686627 /* Icon@2x.png in Resources */, + 0A63D36D11ED318800686627 /* iTunesArtwork in Resources */, + 0A63D37711ED322500686627 /* Default.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* MixerHostAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* MixerHostViewController.m in Sources */, + 0AFAF1E0111B982200B42D9F /* MixerHostAudio.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 0A63D1BC11ECEE0400686627 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 0A63D1BD11ECEE0400686627 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 0A63D1BE11ECEE0400686627 /* MixerHostViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 0A63D1BF11ECEE0400686627 /* en */, + ); + name = MixerHostViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MixerHost_Prefix.pch; + INFOPLIST_FILE = "MixerHost-Info.plist"; + PRODUCT_NAME = MixerHost; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MixerHost_Prefix.pch; + INFOPLIST_FILE = "MixerHost-Info.plist"; + PRODUCT_NAME = MixerHost; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MixerHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MixerHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MixerHost/MixerHost_Prefix.pch b/MixerHost/MixerHost_Prefix.pch new file mode 100644 index 0000000..33ac037 --- /dev/null +++ b/MixerHost/MixerHost_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'MixerHost' target in the 'MixerHost' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/MixerHost/ReadMe.txt b/MixerHost/ReadMe.txt new file mode 100644 index 0000000..ea46b95 --- /dev/null +++ b/MixerHost/ReadMe.txt @@ -0,0 +1,115 @@ +MixerHost + +=========================================================================== +DESCRIPTION: + +MixerHost demonstrates how to use the Multichannel Mixer audio unit in an iOS application. It also demonstrates how to use a render callback function to provide audio to an audio unit input bus. In this sample, the audio delivered by the callback comes from two short loops read from disk. You could use a similar callback, however, to synthesize sounds to feed into a mixer unit. + +This sample is described in Audio Unit Hosting Guide for iOS. + +The code in MixerHost instantiates two system-supplied audio units--the Multichannel Mixer unit (of subtype kAudioUnitSubType_MultichannelMixer) and the Remote I/O unit (of subtype kAudioUnitSubType_RemoteIO)--and connects them together using an audio processing graph (an AUGraph opaque type). The app functions as an audio mixer, letting a user control the playback levels of two sound loops. + +The sample provides a user interface for controlling the following Multichannel Mixer unit parameters: + + * input bus enable + * input bus gain + * output bus gain + +This sample shows how to: + + * Write an input render callback function + * Locate system audio units at runtime and then load, instantiate, configure, + and connect them + * Correctly use audio stream formats in the context of an audio processing + graph + * Instantiate, open, initialize, and start an audio processing graph + * Control a Multichannel Mixer unit through a user interface + +This sample also shows how to: + + * Configure an audio application for playing in the background by adding the + "app plays audio" key to the info.plist file + * Use the AVAudioSession class to configure audio behavior, set hardware + sample rate, and handle interruptions + * Make the app eligible for its audio session to be reactivated while in the + background + * Respond to remote-control events as described in Event Handling Guide for + iOS + * Allocate memory for an AudioBufferList struct so that it can handle more + than one channel of audio + * Use the C interface from Audio Session Services to handle audio hardware + route changes + * Use Cocoa notifications to communicate state changes from the audio object + back to the controller object + +To test how this app can reactivate its audio session while in the background in iOS 4.0 or later: + + 1. Launch the app and start playback. + 2. Press the Home button. MixerHost continues to play in the background. + 3. Launch the Clock app and set a one-minute countdown timer. Leave the + Clock app running in the foreground. + 4. When the timer expires, an alarm sounds, which interrupts MixerHost and + stops its audio. + 5. Tap OK to dismiss the Timer Done alert. The MixerHost audio resumes + playback while the app remains in the background. + +To test how this app responds to remote-control events: + + 1. Launch the app and start playback. + 2. Press the Home button. MixerHost continues to play in the background. + 3. Double-press the Home button to display the running apps. + 4. Swipe right to expose the audio transport controls. + 5. Notice the MixerHost icon at the bottom-right of the screen. This + indicates that MixerHost is the current target of remote-control + events. + 6. Tap the play/pause toggle button; MixerHost stops. Tap it again; + MixerHost resumes playback. Tap the MixerHost icon; MixerHost + comes to the foreground. + + +=========================================================================== +RELATED INFORMATION: + +Audio Unit Hosting Guide for iOS, May 2010 +Audio Session Programming Guide, April 2010 + + +=========================================================================== +BUILD REQUIREMENTS: + +Mac OS X v10.6.4, Xcode 3.2, iOS 4.0 + + +=========================================================================== +RUNTIME REQUIREMENTS: + +Simulator: Mac OS X v10.6.4 +Devices: iOS 4.0 + + +=========================================================================== +PACKAGING LIST: + +MixerHostAppDelegate.h +MixerHostAppDelegate.m + +The MixerHostAppDelegate class defines the application delegate object, responsible for instantiating the controller object (defined in the MixerHostViewController class) and adding the application's view to the application window. + +MixerHostViewController.h +MixerHostViewController.m + +The MixerHostViewController class defines the controller object for the application. The object helps set up the user interface, responds to and manages user interaction, responds to notifications from the MixerHostAudio object to handle audio interruptions and audio route changes, and handles various housekeeping duties. + +MixerHostAudio.h +MixerHostAudio.m + +The MixerHostAudio class encapsulates all of the audio capabilities for the application. It handles audio session configuration, use of the ExtAudioFileRef opaque type for reading audio files from disk into memory, and construction and management of the audio processing graph. It detects interruptions and audio route changes and uses notifications to communicate audio state changes back to the MixerHostViewController object. + + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.0. New sample application that demonstrates how to host a Multichannel Mixer unit. + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/MixerHost/Resources/en.lproj/MainWindow.xib b/MixerHost/Resources/en.lproj/MainWindow.xib new file mode 100644 index 0000000..18352c3 --- /dev/null +++ b/MixerHost/Resources/en.lproj/MainWindow.xib @@ -0,0 +1,219 @@ + + + + 784 + 10A394 + 732 + 1027.1 + 430.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 60 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + MixerHostViewController + + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + viewController + + + + 11 + + + + window + + + + 14 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + MixerHost App Delegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + MixerHostViewController + {{512, 351}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MixerHostAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 14 + + + + YES + + MixerHostAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + MixerHostViewController + UIWindow + + + + IBProjectSource + Classes/MixerHostAppDelegate.h + + + + MixerHostAppDelegate + NSObject + + IBUserSource + + + + + MixerHostViewController + UIViewController + + IBProjectSource + Classes/MixerHostViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + MixerHost.xcodeproj + 3 + 3.1 + + diff --git a/MixerHost/Resources/en.lproj/MixerHostViewController.xib b/MixerHost/Resources/en.lproj/MixerHostViewController.xib new file mode 100644 index 0000000..e432c38 --- /dev/null +++ b/MixerHost/Resources/en.lproj/MixerHostViewController.xib @@ -0,0 +1,986 @@ + + + + 1024 + 10F562 + 788 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 117 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + + 274 + + YES + + + 290 + {320, 44} + + NO + NO + IBCocoaTouchFramework + 1 + + YES + + + MixerHost + IBCocoaTouchFramework + + + + + + 266 + {{0, 436}, {320, 44}} + + NO + NO + IBCocoaTouchFramework + 1 + + YES + + IBCocoaTouchFramework + + 5 + + + Play + IBCocoaTouchFramework + 240 + + + + IBCocoaTouchFramework + + 5 + + + + + + 256 + {{10, 178}, {299, 74}} + + NO + YES + 4 + YES + IBCocoaTouchFramework + + NSImage + rounded_rectangle.png + + + + + 256 + {{10, 260}, {299, 74}} + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + + + 292 + {{142, 217}, {160, 23}} + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + 0.5 + 0.0099999997764825821 + + + + 292 + {{18, 96}, {284, 23}} + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + 0.5 + + + + 292 + {{19, 215}, {94, 27}} + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + YES + + + + 292 + {{19, 188}, {257, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Guitar + + Helvetica-Bold + 14 + 16 + + + 1 + MSAxIDEAA + + 1 + + + + 1 + 10 + + + + 292 + {{21, 67}, {257, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Output Volume + + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + 292 + {{144, 300}, {158, 23}} + + NO + YES + YES + 1 + IBCocoaTouchFramework + 0 + 0 + 0.5 + 0.0099999997764825821 + + + + 292 + {{21, 297}, {94, 27}} + + NO + YES + YES + 1 + IBCocoaTouchFramework + 0 + 0 + YES + + + + 292 + {{21, 270}, {257, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Beats + + + 1 + MSAxIDEAA + + + + 1 + 10 + + + {320, 480} + + + 1 + MCAwIDAAA + + NO + IBCocoaTouchFramework + + + 1 + + IBCocoaTouchFramework + NO + + + + + YES + + + playButton + + + + 31 + + + + playOrStop: + + + + 32 + + + + enableMixerInput: + + + 13 + + 33 + + + + enableMixerInput: + + + 13 + + 34 + + + + mixerOutputGainChanged: + + + 13 + + 41 + + + + mixerInputGainChanged: + + + 13 + + 42 + + + + mixerInputGainChanged: + + + 13 + + 43 + + + + mixerBus0LevelFader + + + + 44 + + + + mixerBus0Switch + + + + 45 + + + + mixerBus1LevelFader + + + + 46 + + + + mixerBus1Switch + + + + 47 + + + + mixerOutputLevelFader + + + + 49 + + + + view + + + + 51 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 9 + + + YES + + + + + + 14 + + + YES + + + + + + + + + + + + + + + + + 15 + + + YES + + + + + + 16 + + + + + 17 + + + YES + + + + + + + + 18 + + + + + 19 + + + + + 20 + + + + + 21 + + + + + 22 + + + + + 23 + + + + + 24 + + + + + 25 + + + + + 26 + + + + + 27 + + + + + 28 + + + + + 29 + + + + + 30 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 14.IBPluginDependency + 15.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 19.IBPluginDependency + 20.IBPluginDependency + 23.IBPluginDependency + 24.IBPluginDependency + 25.IBPluginDependency + 26.IBPluginDependency + 27.IBPluginDependency + 28.IBPluginDependency + 29.IBPluginDependency + 30.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + MixerHostViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{757, 370}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 51 + + + + YES + + MixerHostViewController + UIViewController + + YES + + YES + enableMixerInput: + enableMixerInputChannelGanging: + mixerInputGainChanged: + mixerOutputGainChanged: + playOrStop: + + + YES + UISwitch + UISwitch + UISlider + UISlider + id + + + + YES + + YES + enableMixerInput: + enableMixerInputChannelGanging: + mixerInputGainChanged: + mixerOutputGainChanged: + playOrStop: + + + YES + + enableMixerInput: + UISwitch + + + enableMixerInputChannelGanging: + UISwitch + + + mixerInputGainChanged: + UISlider + + + mixerOutputGainChanged: + UISlider + + + playOrStop: + id + + + + + YES + + YES + mixerBus0LevelFader + mixerBus0Switch + mixerBus1LevelFader + mixerBus1Switch + mixerInputChannelGangingSwitch + mixerOutputLevelFader + playButton + + + YES + UISlider + UISwitch + UISlider + UISwitch + UISwitch + UISlider + UIBarButtonItem + + + + YES + + YES + mixerBus0LevelFader + mixerBus0Switch + mixerBus1LevelFader + mixerBus1Switch + mixerInputChannelGangingSwitch + mixerOutputLevelFader + playButton + + + YES + + mixerBus0LevelFader + UISlider + + + mixerBus0Switch + UISwitch + + + mixerBus1LevelFader + UISlider + + + mixerBus1Switch + UISwitch + + + mixerInputChannelGangingSwitch + UISwitch + + + mixerOutputLevelFader + UISlider + + + playButton + UIBarButtonItem + + + + + IBProjectSource + Classes/MixerHostViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISlider + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISlider.h + + + + UISwitch + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISwitch.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../MixerHost.xcodeproj + 3 + + rounded_rectangle.png + {299, 74} + + 117 + + diff --git a/MixerHost/Resources/images/Default.png b/MixerHost/Resources/images/Default.png new file mode 100644 index 0000000..241ea84 Binary files /dev/null and b/MixerHost/Resources/images/Default.png differ diff --git a/MixerHost/Resources/images/Icon-72.png b/MixerHost/Resources/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/MixerHost/Resources/images/Icon-72.png differ diff --git a/MixerHost/Resources/images/Icon-Small-50.png b/MixerHost/Resources/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/MixerHost/Resources/images/Icon-Small-50.png differ diff --git a/MixerHost/Resources/images/Icon-Small.png b/MixerHost/Resources/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/MixerHost/Resources/images/Icon-Small.png differ diff --git a/MixerHost/Resources/images/Icon-Small@2x.png b/MixerHost/Resources/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/MixerHost/Resources/images/Icon-Small@2x.png differ diff --git a/MixerHost/Resources/images/Icon.png b/MixerHost/Resources/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/MixerHost/Resources/images/Icon.png differ diff --git a/MixerHost/Resources/images/Icon@2x.png b/MixerHost/Resources/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/MixerHost/Resources/images/Icon@2x.png differ diff --git a/MixerHost/Resources/images/iTunesArtwork b/MixerHost/Resources/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/MixerHost/Resources/images/iTunesArtwork differ diff --git a/MixerHost/Resources/images/rounded_rectangle.png b/MixerHost/Resources/images/rounded_rectangle.png new file mode 100644 index 0000000..73acf69 Binary files /dev/null and b/MixerHost/Resources/images/rounded_rectangle.png differ diff --git a/MixerHost/Resources/sounds/beatsMono.caf b/MixerHost/Resources/sounds/beatsMono.caf new file mode 100644 index 0000000..7a3fe93 Binary files /dev/null and b/MixerHost/Resources/sounds/beatsMono.caf differ diff --git a/MixerHost/Resources/sounds/guitarStereo.caf b/MixerHost/Resources/sounds/guitarStereo.caf new file mode 100644 index 0000000..8bff9ec Binary files /dev/null and b/MixerHost/Resources/sounds/guitarStereo.caf differ diff --git a/MixerHost/main.m b/MixerHost/main.m new file mode 100644 index 0000000..d82689b --- /dev/null +++ b/MixerHost/main.m @@ -0,0 +1,57 @@ +/* + File: main.m +Abstract: The main.m file for the MixerHost application. + Version: 1.0 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/MoveMe.zip b/MoveMe.zip new file mode 100644 index 0000000..d5e3f94 Binary files /dev/null and b/MoveMe.zip differ diff --git a/MoveMe/Classes/MoveMeAppDelegate.h b/MoveMe/Classes/MoveMeAppDelegate.h new file mode 100644 index 0000000..979c4c3 --- /dev/null +++ b/MoveMe/Classes/MoveMeAppDelegate.h @@ -0,0 +1,57 @@ +/* + File: MoveMeAppDelegate.h + Abstract: Simple application delegate that sets up a window and view controller. + + Version: 2.10 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface MoveMeAppDelegate : NSObject { + UIWindow *window; + UIViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UIViewController *viewController; + +@end diff --git a/MoveMe/Classes/MoveMeAppDelegate.m b/MoveMe/Classes/MoveMeAppDelegate.m new file mode 100644 index 0000000..4716751 --- /dev/null +++ b/MoveMe/Classes/MoveMeAppDelegate.m @@ -0,0 +1,87 @@ +/* + File: MoveMeAppDelegate.m + Abstract: Simple application delegate that sets up a window and view controller. + + Version: 2.10 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MoveMeAppDelegate.h" + + +@implementation MoveMeAppDelegate + +@synthesize window; + +// The status bar is hidden using the UIStatusBarHidden entry in Info.plist +// The window is set up in the MainWindow nib file + + +@synthesize viewController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + /* + Set up a view controller to manage the MoveMeView. + Since the view controller has no custom behavior in this application, just use an instance of UIViewController. + */ + UIViewController *aViewController = [[UIViewController alloc] initWithNibName:@"MoveMeView" bundle:[NSBundle mainBundle]]; + self.viewController = aViewController; + [aViewController release]; + + // Add the view controller's view as a subview of the window + UIView *controllersView = [viewController view]; + [window addSubview:controllersView]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/MoveMe/Classes/MoveMeView.h b/MoveMe/Classes/MoveMeView.h new file mode 100644 index 0000000..21c83f7 --- /dev/null +++ b/MoveMe/Classes/MoveMeView.h @@ -0,0 +1,63 @@ + /* + File: MoveMeView.h + Abstract: Contains a (placard) view that can be moved by touch. Illustrates + handling touch events and two styles of animation. + + Version: 2.10 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class PlacardView; + +@interface MoveMeView : UIView { + PlacardView *placardView; +} + +@property (nonatomic, retain) PlacardView *placardView; + +- (void)setUpPlacardView; +- (void)animateFirstTouchAtPoint:(CGPoint)touchPoint; +- (void)animatePlacardViewToCenter; + +@end + diff --git a/MoveMe/Classes/MoveMeView.m b/MoveMe/Classes/MoveMeView.m new file mode 100644 index 0000000..11af0e7 --- /dev/null +++ b/MoveMe/Classes/MoveMeView.m @@ -0,0 +1,327 @@ +/* + File: MoveMeView.m + Abstract: Contains a (placard) view that can be moved by touch. Illustrates + handling touch events and two styles of animation. + + Version: 2.10 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MoveMeView.h" +#import "PlacardView.h" + +// Import QuartzCore for animations +#import + + +@implementation MoveMeView + +@synthesize placardView; + + +/* + If the view is stored in the nib file, when it's unarchived it's sent -initWithCoder:. + This is the case in the example as provided. See also initWithFrame:. +*/ +- (id)initWithCoder:(NSCoder *)coder { + + self = [super initWithCoder:coder]; + if (self) { + [self setUpPlacardView]; + } + return self; +} + +/* + If you were to create the view programmatically, you would use initWithFrame:. + You want to make sure the placard view is set up in this case as well (as in initWithCoder:). + */ +- (id)initWithFrame:(CGRect)frame { + + self = [super initWithFrame:frame]; + if (self) { + [self setUpPlacardView]; + } + return self; +} + + +- (void)setUpPlacardView { + // Create the placard view -- its init method calculates its frame based on its image + PlacardView *aPlacardView = [[PlacardView alloc] init]; + self.placardView = aPlacardView; + [aPlacardView release]; + placardView.center = self.center; + [self addSubview:placardView]; +} + + + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + + // We only support single touches, so anyObject retrieves just that touch from touches + UITouch *touch = [touches anyObject]; + + // Only move the placard view if the touch was in the placard view + if ([touch view] != placardView) { + // In case of a double tap outside the placard view, update the placard's display string + if ([touch tapCount] == 2) { + [placardView setupNextDisplayString]; + } + return; + } + // Animate the first touch + CGPoint touchPoint = [touch locationInView:self]; + [self animateFirstTouchAtPoint:touchPoint]; +} + + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + + UITouch *touch = [touches anyObject]; + + // If the touch was in the placardView, move the placardView to its location + if ([touch view] == placardView) { + CGPoint location = [touch locationInView:self]; + placardView.center = location; + return; + } +} + + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + + UITouch *touch = [touches anyObject]; + + // If the touch was in the placardView, bounce it back to the center + if ([touch view] == placardView) { + // Disable user interaction so subsequent touches don't interfere with animation + self.userInteractionEnabled = NO; + [self animatePlacardViewToCenter]; + return; + } +} + + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + + /* + To impose as little impact on the device as possible, simply set the placard view's center and transformation to the original values. + */ + placardView.center = self.center; + placardView.transform = CGAffineTransformIdentity; +} + + +/* + First of two possible implementations of animateFirstTouchAtPoint: illustrating different behaviors. + To choose the second, replace '1' with '0' below. + */ + +#if 1 + +- (void)growAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { + +#define MOVE_ANIMATION_DURATION_SECONDS 0.15 + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS]; + placardView.transform = CGAffineTransformMakeScale(1.1f, 1.1f); + /* + Move the placardView to under the touch. + We passed the location wrapped in an NSValue as the context. + Get the point from the value, then release the value because we retained it in touchesBegan:withEvent:. + */ + NSValue *touchPointValue = (NSValue *)context; + placardView.center = [touchPointValue CGPointValue]; + [touchPointValue release]; + [UIView commitAnimations]; +} + +- (void)animateFirstTouchAtPoint:(CGPoint)touchPoint { + /* + "Pulse" the placard view by scaling up then down, then move the placard to under the finger. + + This illustrates using UIView's built-in animation. We want, though, to animate the same property (transform) twice -- first to scale up, then to shrink. You can't animate the same property more than once using the built-in animation -- the last one wins. So we'll set a delegate action to be invoked after the first animation has finished. It will complete the sequence. + Note that we can pass information -- in this case, the using the context. The context needs to be a pointer. A convenient way to pass a CGPoint here is to wrap it in an NSValue object. However, the value returned from valueWithCGPoint is autoreleased. Normally this wouldn't be an issue because typically if you need to use the value later you store it as an instance variable using an accessor method that retains it, or pass it to another object which retains it. In this case, though, it's being passed as a void * parameter, and it's not retained by the UIView class. By the time the delegate method is called, therefore, the autorelease pool will have been popped and the value would no longer be valid. To address this problem, retain the value here, and release it in the delegate method. + */ + +#define GROW_ANIMATION_DURATION_SECONDS 0.15 + + NSValue *touchPointValue = [[NSValue valueWithCGPoint:touchPoint] retain]; + [UIView beginAnimations:nil context:touchPointValue]; + [UIView setAnimationDuration:GROW_ANIMATION_DURATION_SECONDS]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(growAnimationDidStop:finished:context:)]; + CGAffineTransform transform = CGAffineTransformMakeScale(1.2f, 1.2f); + placardView.transform = transform; + [UIView commitAnimations]; +} + +#else + +/* + Alternate behavior. + The preceding implementation grows the placard in place then moves it to the new location and shrinks it at the same time. An alternative is to move the placard for the total duration of the grow and shrink operations; this gives a smoother effect. + + */ + +- (void)animateFirstTouchAtPoint:(CGPoint)touchPoint { + +#define GROW_ANIMATION_DURATION_SECONDS 0.15 +#define SHRINK_ANIMATION_DURATION_SECONDS 0.15 + + /* + Create two separate animations, the first for the grow, which uses a delegate method as before to start an animation for the shrink operation. The second animation here lasts for the total duration of the grow and shrink animations and is responsible for performing the move. + */ + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:GROW_ANIMATION_DURATION_SECONDS]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(growAnimationDidStop:finished:context:)]; + CGAffineTransform transform = CGAffineTransformMakeScale(1.2, 1.2); + placardView.transform = transform; + [UIView commitAnimations]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:GROW_ANIMATION_DURATION_SECONDS + SHRINK_ANIMATION_DURATION_SECONDS]; + placardView.center = touchPoint; + [UIView commitAnimations]; +} + + +- (void)growAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:SHRINK_ANIMATION_DURATION_SECONDS]; + placardView.transform = CGAffineTransformMakeScale(1.1, 1.1); + [UIView commitAnimations]; +} + + +#endif + + +- (void)animatePlacardViewToCenter { + + // Bounces the placard back to the center + + CALayer *welcomeLayer = placardView.layer; + + // Create a keyframe animation to follow a path back to the center + CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; + bounceAnimation.removedOnCompletion = NO; + + CGFloat animationDuration = 1.5f; + + + // Create the path for the bounces + CGMutablePathRef thePath = CGPathCreateMutable(); + + CGFloat midX = self.center.x; + CGFloat midY = self.center.y; + CGFloat originalOffsetX = placardView.center.x - midX; + CGFloat originalOffsetY = placardView.center.y - midY; + CGFloat offsetDivider = 4.0f; + + BOOL stopBouncing = NO; + + // Start the path at the placard's current location + CGPathMoveToPoint(thePath, NULL, placardView.center.x, placardView.center.y); + CGPathAddLineToPoint(thePath, NULL, midX, midY); + + // Add to the bounce path in decreasing excursions from the center + while (stopBouncing != YES) { + CGPathAddLineToPoint(thePath, NULL, midX + originalOffsetX/offsetDivider, midY + originalOffsetY/offsetDivider); + CGPathAddLineToPoint(thePath, NULL, midX, midY); + + offsetDivider += 4; + animationDuration += 1/offsetDivider; + if ((abs(originalOffsetX/offsetDivider) < 6) && (abs(originalOffsetY/offsetDivider) < 6)) { + stopBouncing = YES; + } + } + + bounceAnimation.path = thePath; + bounceAnimation.duration = animationDuration; + CGPathRelease(thePath); + + // Create a basic animation to restore the size of the placard + CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; + transformAnimation.removedOnCompletion = YES; + transformAnimation.duration = animationDuration; + transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; + + + // Create an animation group to combine the keyframe and basic animations + CAAnimationGroup *theGroup = [CAAnimationGroup animation]; + + // Set self as the delegate to allow for a callback to reenable user interaction + theGroup.delegate = self; + theGroup.duration = animationDuration; + theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + + theGroup.animations = [NSArray arrayWithObjects:bounceAnimation, transformAnimation, nil]; + + + // Add the animation group to the layer + [welcomeLayer addAnimation:theGroup forKey:@"animatePlacardViewToCenter"]; + + // Set the placard view's center and transformation to the original values in preparation for the end of the animation + placardView.center = self.center; + placardView.transform = CGAffineTransformIdentity; +} + + +- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { + //Animation delegate method called when the animation's finished: + // restore the transform and reenable user interaction + placardView.transform = CGAffineTransformIdentity; + self.userInteractionEnabled = YES; +} + + +- (void)dealloc { + [placardView release]; + [super dealloc]; +} + +@end diff --git a/MoveMe/Classes/PlacardView.h b/MoveMe/Classes/PlacardView.h new file mode 100644 index 0000000..6199d52 --- /dev/null +++ b/MoveMe/Classes/PlacardView.h @@ -0,0 +1,69 @@ + /* + File: PlacardView.h + Abstract: Displays a UIImage with text superimposed. + + Version: 2.10 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface PlacardView : UIView { + UIImage *placardImage; + + NSString *currentDisplayString; + CGFloat fontSize; + CGSize textSize; + + NSArray *displayStrings; + NSUInteger displayStringsIndex; +} + +@property (nonatomic, retain) UIImage *placardImage; +@property (nonatomic, retain) NSString *currentDisplayString; +@property (nonatomic, retain) NSArray *displayStrings; + +// Initializer for this object +- (id)init; + +- (void)setupNextDisplayString; + +@end diff --git a/MoveMe/Classes/PlacardView.m b/MoveMe/Classes/PlacardView.m new file mode 100644 index 0000000..0189aa8 --- /dev/null +++ b/MoveMe/Classes/PlacardView.m @@ -0,0 +1,138 @@ +/* + File: PlacardView.m + Abstract: Displays a UIImage with text superimposed. + + Version: 2.10 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PlacardView.h" + +@implementation PlacardView + +@synthesize placardImage; +@synthesize currentDisplayString; +@synthesize displayStrings; + + +- (id)init { + // Retrieve the image for the view and determine its size + UIImage *image = [UIImage imageNamed:@"Placard.png"]; + CGRect frame = CGRectMake(0, 0, image.size.width, image.size.height); + + // Set self's frame to encompass the image + self = [self initWithFrame:frame]; + if (self) { + + self.opaque = NO; + placardImage = image; + + // Load the display strings + NSString *path = [[NSBundle mainBundle] pathForResource:@"DisplayStrings" ofType:@"txt"]; + NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF16BigEndianStringEncoding error:NULL]; + self.displayStrings = [string componentsSeparatedByString:@"\n"]; + displayStringsIndex = 0; + [self setupNextDisplayString]; + } + return self; +} + + +- (void)dealloc { + [placardImage release]; + [currentDisplayString release]; + [displayStrings release]; + [super dealloc]; +} + + +#define STRING_INDENT 20 + +- (void)drawRect:(CGRect)rect { + + // Draw the placard at 0, 0 + [placardImage drawAtPoint:(CGPointMake(0.0f, 0.0f))]; + + /* + Draw the current display string. + Typically you would use a UILabel, but this example serves to illustrate the UIKit extensions to NSString. + The text is drawn center of the view twice - first slightly offset in black, then in white -- to give an embossed appearance. + The size of the font and text are calculated in setupNextDisplayString. + */ + + // Find point at which to draw the string so it will be in the center of the view + CGFloat x = self.bounds.size.width/2 - textSize.width/2; + CGFloat y = self.bounds.size.height/2 - textSize.height/2; + CGPoint point; + + // Get the font of the appropriate size + UIFont *font = [UIFont systemFontOfSize:fontSize]; + + [[UIColor blackColor] set]; + point = CGPointMake(x, y + 0.5f); + [currentDisplayString drawAtPoint:point forWidth:(self.bounds.size.width-STRING_INDENT) withFont:font fontSize:fontSize lineBreakMode:UILineBreakModeMiddleTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; + + [[UIColor whiteColor] set]; + point = CGPointMake(x, y); + [currentDisplayString drawAtPoint:point forWidth:(self.bounds.size.width-STRING_INDENT) withFont:font fontSize:fontSize lineBreakMode:UILineBreakModeMiddleTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; +} + + +- (void)setupNextDisplayString { + + // Get the string at the current index, then increment the index + self.currentDisplayString = [displayStrings objectAtIndex:displayStringsIndex]; + displayStringsIndex++; + if (displayStringsIndex >= [displayStrings count]) { + displayStringsIndex = 0; + } + + UIFont *font = [UIFont systemFontOfSize:24]; + // Precalculate size of text and size of font so that text fits inside placard + textSize = [currentDisplayString sizeWithFont:font minFontSize:9.0f actualFontSize:&fontSize forWidth:(self.bounds.size.width-STRING_INDENT) lineBreakMode:UILineBreakModeMiddleTruncation]; + + [self setNeedsDisplay]; +} + + +@end diff --git a/MoveMe/DisplayStrings.txt b/MoveMe/DisplayStrings.txt new file mode 100644 index 0000000..f8bdf9a Binary files /dev/null and b/MoveMe/DisplayStrings.txt differ diff --git a/MoveMe/Info.plist b/MoveMe/Info.plist new file mode 100644 index 0000000..ac96cf1 --- /dev/null +++ b/MoveMe/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.9 + UIStatusBarHidden + + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/MoveMe/MoveMe.xcodeproj/project.pbxproj b/MoveMe/MoveMe.xcodeproj/project.pbxproj new file mode 100755 index 0000000..319fbbc --- /dev/null +++ b/MoveMe/MoveMe.xcodeproj/project.pbxproj @@ -0,0 +1,365 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1825967911D13202000B79F7 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1825967611D13202000B79F7 /* Default.png */; }; + 1825967B11D13202000B79F7 /* Placard.png in Resources */ = {isa = PBXBuildFile; fileRef = 1825967811D13202000B79F7 /* Placard.png */; }; + 1825968311D13209000B79F7 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1825967E11D13209000B79F7 /* MainWindow.xib */; }; + 1825968411D13209000B79F7 /* MoveMeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1825968011D13209000B79F7 /* MoveMeView.xib */; }; + 18AD6C4211D5740F005232E4 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C3B11D5740F005232E4 /* Icon-72.png */; }; + 18AD6C4311D5740F005232E4 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C3C11D5740F005232E4 /* Icon-Small-50.png */; }; + 18AD6C4411D5740F005232E4 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C3D11D5740F005232E4 /* Icon-Small.png */; }; + 18AD6C4511D5740F005232E4 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C3E11D5740F005232E4 /* Icon-Small@2x.png */; }; + 18AD6C4611D5740F005232E4 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C3F11D5740F005232E4 /* Icon.png */; }; + 18AD6C4711D5740F005232E4 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C4011D5740F005232E4 /* Icon@2x.png */; }; + 18AD6C4811D5740F005232E4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6C4111D5740F005232E4 /* iTunesArtwork */; }; + 1D3623260D0F684500981E51 /* MoveMeAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MoveMeAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 280F00580D616E660055FFEA /* PlacardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 280F00560D616E660055FFEA /* PlacardView.m */; }; + 28D255B50D58154B00D6FA53 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D255B40D58154B00D6FA53 /* QuartzCore.framework */; }; + 28D918A60DCB9CEF00DA1262 /* MoveMeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D918A50DCB9CEF00DA1262 /* MoveMeView.m */; }; + 5326AF8E12ADAA630034CF2A /* DisplayStrings.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5326AF8D12ADAA630034CF2A /* DisplayStrings.txt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1825967611D13202000B79F7 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 1825967811D13202000B79F7 /* Placard.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Placard.png; path = images/Placard.png; sourceTree = ""; }; + 1825967F11D13209000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 1825968111D13209000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MoveMeView.xib; sourceTree = ""; }; + 18AD6C3B11D5740F005232E4 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18AD6C3C11D5740F005232E4 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18AD6C3D11D5740F005232E4 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18AD6C3E11D5740F005232E4 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18AD6C3F11D5740F005232E4 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18AD6C4011D5740F005232E4 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18AD6C4111D5740F005232E4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* MoveMeAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveMeAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* MoveMeAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MoveMeAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* MoveMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MoveMe.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 280F00560D616E660055FFEA /* PlacardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlacardView.m; sourceTree = ""; }; + 280F00570D616E660055FFEA /* PlacardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlacardView.h; sourceTree = ""; }; + 28D255B40D58154B00D6FA53 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 28D918A40DCB9CEF00DA1262 /* MoveMeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveMeView.h; sourceTree = ""; }; + 28D918A50DCB9CEF00DA1262 /* MoveMeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MoveMeView.m; sourceTree = ""; }; + 28F1A76A0DC933EE00332FD8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* MoveMe_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveMe_Prefix.pch; sourceTree = ""; }; + 5326AF8D12ADAA630034CF2A /* DisplayStrings.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DisplayStrings.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 28D255B50D58154B00D6FA53 /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* MoveMeAppDelegate.h */, + 1D3623250D0F684500981E51 /* MoveMeAppDelegate.m */, + 28D918A40DCB9CEF00DA1262 /* MoveMeView.h */, + 28D918A50DCB9CEF00DA1262 /* MoveMeView.m */, + 280F00570D616E660055FFEA /* PlacardView.h */, + 280F00560D616E660055FFEA /* PlacardView.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MoveMe.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28F1A76A0DC933EE00332FD8 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* MoveMe_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18AD6C3B11D5740F005232E4 /* Icon-72.png */, + 18AD6C3C11D5740F005232E4 /* Icon-Small-50.png */, + 18AD6C3D11D5740F005232E4 /* Icon-Small.png */, + 18AD6C3E11D5740F005232E4 /* Icon-Small@2x.png */, + 18AD6C3F11D5740F005232E4 /* Icon.png */, + 18AD6C4011D5740F005232E4 /* Icon@2x.png */, + 18AD6C4111D5740F005232E4 /* iTunesArtwork */, + 1825967E11D13209000B79F7 /* MainWindow.xib */, + 1825968011D13209000B79F7 /* MoveMeView.xib */, + 1825967611D13202000B79F7 /* Default.png */, + 1825967811D13202000B79F7 /* Placard.png */, + 8D1107310486CEB800E47090 /* Info.plist */, + 5326AF8D12ADAA630034CF2A /* DisplayStrings.txt */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 28D255B40D58154B00D6FA53 /* QuartzCore.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MoveMe */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MoveMe" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MoveMe; + productName = MoveMe; + productReference = 1D6058910D05DD3D006BFB54 /* MoveMe.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MoveMe" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MoveMe */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1825967911D13202000B79F7 /* Default.png in Resources */, + 1825967B11D13202000B79F7 /* Placard.png in Resources */, + 1825968311D13209000B79F7 /* MainWindow.xib in Resources */, + 1825968411D13209000B79F7 /* MoveMeView.xib in Resources */, + 18AD6C4211D5740F005232E4 /* Icon-72.png in Resources */, + 18AD6C4311D5740F005232E4 /* Icon-Small-50.png in Resources */, + 18AD6C4411D5740F005232E4 /* Icon-Small.png in Resources */, + 18AD6C4511D5740F005232E4 /* Icon-Small@2x.png in Resources */, + 18AD6C4611D5740F005232E4 /* Icon.png in Resources */, + 18AD6C4711D5740F005232E4 /* Icon@2x.png in Resources */, + 18AD6C4811D5740F005232E4 /* iTunesArtwork in Resources */, + 5326AF8E12ADAA630034CF2A /* DisplayStrings.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* MoveMeAppDelegate.m in Sources */, + 280F00580D616E660055FFEA /* PlacardView.m in Sources */, + 28D918A60DCB9CEF00DA1262 /* MoveMeView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 1825967E11D13209000B79F7 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 1825967F11D13209000B79F7 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 1825968011D13209000B79F7 /* MoveMeView.xib */ = { + isa = PBXVariantGroup; + children = ( + 1825968111D13209000B79F7 /* en */, + ); + name = MoveMeView.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MoveMe_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = MoveMe; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MoveMe_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = MoveMe; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + SDKROOT = iphoneos; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MoveMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MoveMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MoveMe/MoveMe_Prefix.pch b/MoveMe/MoveMe_Prefix.pch new file mode 100644 index 0000000..feec71b --- /dev/null +++ b/MoveMe/MoveMe_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'MoveMe' target in the 'MoveMe' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/MoveMe/ReadMe.txt b/MoveMe/ReadMe.txt new file mode 100644 index 0000000..e2ee5af --- /dev/null +++ b/MoveMe/ReadMe.txt @@ -0,0 +1,96 @@ +### MoveMe ### + +================================================================================ +DESCRIPTION: + +This application illustrates simple drawing, touch handling, and animation using UIKit and Core Animation. + +The main class of interest is MoveMeView. An instance of MoveMeView is created in the MainWindow nib file as a subview of the window. MoveMeView creates an instance of PlacardView which displays text superimposed over an image, and adds the placard view as a subview of itself. +If you touch inside the placard, the placard is animated in two ways: its transform is changed such that it appears to pulse, and it is moved such that its center is directly under the touch. +If you move your finger, MoveMeView moves the placard so that it remains centered under the touch. When the touch ends, the placard is animated back to the center of the screen, and its original (identity) transform restored. + +The UIView methods implemented by MoveMeView that relate to touch handling are: + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event + +These in turn invoke other methods to perform the animation. The sample illustrates two forms of animation: + +- (void)animateFirstTouchAtPoint:(CGPoint)touchPoint shows you how to use UIView's built-in animation with a delegate. Two slightly different implementations are provided to illustrate different animation behaviors. + +- (void)animatePlacardViewToCenter shows how to implement explicit animation using CAKeyframeAnimation. + +Further details are given in comments in the code. + + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.2 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +Classes/MoveMeAppDelegate.h +Classes/MoveMeAppDelegate.m +Simple application delegate that sets up a window and view controller. + +Classes/MoveMeView.h +Classes/MoveMeView.m +Contains a (placard) view that can be moved by touch. Illustrates handling touches and two styles of animation. + +Classes/PlacardView.h +Classes/PlacardView.m +Displays a UIImage with text superimposed. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 2.10 +- Upgraded to iOS 4.2 SDK, DisplayStrings now included in project, now checking for more GCC warnings. + +Version 2.9 +- Added CFBundleIconFiles in Info.plist. + +Version 2.8 +- Upgraded project to build with the iOS 4.0 SDK. + +Version 2.7 +- Corrected a memory leak where a CGPath was not released. + +Version 2.6 +- Updated for and tested with iPhone OS 2.0. First public release. + +Version 2.5 +- Updated the bundle identifier. + +Version 2.4 +- Updated for Beta 6. +- Added LSRequiresIPhoneOS flag to Info.plist file. +- Added touchesCanceled method to MoveMeView. +- Updated the Default image. + +Version 2.3 +- Updated for Beta 5. +- Moved the MoveMeView to a separate nib file; added a view controller to manage the view. +- The window is now displayed by the application delegate. + +Version 2.2 +- Updated for Beta 4. +- Minor change to artwork. +- The application window is displayed using the Visible At Launch flag in the MainWindow xib file (previously it was sent makeKeyAndVisible in applicationDidFinishLaunching:). +- The bounce animation path is changed. + +Version 2.1 +- Updated for Beta 3 +- Updated to use a nib file to create the application window and the instance of MoveMeView. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/MoveMe/en.lproj/MainWindow.xib b/MoveMe/en.lproj/MainWindow.xib new file mode 100644 index 0000000..a93aaf7 --- /dev/null +++ b/MoveMe/en.lproj/MainWindow.xib @@ -0,0 +1,172 @@ + + + + 512 + 9C7010 + 658 + 949.26 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + window + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + MoveMeAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{386, 330}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MoveMeAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 11 + + + + YES + + MoveMeAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/MoveMeAppDelegate.h + + + + + 0 + MoveMe.xcodeproj + 3 + + diff --git a/MoveMe/en.lproj/MoveMeView.xib b/MoveMe/en.lproj/MoveMeView.xib new file mode 100644 index 0000000..b0b00fa --- /dev/null +++ b/MoveMe/en.lproj/MoveMeView.xib @@ -0,0 +1,135 @@ + + + + 512 + 9C7010 + 658 + 949.26 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 268 + {320, 480} + + + 3 + MC4zMzAwMDAwMQA + + + + + + YES + + + view + + + + 3 + + + + + YES + + 0 + + YES + + + + + + 1 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + + + YES + UIViewController + UIResponder + MoveMeView + {{509, 297}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 3 + + + + YES + + MoveMeView + UIView + + IBProjectSource + Classes/MoveMeView.h + + + + + 0 + MoveMe.xcodeproj + 3 + + diff --git a/MoveMe/images/Default.png b/MoveMe/images/Default.png new file mode 100644 index 0000000..ef5f2bd Binary files /dev/null and b/MoveMe/images/Default.png differ diff --git a/MoveMe/images/Icon-72.png b/MoveMe/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/MoveMe/images/Icon-72.png differ diff --git a/MoveMe/images/Icon-Small-50.png b/MoveMe/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/MoveMe/images/Icon-Small-50.png differ diff --git a/MoveMe/images/Icon-Small.png b/MoveMe/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/MoveMe/images/Icon-Small.png differ diff --git a/MoveMe/images/Icon-Small@2x.png b/MoveMe/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/MoveMe/images/Icon-Small@2x.png differ diff --git a/MoveMe/images/Icon.png b/MoveMe/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/MoveMe/images/Icon.png differ diff --git a/MoveMe/images/Icon@2x.png b/MoveMe/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/MoveMe/images/Icon@2x.png differ diff --git a/MoveMe/images/Placard.png b/MoveMe/images/Placard.png new file mode 100644 index 0000000..b9af23c Binary files /dev/null and b/MoveMe/images/Placard.png differ diff --git a/MoveMe/images/iTunesArtwork b/MoveMe/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/MoveMe/images/iTunesArtwork differ diff --git a/MoveMe/main.m b/MoveMe/main.m new file mode 100644 index 0000000..fe7e3c1 --- /dev/null +++ b/MoveMe/main.m @@ -0,0 +1,56 @@ + +/* + File: main.m + Abstract: Main file for the application. + + Version: 2.7 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/PageControl.zip b/PageControl.zip new file mode 100644 index 0000000..35101fb Binary files /dev/null and b/PageControl.zip differ diff --git a/PageControl/Classes/AppDelegate.h b/PageControl/Classes/AppDelegate.h new file mode 100644 index 0000000..f281321 --- /dev/null +++ b/PageControl/Classes/AppDelegate.h @@ -0,0 +1,62 @@ +/* + File: AppDelegate.h + Abstract: Application delegate for the universal PageControl sample (for both iPad and iPhone) + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class ContentController; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + ContentController *contentController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet ContentController *contentController; + +@end + diff --git a/PageControl/Classes/AppDelegate.m b/PageControl/Classes/AppDelegate.m new file mode 100644 index 0000000..b11cba7 --- /dev/null +++ b/PageControl/Classes/AppDelegate.m @@ -0,0 +1,76 @@ +/* + File: AppDelegate.m + Abstract: Application delegate for the universal PageControl sample (for both iPad and iPhone) + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "ContentController.h" + +@implementation AppDelegate + +@synthesize window, contentController; + +- (void)dealloc +{ + [window release]; + [contentController release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + NSString *nibTitle = @"PadContent"; + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) + { + nibTitle = @"PhoneContent"; + } + [[NSBundle mainBundle] loadNibNamed:nibTitle owner:self options:nil]; + + [self.window addSubview:self.contentController.view]; + [window makeKeyAndVisible]; +} + +@end diff --git a/PageControl/Classes/ContentController.h b/PageControl/Classes/ContentController.h new file mode 100644 index 0000000..5a7b6f7 --- /dev/null +++ b/PageControl/Classes/ContentController.h @@ -0,0 +1,59 @@ +/* + File: ContentController.h + Abstract: The generic content controller superclass. Subclasses are created for supporting differing devices. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface ContentController : NSObject +{ + NSArray *contentList; +} + +@property (nonatomic, retain) NSArray *contentList; + +- (UIView *)view; + +@end diff --git a/PageControl/Classes/ContentController.m b/PageControl/Classes/ContentController.m new file mode 100644 index 0000000..2111957 --- /dev/null +++ b/PageControl/Classes/ContentController.m @@ -0,0 +1,65 @@ +/* + File: ContentController.m + Abstract: The generic content controller superclass. Subclasses are created for supporting differing devices. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ContentController.h" + +@implementation ContentController + +@synthesize contentList; + +- (void)dealloc +{ + [contentList release]; + [super dealloc]; +} + +- (UIView *)view +{ + return nil; // subclasses need to override this with their own view property +} + +@end diff --git a/PageControl/Classes/DetailPopoverViewController.h b/PageControl/Classes/DetailPopoverViewController.h new file mode 100644 index 0000000..67be640 --- /dev/null +++ b/PageControl/Classes/DetailPopoverViewController.h @@ -0,0 +1,61 @@ +/* + File: DetailPopoverViewController.h + Abstract: View controller responsible for drawing iPad number content in a popover. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface DetailPopoverViewController : UIViewController +{ + UIImageView *numberImage; + UILabel *numberLabel; + UITextView *numberDetail; +} + +@property (nonatomic, retain) IBOutlet UIImageView *numberImage; +@property (nonatomic, retain) IBOutlet UILabel *numberLabel; +@property (nonatomic, retain) IBOutlet UITextView *numberDetail; + +@end diff --git a/PageControl/Classes/DetailPopoverViewController.m b/PageControl/Classes/DetailPopoverViewController.m new file mode 100644 index 0000000..9674979 --- /dev/null +++ b/PageControl/Classes/DetailPopoverViewController.m @@ -0,0 +1,84 @@ +/* + File: DetailPopoverViewController.m + Abstract: View controller responsible for drawing iPad number content in a popover. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "DetailPopoverViewController.h" + +@implementation DetailPopoverViewController + +@synthesize numberImage, numberLabel, numberDetail; + +// implement viewDidLoad to do additional setup after loading the view, typically from a nib +- (void)viewDidLoad +{ + [super viewDidLoad]; +} + +// override to allow orientations other than the default portrait orientation +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + + self.numberImage = nil; + self.numberLabel = nil; + self.numberDetail = nil; +} + +- (void)dealloc +{ + [numberImage release]; + [numberLabel release]; + [numberDetail release]; + + [super dealloc]; +} + +@end diff --git a/PageControl/Classes/MyViewController.h b/PageControl/Classes/MyViewController.h new file mode 100644 index 0000000..2a2fa0d --- /dev/null +++ b/PageControl/Classes/MyViewController.h @@ -0,0 +1,60 @@ +/* + File: MyViewController.h + Abstract: A controller for a single page of content. For this application, pages simply display text on a colored background. The colors are retrieved from a static color list. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + + +@interface MyViewController : UIViewController { + UILabel *pageNumberLabel; + int pageNumber; +} + +@property (nonatomic, retain) IBOutlet UILabel *pageNumberLabel; + +- (id)initWithPageNumber:(int)page; + +@end diff --git a/PageControl/Classes/MyViewController.m b/PageControl/Classes/MyViewController.m new file mode 100644 index 0000000..3667f97 --- /dev/null +++ b/PageControl/Classes/MyViewController.m @@ -0,0 +1,86 @@ +/* + File: MyViewController.m + Abstract: A controller for a single page of content. For this application, pages simply display text on a colored background. The colors are retrieved from a static color list. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MyViewController.h" + +static NSArray *__pageControlColorList = nil; + +@implementation MyViewController + +@synthesize pageNumberLabel; + +// Creates the color list the first time this method is invoked. Returns one color object from the list. ++ (UIColor *)pageControlColorWithIndex:(NSUInteger)index { + if (__pageControlColorList == nil) { + __pageControlColorList = [[NSArray alloc] initWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor magentaColor], + [UIColor blueColor], [UIColor orangeColor], [UIColor brownColor], [UIColor grayColor], nil]; + } + + // Mod the index by the list length to ensure access remains in bounds. + return [__pageControlColorList objectAtIndex:index % [__pageControlColorList count]]; +} + +// Load the view nib and initialize the pageNumber ivar. +- (id)initWithPageNumber:(int)page { + if (self = [super initWithNibName:@"MyView" bundle:nil]) { + pageNumber = page; + } + return self; +} + +- (void)dealloc { + [pageNumberLabel release]; + [super dealloc]; +} + +// Set the label and background color when the view has finished loading. +- (void)viewDidLoad { + pageNumberLabel.text = [NSString stringWithFormat:@"Page %d", pageNumber + 1]; + self.view.backgroundColor = [MyViewController pageControlColorWithIndex:pageNumber]; +} + +@end diff --git a/PageControl/Classes/iPad/DetailViewController.h b/PageControl/Classes/iPad/DetailViewController.h new file mode 100644 index 0000000..21ce1d9 --- /dev/null +++ b/PageControl/Classes/iPad/DetailViewController.h @@ -0,0 +1,81 @@ +/* + File: DetailViewController.h + Abstract: A view controller used for displaying a grid of Tile views for the iPad. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "PadContentController.h" +#import "Tile.h" + +#define TILE_ROWS 2 +#define TILE_COLUMNS 3 +#define TILE_COUNT (TILE_ROWS * TILE_COLUMNS) + +@class DetailPopoverViewController; + +@interface DetailViewController : UIViewController +{ + UINavigationBar *navBar; + + NSArray *contentList; + + UIPopoverController *popoverController; + DetailPopoverViewController *popoverViewController; + + CGRect savedPopoverRect; + +@private + CGRect tileFrame[TILE_COUNT]; + Tile* tileForFrame[TILE_COUNT]; +} + +@property (nonatomic, retain) IBOutlet UINavigationBar *navBar; + +@property (nonatomic, retain) UIPopoverController *popoverController; +@property (nonatomic, retain) DetailPopoverViewController *popoverViewController; + +@property (nonatomic, retain) NSArray *contentList; + +@end diff --git a/PageControl/Classes/iPad/DetailViewController.m b/PageControl/Classes/iPad/DetailViewController.m new file mode 100644 index 0000000..78d8a97 --- /dev/null +++ b/PageControl/Classes/iPad/DetailViewController.m @@ -0,0 +1,214 @@ +/* + File: DetailViewController.m + Abstract: A view controller used for displaying a grid of Tile views for the iPad. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "DetailViewController.h" +#import "DetailPopoverViewController.h" + + +#define TILE_WIDTH 225 +#define TILE_HEIGHT 320 +#define TILE_MARGIN 23 + +@interface DetailViewController () +- (void)createTiles; +@end + +@implementation DetailViewController + +@synthesize navBar, popoverController, popoverViewController, contentList; + + +#pragma mark - +#pragma mark View lifecycle + +// implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad +{ + self.view.backgroundColor = [UIColor colorWithRed:197.0/255.0 + green:204.0/255.0 + blue:211.0/255.0 + alpha:1.0]; + + [super viewDidLoad]; + + self.popoverViewController = [[[DetailPopoverViewController alloc] + initWithNibName:@"DetailPopoverViewController" bundle:nil] autorelease]; + + self.popoverController.popoverContentSize = [self.popoverViewController.view + sizeThatFits:CGSizeMake(512.0, 618.0)]; + + [self createTiles]; +} + +- (void)viewDidUnload +{ + // release any retained subviews of the main view + self.navBar = nil; + self.popoverViewController = nil; + + [super viewDidUnload]; +} + +- (void)dealloc +{ + [navBar release]; + [contentList release]; + + [popoverController release]; + [popoverViewController release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark Tile support + +// creates the grid of page views each containing the individual number content +- (void)createTiles +{ + for (int row = 0; row < TILE_ROWS; ++row) + { + for (int col = 0; col < TILE_COLUMNS; ++col) + { + int index = (row * TILE_COLUMNS) + col; + + CGRect frame = CGRectMake(TILE_MARGIN + col * (TILE_MARGIN + TILE_WIDTH), + TILE_MARGIN + row * (TILE_MARGIN + TILE_HEIGHT) + navBar.frame.size.height, + TILE_WIDTH, TILE_HEIGHT); + tileFrame[index] = frame; + + Tile *tile = [[Tile alloc] init]; + tile.tag = index + 1; + tileForFrame[index] = tile; + tile.frame = frame; + tile.backgroundColor = [UIColor whiteColor]; + + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)]; + tapGesture.numberOfTapsRequired = 1; + tapGesture.numberOfTouchesRequired = 1; + [tile addGestureRecognizer:tapGesture]; + [tapGesture release]; + + [self.view addSubview:tile]; + [tile release]; + } + } +} + +- (void)tapAction:(UIGestureRecognizer *)gestureRecognizer +{ + // get the number data for the tapped view, and set the UI elements according + // to what found in that NSDictionary: + // + NSDictionary *numberItem = [self.contentList objectAtIndex:gestureRecognizer.view.tag - 1]; + self.popoverViewController.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]]; + self.popoverViewController.numberLabel.text = [numberItem valueForKey:NameKey]; + self.popoverViewController.numberDetail.text = [numberItem valueForKey:TranslationsKey]; + + if (self.popoverController) + { + // dismiss the popover before releasing it + [self.popoverController dismissPopoverAnimated:YES]; + } + + // create and present popover + UIPopoverController *aPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.popoverViewController]; + self.popoverController = aPopoverController; + self.popoverController.delegate = self; + self.popoverController.popoverContentSize = self.popoverViewController.view.bounds.size; + + // setup the frame in which the popover can be presented slightly smaller its view frame + CGRect rect = gestureRecognizer.view.frame; + CGRect finalRect = CGRectInset(rect, 80.0, 80.0); + + savedPopoverRect = finalRect; + [self.popoverController presentPopoverFromRect:finalRect + inView:self.view + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:YES]; + [aPopoverController release]; +} + + +#pragma mark - +#pragma mark Rotation support + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +{ + if (self.popoverController) + { + // we finished rotating, if a popover is allocated, show it again in the new orientation + [self.popoverController presentPopoverFromRect:savedPopoverRect + inView:self.view + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:YES]; + } +} + +// Ensure that the view controller supports rotation and that the split view can therefore show in +// both portrait and landscape. +// +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + if (self.popoverController.popoverVisible) + [self.popoverController dismissPopoverAnimated:YES]; // as we rotate, dismiss the current popover + + return YES; +} + + +#pragma mark - +#pragma mark UIPopoverControllerDelegate + +- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController +{ + // the user dismissed the popover, so release it here + self.popoverController = nil; +} + +@end diff --git a/PageControl/Classes/iPad/PadContentController.h b/PageControl/Classes/iPad/PadContentController.h new file mode 100644 index 0000000..511f99c --- /dev/null +++ b/PageControl/Classes/iPad/PadContentController.h @@ -0,0 +1,64 @@ +/* + File: PadContentController.h + Abstract: Content controller used to manage the iPad user interface for this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ContentController.h" + +extern NSString *NameKey; +extern NSString *ImageKey; +extern NSString *TranslationsKey; + +@class DetailViewController; + +@interface PadContentController : ContentController +{ + DetailViewController *detailViewController; +} + +@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController; + +@end \ No newline at end of file diff --git a/PageControl/Classes/iPad/PadContentController.m b/PageControl/Classes/iPad/PadContentController.m new file mode 100644 index 0000000..202c453 --- /dev/null +++ b/PageControl/Classes/iPad/PadContentController.m @@ -0,0 +1,82 @@ +/* + File: PadContentController.m + Abstract: Content controller used to manage the iPad user interface for this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PadContentController.h" +#import "DetailViewController.h" +#import "AppDelegate.h" + +NSString *NameKey = @"nameKey"; +NSString *ImageKey = @"imageKey"; +NSString *TranslationsKey = @"translationsKey"; + + +@implementation PadContentController + +@synthesize detailViewController; + +- (void)awakeFromNib +{ + // load our data from a plist file inside our app bundle + NSString *path = [[NSBundle mainBundle] pathForResource:@"content_iPad" ofType:@"plist"]; + self.contentList = [NSArray arrayWithContentsOfFile:path]; + + self.detailViewController.contentList = self.contentList; +} + +- (void)dealloc +{ + [detailViewController release]; + + [super dealloc]; +} + +- (UIView *)view +{ + return self.detailViewController.view; +} + +@end diff --git a/PageControl/Classes/iPad/Tile.h b/PageControl/Classes/iPad/Tile.h new file mode 100644 index 0000000..a318b6b --- /dev/null +++ b/PageControl/Classes/iPad/Tile.h @@ -0,0 +1,51 @@ +/* + File: Tile.h + Abstract: Tile view for drawing our number content. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface Tile : UIView +{ } + +@end diff --git a/PageControl/Classes/iPad/Tile.m b/PageControl/Classes/iPad/Tile.m new file mode 100644 index 0000000..ead872b --- /dev/null +++ b/PageControl/Classes/iPad/Tile.m @@ -0,0 +1,68 @@ +/* + File: Tile.m + Abstract: Tile view for drawing our number content. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Tile.h" + +@implementation Tile + +- (void)drawRect:(CGRect)frame +{ + [super drawRect:frame]; + + UIFont *fontToUse = [UIFont boldSystemFontOfSize:100.0]; + + NSString *strToDraw = [NSString stringWithFormat:@"%ld", self.tag]; + + CGSize size = [strToDraw sizeWithFont:fontToUse]; + + CGRect textBounds = CGRectMake(self.bounds.origin.x + (self.bounds.size.width - size.width) / 2, + self.bounds.origin.y + (self.bounds.size.height - size.height) / 2, + size.width, size.height); + [strToDraw drawInRect:textBounds withFont:fontToUse]; +} + +@end diff --git a/PageControl/Classes/iPhone/MyViewController.h b/PageControl/Classes/iPhone/MyViewController.h new file mode 100644 index 0000000..b37d41a --- /dev/null +++ b/PageControl/Classes/iPhone/MyViewController.h @@ -0,0 +1,67 @@ +/* + File: MyViewController.h + Abstract: The root view controller for the iPhone design of this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface MyViewController : UIViewController +{ + UILabel *pageNumberLabel; + int pageNumber; + + UILabel *numberTitle; + UIImageView *numberImage; +} + +@property (nonatomic, retain) IBOutlet UILabel *pageNumberLabel; + +@property (nonatomic, retain) IBOutlet UILabel *numberTitle; +@property (nonatomic, retain) IBOutlet UIImageView *numberImage; + +- (id)initWithPageNumber:(int)page; + +@end diff --git a/PageControl/Classes/iPhone/MyViewController.m b/PageControl/Classes/iPhone/MyViewController.m new file mode 100644 index 0000000..992f399 --- /dev/null +++ b/PageControl/Classes/iPhone/MyViewController.m @@ -0,0 +1,79 @@ +/* + File: MyViewController.m + Abstract: The root view controller for the iPhone design of this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyViewController.h" + +@implementation MyViewController + +@synthesize pageNumberLabel, numberTitle, numberImage; + +// load the view nib and initialize the pageNumber ivar +- (id)initWithPageNumber:(int)page +{ + if (self = [super initWithNibName:@"MyView" bundle:nil]) + { + pageNumber = page; + } + return self; +} + +- (void)dealloc +{ + [pageNumberLabel release]; + [numberTitle release]; + [numberImage release]; + + [super dealloc]; +} + +// set the label and background color when the view has finished loading +- (void)viewDidLoad +{ + pageNumberLabel.text = [NSString stringWithFormat:@"Page %d", pageNumber + 1]; +} + +@end diff --git a/PageControl/Classes/iPhone/PhoneContentController.h b/PageControl/Classes/iPhone/PhoneContentController.h new file mode 100644 index 0000000..be31338 --- /dev/null +++ b/PageControl/Classes/iPhone/PhoneContentController.h @@ -0,0 +1,70 @@ +/* + File: PhoneContentController.h + Abstract: Content controller used to manage the iPhone user interface for this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +#import "ContentController.h" + +@interface PhoneContentController : ContentController +{ + UIScrollView *scrollView; + UIPageControl *pageControl; + NSMutableArray *viewControllers; + + // To be used when scrolls originate from the UIPageControl + BOOL pageControlUsed; +} + +@property (nonatomic, retain) IBOutlet UIScrollView *scrollView; +@property (nonatomic, retain) IBOutlet UIPageControl *pageControl; + +@property (nonatomic, retain) NSMutableArray *viewControllers; + +- (IBAction)changePage:(id)sender; + +@end \ No newline at end of file diff --git a/PageControl/Classes/iPhone/PhoneContentController.m b/PageControl/Classes/iPhone/PhoneContentController.m new file mode 100644 index 0000000..479e724 --- /dev/null +++ b/PageControl/Classes/iPhone/PhoneContentController.m @@ -0,0 +1,203 @@ +/* + File: PhoneContentController.m + Abstract: Content controller used to manage the iPhone user interface for this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PhoneContentController.h" +#import "AppDelegate.h" +#import "MyViewController.h" + +static NSUInteger kNumberOfPages = 6; + +static NSString *NameKey = @"nameKey"; +static NSString *ImageKey = @"imageKey"; + + +@interface ContentController (PrivateMethods) +- (void)loadScrollViewWithPage:(int)page; +- (void)scrollViewDidScroll:(UIScrollView *)sender; +@end + + +@implementation PhoneContentController + +@synthesize scrollView, pageControl, viewControllers; + +- (void)awakeFromNib +{ + // load our data from a plist file inside our app bundle + NSString *path = [[NSBundle mainBundle] pathForResource:@"content_iPhone" ofType:@"plist"]; + self.contentList = [NSArray arrayWithContentsOfFile:path]; + + // view controllers are created lazily + // in the meantime, load the array with placeholders which will be replaced on demand + NSMutableArray *controllers = [[NSMutableArray alloc] init]; + for (unsigned i = 0; i < kNumberOfPages; i++) + { + [controllers addObject:[NSNull null]]; + } + self.viewControllers = controllers; + [controllers release]; + + // a page is the width of the scroll view + scrollView.pagingEnabled = YES; + scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height); + scrollView.showsHorizontalScrollIndicator = NO; + scrollView.showsVerticalScrollIndicator = NO; + scrollView.scrollsToTop = NO; + scrollView.delegate = self; + + pageControl.numberOfPages = kNumberOfPages; + pageControl.currentPage = 0; + + // pages are created on demand + // load the visible page + // load the page on either side to avoid flashes when the user starts scrolling + // + [self loadScrollViewWithPage:0]; + [self loadScrollViewWithPage:1]; +} + +- (void)dealloc +{ + [viewControllers release]; + [scrollView release]; + [pageControl release]; + + [super dealloc]; +} + +- (UIView *)view +{ + return self.scrollView; +} + +- (void)loadScrollViewWithPage:(int)page +{ + if (page < 0) + return; + if (page >= kNumberOfPages) + return; + + // replace the placeholder if necessary + MyViewController *controller = [viewControllers objectAtIndex:page]; + if ((NSNull *)controller == [NSNull null]) + { + controller = [[MyViewController alloc] initWithPageNumber:page]; + [viewControllers replaceObjectAtIndex:page withObject:controller]; + [controller release]; + } + + // add the controller's view to the scroll view + if (controller.view.superview == nil) + { + CGRect frame = scrollView.frame; + frame.origin.x = frame.size.width * page; + frame.origin.y = 0; + controller.view.frame = frame; + [scrollView addSubview:controller.view]; + + NSDictionary *numberItem = [self.contentList objectAtIndex:page]; + controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]]; + controller.numberTitle.text = [numberItem valueForKey:NameKey]; + } +} + +- (void)scrollViewDidScroll:(UIScrollView *)sender +{ + // We don't want a "feedback loop" between the UIPageControl and the scroll delegate in + // which a scroll event generated from the user hitting the page control triggers updates from + // the delegate method. We use a boolean to disable the delegate logic when the page control is used. + if (pageControlUsed) + { + // do nothing - the scroll was initiated from the page control, not the user dragging + return; + } + + // Switch the indicator when more than 50% of the previous/next page is visible + CGFloat pageWidth = scrollView.frame.size.width; + int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1; + pageControl.currentPage = page; + + // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling) + [self loadScrollViewWithPage:page - 1]; + [self loadScrollViewWithPage:page]; + [self loadScrollViewWithPage:page + 1]; + + // A possible optimization would be to unload the views+controllers which are no longer visible +} + +// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView +{ + pageControlUsed = NO; +} + +// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView +{ + pageControlUsed = NO; +} + +- (IBAction)changePage:(id)sender +{ + int page = pageControl.currentPage; + + // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling) + [self loadScrollViewWithPage:page - 1]; + [self loadScrollViewWithPage:page]; + [self loadScrollViewWithPage:page + 1]; + + // update the scroll view to the appropriate page + CGRect frame = scrollView.frame; + frame.origin.x = frame.size.width * page; + frame.origin.y = 0; + [scrollView scrollRectToVisible:frame animated:YES]; + + // Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above. + pageControlUsed = YES; +} + +@end diff --git a/PageControl/Default-Landscape.png b/PageControl/Default-Landscape.png new file mode 100644 index 0000000..2954291 Binary files /dev/null and b/PageControl/Default-Landscape.png differ diff --git a/PageControl/Default-Portrait.png b/PageControl/Default-Portrait.png new file mode 100644 index 0000000..4d0971b Binary files /dev/null and b/PageControl/Default-Portrait.png differ diff --git a/PageControl/Default.png b/PageControl/Default.png new file mode 100644 index 0000000..10caade Binary files /dev/null and b/PageControl/Default.png differ diff --git a/PageControl/Default@2x.png b/PageControl/Default@2x.png new file mode 100644 index 0000000..45379cf Binary files /dev/null and b/PageControl/Default@2x.png differ diff --git a/PageControl/Info.plist b/PageControl/Info.plist new file mode 100644 index 0000000..29494d8 --- /dev/null +++ b/PageControl/Info.plist @@ -0,0 +1,48 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleDocumentTypes + + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/PageControl/LargeImages/large_five.png b/PageControl/LargeImages/large_five.png new file mode 100644 index 0000000..063605d Binary files /dev/null and b/PageControl/LargeImages/large_five.png differ diff --git a/PageControl/LargeImages/large_four.png b/PageControl/LargeImages/large_four.png new file mode 100644 index 0000000..cecf4b5 Binary files /dev/null and b/PageControl/LargeImages/large_four.png differ diff --git a/PageControl/LargeImages/large_one.png b/PageControl/LargeImages/large_one.png new file mode 100644 index 0000000..d4e9eb3 Binary files /dev/null and b/PageControl/LargeImages/large_one.png differ diff --git a/PageControl/LargeImages/large_six.png b/PageControl/LargeImages/large_six.png new file mode 100644 index 0000000..2774db8 Binary files /dev/null and b/PageControl/LargeImages/large_six.png differ diff --git a/PageControl/LargeImages/large_three.png b/PageControl/LargeImages/large_three.png new file mode 100644 index 0000000..0698f54 Binary files /dev/null and b/PageControl/LargeImages/large_three.png differ diff --git a/PageControl/LargeImages/large_two.png b/PageControl/LargeImages/large_two.png new file mode 100644 index 0000000..4e374a7 Binary files /dev/null and b/PageControl/LargeImages/large_two.png differ diff --git a/PageControl/PageControl.xcodeproj/project.pbxproj b/PageControl/PageControl.xcodeproj/project.pbxproj new file mode 100755 index 0000000..f9af7cc --- /dev/null +++ b/PageControl/PageControl.xcodeproj/project.pbxproj @@ -0,0 +1,548 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 530BFB2B1243F76F007D91DD /* content_iPad.plist in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB231243F76F007D91DD /* content_iPad.plist */; }; + 530BFB2C1243F76F007D91DD /* DetailPopoverViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB251243F76F007D91DD /* DetailPopoverViewController.xib */; }; + 530BFB2D1243F76F007D91DD /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB271243F76F007D91DD /* DetailViewController.xib */; }; + 530BFB2E1243F76F007D91DD /* PadContent.xib in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB291243F76F007D91DD /* PadContent.xib */; }; + 530BFB351243F778007D91DD /* content_iPhone.plist in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB2F1243F778007D91DD /* content_iPhone.plist */; }; + 530BFB361243F778007D91DD /* MyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB311243F778007D91DD /* MyView.xib */; }; + 530BFB371243F778007D91DD /* PhoneContent.xib in Resources */ = {isa = PBXBuildFile; fileRef = 530BFB331243F778007D91DD /* PhoneContent.xib */; }; + 532161021263B5AD00CE2C97 /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 532161001263B5AD00CE2C97 /* Default-Landscape.png */; }; + 532161031263B5AD00CE2C97 /* Default-Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 532161011263B5AD00CE2C97 /* Default-Portrait.png */; }; + 5321611A1263B76600CE2C97 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 532161191263B76600CE2C97 /* Default.png */; }; + 534E1D291123562800EB729D /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 534E1D271123562800EB729D /* MainWindow.xib */; }; + 534E1D471123580700EB729D /* ContentController.m in Sources */ = {isa = PBXBuildFile; fileRef = 534E1D461123580700EB729D /* ContentController.m */; }; + 534E1DB811235B2500EB729D /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53CEA3431118C75500058645 /* DetailViewController.m */; }; + 534E1DBA11235B2B00EB729D /* PadContentController.m in Sources */ = {isa = PBXBuildFile; fileRef = 538B41C01118DD92004F50A9 /* PadContentController.m */; }; + 535140DF112C9BF800167F51 /* Tile.m in Sources */ = {isa = PBXBuildFile; fileRef = 535140DE112C9BF800167F51 /* Tile.m */; }; + 53514207112CA5B000167F51 /* DetailPopoverViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53514206112CA5B000167F51 /* DetailPopoverViewController.m */; }; + 53643F00111A342B0076F355 /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53643EF8111A34070076F355 /* MyViewController.m */; }; + 5395844C112C8AC3009625EE /* large_five.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958446112C8AC3009625EE /* large_five.png */; }; + 5395844D112C8AC3009625EE /* large_four.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958447112C8AC3009625EE /* large_four.png */; }; + 5395844E112C8AC3009625EE /* large_one.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958448112C8AC3009625EE /* large_one.png */; }; + 5395844F112C8AC3009625EE /* large_six.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958449112C8AC3009625EE /* large_six.png */; }; + 53958450112C8AC3009625EE /* large_three.png in Resources */ = {isa = PBXBuildFile; fileRef = 5395844A112C8AC3009625EE /* large_three.png */; }; + 53958451112C8AC3009625EE /* large_two.png in Resources */ = {isa = PBXBuildFile; fileRef = 5395844B112C8AC3009625EE /* large_two.png */; }; + 53958458112C8AD5009625EE /* small_five.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958452112C8AD5009625EE /* small_five.png */; }; + 53958459112C8AD5009625EE /* small_four.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958453112C8AD5009625EE /* small_four.png */; }; + 5395845A112C8AD5009625EE /* small_one.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958454112C8AD5009625EE /* small_one.png */; }; + 5395845B112C8AD5009625EE /* small_six.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958455112C8AD5009625EE /* small_six.png */; }; + 5395845C112C8AD5009625EE /* small_three.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958456112C8AD5009625EE /* small_three.png */; }; + 5395845D112C8AD5009625EE /* small_two.png in Resources */ = {isa = PBXBuildFile; fileRef = 53958457112C8AD5009625EE /* small_two.png */; }; + 53CEA3B21118CB5600058645 /* PhoneContentController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53CEA3B11118CB5600058645 /* PhoneContentController.m */; }; + 53E214E41265003C0028355A /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214DC1265003C0028355A /* Default.png */; }; + 53E214E51265003C0028355A /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214DD1265003C0028355A /* Icon-72.png */; }; + 53E214E61265003C0028355A /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214DE1265003C0028355A /* Icon-Small-50.png */; }; + 53E214E71265003C0028355A /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214DF1265003C0028355A /* Icon-Small.png */; }; + 53E214E81265003C0028355A /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214E01265003C0028355A /* Icon-Small@2x.png */; }; + 53E214E91265003C0028355A /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214E11265003C0028355A /* Icon.png */; }; + 53E214EA1265003C0028355A /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E214E21265003C0028355A /* Icon@2x.png */; }; + 53E214EB1265003C0028355A /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 53E214E31265003C0028355A /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* PageControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PageControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 530BFB241243F76F007D91DD /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/content_iPad.plist; sourceTree = ""; }; + 530BFB261243F76F007D91DD /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailPopoverViewController.xib; sourceTree = ""; }; + 530BFB281243F76F007D91DD /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController.xib; sourceTree = ""; }; + 530BFB2A1243F76F007D91DD /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PadContent.xib; sourceTree = ""; }; + 530BFB301243F778007D91DD /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/content_iPhone.plist; sourceTree = ""; }; + 530BFB321243F778007D91DD /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MyView.xib; sourceTree = ""; }; + 530BFB341243F778007D91DD /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PhoneContent.xib; sourceTree = ""; }; + 532161001263B5AD00CE2C97 /* Default-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape.png"; sourceTree = ""; }; + 532161011263B5AD00CE2C97 /* Default-Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait.png"; sourceTree = ""; }; + 532161191263B76600CE2C97 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 534E1D281123562800EB729D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 534E1D451123580700EB729D /* ContentController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentController.h; sourceTree = ""; }; + 534E1D461123580700EB729D /* ContentController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentController.m; sourceTree = ""; }; + 535140DD112C9BF800167F51 /* Tile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tile.h; path = iPad/Tile.h; sourceTree = ""; }; + 535140DE112C9BF800167F51 /* Tile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Tile.m; path = iPad/Tile.m; sourceTree = ""; }; + 53514205112CA5B000167F51 /* DetailPopoverViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailPopoverViewController.h; sourceTree = ""; }; + 53514206112CA5B000167F51 /* DetailPopoverViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailPopoverViewController.m; sourceTree = ""; }; + 535B494A111A048600A22460 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53643EF7111A34070076F355 /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MyViewController.h; path = iPhone/MyViewController.h; sourceTree = ""; }; + 53643EF8111A34070076F355 /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MyViewController.m; path = iPhone/MyViewController.m; sourceTree = ""; }; + 538B41221118DA41004F50A9 /* PhoneContentController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhoneContentController.h; path = iPhone/PhoneContentController.h; sourceTree = ""; }; + 538B41231118DA49004F50A9 /* PadContentController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PadContentController.h; path = iPad/PadContentController.h; sourceTree = ""; }; + 538B41C01118DD92004F50A9 /* PadContentController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PadContentController.m; path = iPad/PadContentController.m; sourceTree = ""; }; + 53958446112C8AC3009625EE /* large_five.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = large_five.png; sourceTree = ""; }; + 53958447112C8AC3009625EE /* large_four.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = large_four.png; sourceTree = ""; }; + 53958448112C8AC3009625EE /* large_one.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = large_one.png; sourceTree = ""; }; + 53958449112C8AC3009625EE /* large_six.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = large_six.png; sourceTree = ""; }; + 5395844A112C8AC3009625EE /* large_three.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = large_three.png; sourceTree = ""; }; + 5395844B112C8AC3009625EE /* large_two.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = large_two.png; sourceTree = ""; }; + 53958452112C8AD5009625EE /* small_five.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = small_five.png; sourceTree = ""; }; + 53958453112C8AD5009625EE /* small_four.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = small_four.png; sourceTree = ""; }; + 53958454112C8AD5009625EE /* small_one.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = small_one.png; sourceTree = ""; }; + 53958455112C8AD5009625EE /* small_six.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = small_six.png; sourceTree = ""; }; + 53958456112C8AD5009625EE /* small_three.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = small_three.png; sourceTree = ""; }; + 53958457112C8AD5009625EE /* small_two.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = small_two.png; sourceTree = ""; }; + 53CEA3421118C75500058645 /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailViewController.h; path = iPad/DetailViewController.h; sourceTree = ""; }; + 53CEA3431118C75500058645 /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailViewController.m; path = iPad/DetailViewController.m; sourceTree = ""; }; + 53CEA3B11118CB5600058645 /* PhoneContentController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PhoneContentController.m; path = iPhone/PhoneContentController.m; sourceTree = ""; }; + 53E214DC1265003C0028355A /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 53E214DD1265003C0028355A /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 53E214DE1265003C0028355A /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 53E214DF1265003C0028355A /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 53E214E01265003C0028355A /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 53E214E11265003C0028355A /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 53E214E21265003C0028355A /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 53E214E31265003C0028355A /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 534E1D451123580700EB729D /* ContentController.h */, + 534E1D461123580700EB729D /* ContentController.m */, + 53CEA39C1118CAFF00058645 /* PhoneContent */, + 5337E331111233D6007C5B53 /* PadContent */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* PageControl.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 29B97315FDCFA39411CA2CEA /* Main */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Main */ = { + isa = PBXGroup; + children = ( + 535B494A111A048600A22460 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = Main; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 53E214DB1265003C0028355A /* images */, + 5322DF0511235E0000A944DE /* PhoneContent */, + 5322DF0211235DE600A944DE /* PadContent */, + 534E1D271123562800EB729D /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 532161191263B76600CE2C97 /* Default.png */, + 532161001263B5AD00CE2C97 /* Default-Landscape.png */, + 532161011263B5AD00CE2C97 /* Default-Portrait.png */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5322DF0211235DE600A944DE /* PadContent */ = { + isa = PBXGroup; + children = ( + 530BFB231243F76F007D91DD /* content_iPad.plist */, + 530BFB291243F76F007D91DD /* PadContent.xib */, + 530BFB251243F76F007D91DD /* DetailPopoverViewController.xib */, + 530BFB271243F76F007D91DD /* DetailViewController.xib */, + 533409F7111A085600E04869 /* LargeImages */, + ); + name = PadContent; + sourceTree = ""; + }; + 5322DF0511235E0000A944DE /* PhoneContent */ = { + isa = PBXGroup; + children = ( + 530BFB2F1243F778007D91DD /* content_iPhone.plist */, + 530BFB331243F778007D91DD /* PhoneContent.xib */, + 530BFB311243F778007D91DD /* MyView.xib */, + 533409FE111A085600E04869 /* SmallImages */, + ); + name = PhoneContent; + sourceTree = ""; + }; + 533409F7111A085600E04869 /* LargeImages */ = { + isa = PBXGroup; + children = ( + 53958448112C8AC3009625EE /* large_one.png */, + 5395844B112C8AC3009625EE /* large_two.png */, + 5395844A112C8AC3009625EE /* large_three.png */, + 53958447112C8AC3009625EE /* large_four.png */, + 53958446112C8AC3009625EE /* large_five.png */, + 53958449112C8AC3009625EE /* large_six.png */, + ); + path = LargeImages; + sourceTree = ""; + }; + 533409FE111A085600E04869 /* SmallImages */ = { + isa = PBXGroup; + children = ( + 53958454112C8AD5009625EE /* small_one.png */, + 53958457112C8AD5009625EE /* small_two.png */, + 53958456112C8AD5009625EE /* small_three.png */, + 53958453112C8AD5009625EE /* small_four.png */, + 53958452112C8AD5009625EE /* small_five.png */, + 53958455112C8AD5009625EE /* small_six.png */, + ); + path = SmallImages; + sourceTree = ""; + }; + 5337E331111233D6007C5B53 /* PadContent */ = { + isa = PBXGroup; + children = ( + 538B41231118DA49004F50A9 /* PadContentController.h */, + 538B41C01118DD92004F50A9 /* PadContentController.m */, + 53CEA3421118C75500058645 /* DetailViewController.h */, + 53CEA3431118C75500058645 /* DetailViewController.m */, + 53514205112CA5B000167F51 /* DetailPopoverViewController.h */, + 53514206112CA5B000167F51 /* DetailPopoverViewController.m */, + 535140DD112C9BF800167F51 /* Tile.h */, + 535140DE112C9BF800167F51 /* Tile.m */, + ); + name = PadContent; + sourceTree = ""; + }; + 53CEA39C1118CAFF00058645 /* PhoneContent */ = { + isa = PBXGroup; + children = ( + 538B41221118DA41004F50A9 /* PhoneContentController.h */, + 53CEA3B11118CB5600058645 /* PhoneContentController.m */, + 53643EF7111A34070076F355 /* MyViewController.h */, + 53643EF8111A34070076F355 /* MyViewController.m */, + ); + name = PhoneContent; + sourceTree = ""; + }; + 53E214DB1265003C0028355A /* images */ = { + isa = PBXGroup; + children = ( + 53E214DC1265003C0028355A /* Default.png */, + 53E214DD1265003C0028355A /* Icon-72.png */, + 53E214DE1265003C0028355A /* Icon-Small-50.png */, + 53E214DF1265003C0028355A /* Icon-Small.png */, + 53E214E01265003C0028355A /* Icon-Small@2x.png */, + 53E214E11265003C0028355A /* Icon.png */, + 53E214E21265003C0028355A /* Icon@2x.png */, + 53E214E31265003C0028355A /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* PageControl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "PageControl" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PageControl; + productName = LazyTable; + productReference = 1D6058910D05DD3D006BFB54 /* PageControl.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "PageControl" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* PageControl */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 534E1D291123562800EB729D /* MainWindow.xib in Resources */, + 5395844C112C8AC3009625EE /* large_five.png in Resources */, + 5395844D112C8AC3009625EE /* large_four.png in Resources */, + 5395844E112C8AC3009625EE /* large_one.png in Resources */, + 5395844F112C8AC3009625EE /* large_six.png in Resources */, + 53958450112C8AC3009625EE /* large_three.png in Resources */, + 53958451112C8AC3009625EE /* large_two.png in Resources */, + 53958458112C8AD5009625EE /* small_five.png in Resources */, + 53958459112C8AD5009625EE /* small_four.png in Resources */, + 5395845A112C8AD5009625EE /* small_one.png in Resources */, + 5395845B112C8AD5009625EE /* small_six.png in Resources */, + 5395845C112C8AD5009625EE /* small_three.png in Resources */, + 5395845D112C8AD5009625EE /* small_two.png in Resources */, + 530BFB2B1243F76F007D91DD /* content_iPad.plist in Resources */, + 530BFB2C1243F76F007D91DD /* DetailPopoverViewController.xib in Resources */, + 530BFB2D1243F76F007D91DD /* DetailViewController.xib in Resources */, + 530BFB2E1243F76F007D91DD /* PadContent.xib in Resources */, + 530BFB351243F778007D91DD /* content_iPhone.plist in Resources */, + 530BFB361243F778007D91DD /* MyView.xib in Resources */, + 530BFB371243F778007D91DD /* PhoneContent.xib in Resources */, + 532161021263B5AD00CE2C97 /* Default-Landscape.png in Resources */, + 532161031263B5AD00CE2C97 /* Default-Portrait.png in Resources */, + 5321611A1263B76600CE2C97 /* Default.png in Resources */, + 53E214E41265003C0028355A /* Default.png in Resources */, + 53E214E51265003C0028355A /* Icon-72.png in Resources */, + 53E214E61265003C0028355A /* Icon-Small-50.png in Resources */, + 53E214E71265003C0028355A /* Icon-Small.png in Resources */, + 53E214E81265003C0028355A /* Icon-Small@2x.png in Resources */, + 53E214E91265003C0028355A /* Icon.png in Resources */, + 53E214EA1265003C0028355A /* Icon@2x.png in Resources */, + 53E214EB1265003C0028355A /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 53CEA3B21118CB5600058645 /* PhoneContentController.m in Sources */, + 53643F00111A342B0076F355 /* MyViewController.m in Sources */, + 534E1D471123580700EB729D /* ContentController.m in Sources */, + 534E1DB811235B2500EB729D /* DetailViewController.m in Sources */, + 534E1DBA11235B2B00EB729D /* PadContentController.m in Sources */, + 535140DF112C9BF800167F51 /* Tile.m in Sources */, + 53514207112CA5B000167F51 /* DetailPopoverViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 530BFB231243F76F007D91DD /* content_iPad.plist */ = { + isa = PBXVariantGroup; + children = ( + 530BFB241243F76F007D91DD /* en */, + ); + name = content_iPad.plist; + sourceTree = ""; + }; + 530BFB251243F76F007D91DD /* DetailPopoverViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 530BFB261243F76F007D91DD /* en */, + ); + name = DetailPopoverViewController.xib; + sourceTree = ""; + }; + 530BFB271243F76F007D91DD /* DetailViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 530BFB281243F76F007D91DD /* en */, + ); + name = DetailViewController.xib; + sourceTree = ""; + }; + 530BFB291243F76F007D91DD /* PadContent.xib */ = { + isa = PBXVariantGroup; + children = ( + 530BFB2A1243F76F007D91DD /* en */, + ); + name = PadContent.xib; + sourceTree = ""; + }; + 530BFB2F1243F778007D91DD /* content_iPhone.plist */ = { + isa = PBXVariantGroup; + children = ( + 530BFB301243F778007D91DD /* en */, + ); + name = content_iPhone.plist; + sourceTree = ""; + }; + 530BFB311243F778007D91DD /* MyView.xib */ = { + isa = PBXVariantGroup; + children = ( + 530BFB321243F778007D91DD /* en */, + ); + name = MyView.xib; + sourceTree = ""; + }; + 530BFB331243F778007D91DD /* PhoneContent.xib */ = { + isa = PBXVariantGroup; + children = ( + 530BFB341243F778007D91DD /* en */, + ); + name = PhoneContent.xib; + sourceTree = ""; + }; + 534E1D271123562800EB729D /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 534E1D281123562800EB729D /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + PRODUCT_NAME = PageControl; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos3.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + PRODUCT_NAME = PageControl; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos3.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "PageControl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "PageControl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/PageControl/Prefix.pch b/PageControl/Prefix.pch new file mode 100644 index 0000000..81fc785 --- /dev/null +++ b/PageControl/Prefix.pch @@ -0,0 +1,51 @@ +/* + File: Prefix.pch + Abstract: Prefix header for all source files of the 'PageControl' target in the 'PageControl' project. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/PageControl/ReadMe.txt b/PageControl/ReadMe.txt new file mode 100644 index 0000000..993299a --- /dev/null +++ b/PageControl/ReadMe.txt @@ -0,0 +1,25 @@ +PageControl + +This application primarily demonstrates use of UIScrollView's paging functionality to use horizontal scrolling as a mechanism for navigating between different pages of content. With the iPad, this type of user interface is not really necessary since the screen is larger allowing for more content and detailed information. + +Designed as a universal application for both iPhone and iPad, this sample shows how to use two different sets of content, depending on which device the sample is running. The idea is that the iPhone uses a "smaller" set of images, while the iPad uses a "larger" set of images plus more detailed information. �As a universal app this sample shows how to factor out these two types of UI and data based on the device.� + +For the iPhone - The app uses UIScrollView and UIPageControl to move between pages. +For the iPad - The app uses one large UIView with tiled pages, each page presenting a popover to display more detailed information. + +Based on the UIDevice idiom type, the UIApplication delegate loads two different set of nib files, one for the iPhone and the other for the iPad. �To direct this kind of UI factoring, the sample uses a base class called "ContentController". Subclasses of ContentController are used to support each device. Hence, the app loads two different user interfaces (or xibs) as well as two different sets of data driven by the ContentController. + +Build Requirements +iOS SDK 4.1 and later. + +Runtime Requirements +iOS OS 3.2 and later. + +Changes from Previous Versions +1.4 Updated as a universal application for iPhone and iPad. +1.3 Upgraded project to build with the iOS 4.0 SDK. +1.2 Fixed issue where scrolling by dragging the UIScrollView did not update the UIPageControl. +1.1 Added a check to eliminate flicker of the UIPageControl when it is used to change pages. +1.0 Initial version. + +Copyright (C) 2010 Apple Inc. All rights reserved. diff --git a/PageControl/SmallImages/small_five.png b/PageControl/SmallImages/small_five.png new file mode 100644 index 0000000..948ec2d Binary files /dev/null and b/PageControl/SmallImages/small_five.png differ diff --git a/PageControl/SmallImages/small_four.png b/PageControl/SmallImages/small_four.png new file mode 100644 index 0000000..225ac2d Binary files /dev/null and b/PageControl/SmallImages/small_four.png differ diff --git a/PageControl/SmallImages/small_one.png b/PageControl/SmallImages/small_one.png new file mode 100644 index 0000000..90a932d Binary files /dev/null and b/PageControl/SmallImages/small_one.png differ diff --git a/PageControl/SmallImages/small_six.png b/PageControl/SmallImages/small_six.png new file mode 100644 index 0000000..a8cb5a9 Binary files /dev/null and b/PageControl/SmallImages/small_six.png differ diff --git a/PageControl/SmallImages/small_three.png b/PageControl/SmallImages/small_three.png new file mode 100644 index 0000000..bd60c5f Binary files /dev/null and b/PageControl/SmallImages/small_three.png differ diff --git a/PageControl/SmallImages/small_two.png b/PageControl/SmallImages/small_two.png new file mode 100644 index 0000000..ab81418 Binary files /dev/null and b/PageControl/SmallImages/small_two.png differ diff --git a/PageControl/en.lproj/DetailPopoverViewController.xib b/PageControl/en.lproj/DetailPopoverViewController.xib new file mode 100644 index 0000000..fae0341 --- /dev/null +++ b/PageControl/en.lproj/DetailPopoverViewController.xib @@ -0,0 +1,510 @@ + + + + 800 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + + YES + + + 306 + {{20, 56}, {472, 423}} + + 1 + NO + IBIPadFramework + + + + 266 + {{20, 487}, {472, 111}} + + + 1 + MSAxIDEgMAA + + NO + YES + YES + IBIPadFramework + NO + NO + NO + NO + NO + + + Helvetica + 24 + 16 + + + 2 + IBCocoaTouchFramework + + + + + 290 + {{20, 15}, {472, 37}} + + NO + YES + 7 + NO + IBIPadFramework + + + Helvetica-Bold + 36 + 16 + + + 1 + MCAwIDAAA + + + 1 + 10 + 1 + + + {512, 618} + + + 1 + MC43Mzk3OTU5MjMyIDAuNzM5Nzk1OTIzMiAwLjczOTc5NTkyMzIAA + + IBIPadFramework + + + + + YES + + + view + + + + 116 + + + + numberImage + + + + 120 + + + + numberDetail + + + + 121 + + + + numberLabel + + + + 122 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 104 + + + YES + + + + + + + + 117 + + + + + 118 + + + + + 119 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 104.IBEditorWindowLastContentRect + 104.IBPluginDependency + 104.IBViewEditorWindowController.showingLayoutRectangles + 117.IBPluginDependency + 118.IBPluginDependency + 119.IBPluginDependency + + + YES + DetailPopoverViewController + UIResponder + {{141, 340}, {512, 618}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 122 + + + + YES + + DetailPopoverViewController + UIViewController + + YES + + YES + numberDetail + numberImage + numberLabel + + + YES + UITextView + UIImageView + UILabel + + + + YES + + YES + numberDetail + numberImage + numberLabel + + + YES + + numberDetail + UITextView + + + numberImage + UIImageView + + + numberLabel + UILabel + + + + + IBProjectSource + Classes/DetailPopoverViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITextView.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../PageControl.xcodeproj + 3 + 123 + + diff --git a/PageControl/en.lproj/DetailViewController.xib b/PageControl/en.lproj/DetailViewController.xib new file mode 100644 index 0000000..6352c7f --- /dev/null +++ b/PageControl/en.lproj/DetailViewController.xib @@ -0,0 +1,465 @@ + + + + 800 + 10C540 + 760 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 82 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 290 + {768, 44} + + IBIPadFramework + + YES + + + + IBIPadFramework + + + + + {768, 1024} + + + 3 + MQA + + 2 + + + IBIPadFramework + + + + + YES + + + view + + + + 105 + + + + navBar + + + + 106 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 104 + + + YES + + + + + + 69 + + + YES + + + + + + 70 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 104.IBEditorWindowLastContentRect + 104.IBPluginDependency + 104.IBViewEditorWindowController.showingLayoutRectangles + 69.IBPluginDependency + 70.IBPluginDependency + + + YES + DetailViewController + UIResponder + {{0, 4}, {783, 1002}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 115 + + + + YES + + DetailViewController + UIViewController + + YES + + YES + navBar + numberDetail + numberImage + numberTitle + + + YES + UINavigationBar + UITextView + UIImageView + UILabel + + + + IBProjectSource + Classes/iPad/DetailViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITextView.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../PageControl.xcodeproj + 3 + 82 + + diff --git a/PageControl/en.lproj/MainWindow.xib b/PageControl/en.lproj/MainWindow.xib new file mode 100644 index 0000000..e4c049b --- /dev/null +++ b/PageControl/en.lproj/MainWindow.xib @@ -0,0 +1,312 @@ + + + + 528 + 10C540 + 760 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 82 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + + YES + + + delegate + + + + 26 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + AppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 30 + + + + YES + + AppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/AppDelegate.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIResponder + NSObject + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../PageControl.xcodeproj + 3 + 82 + + diff --git a/PageControl/en.lproj/MyView.xib b/PageControl/en.lproj/MyView.xib new file mode 100644 index 0000000..11b7283 --- /dev/null +++ b/PageControl/en.lproj/MyView.xib @@ -0,0 +1,481 @@ + + + + 768 + 10C540 + 760 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 82 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 268 + + YES + + + 290 + {{20, 1}, {280, 15}} + + NO + YES + NO + IBCocoaTouchFramework + 1 + + Helvetica + 10 + 16 + + + 1 + MCAwIDAAA + + + 1 + 10 + 2 + + + + 292 + {{10, 49}, {300, 387}} + + YES + 1 + NO + IBCocoaTouchFramework + + + + 292 + {{10, 25}, {300, 21}} + + NO + YES + 7 + NO + IBCocoaTouchFramework + + + Helvetica-Bold + 18 + 16 + + + + 1 + 10 + 1 + + + {320, 480} + + + 1 + MSAxIDEAA + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 7 + + + + pageNumberLabel + + + + 16 + + + + numberImage + + + + 17 + + + + numberTitle + + + + 18 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 5 + + + + + 9 + + + + + 10 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 1.IBViewEditorWindowController.showingLayoutRectangles + 10.IBPluginDependency + 5.IBPluginDependency + 9.IBPluginDependency + + + YES + MyViewController + UIResponder + {{205, 427}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 18 + + + + YES + + MyViewController + UIViewController + + YES + + YES + numberImage + numberTitle + pageNumberLabel + + + YES + UIImageView + UILabel + UILabel + + + + IBProjectSource + Classes/iPhone/MyViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../PageControl.xcodeproj + 3 + 82 + + diff --git a/PageControl/en.lproj/PadContent.xib b/PageControl/en.lproj/PadContent.xib new file mode 100644 index 0000000..034f134 --- /dev/null +++ b/PageControl/en.lproj/PadContent.xib @@ -0,0 +1,508 @@ + + + + 528 + 10C540 + 760 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 82 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 1316 + + {768, 1024} + + 1 + MSAxIDEAA + + NO + NO + + 2 + + IBIPadFramework + + + IBIPadFramework + + + + DetailViewController + IBIPadFramework + + + + + YES + + + window + + + + 58 + + + + contentController + + + + 59 + + + + detailViewController + + + + 63 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + -2 + + + + + 26 + + + PadContentController + + + 61 + + + DetailViewController + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBLastUsedUIStatusBarStylesToTargetRuntimesMap + 2.IBPluginDependency + 26.CustomClassName + 26.IBPluginDependency + 61.CustomClassName + 61.IBPluginDependency + + + YES + AppDelegate + UIResponder + + YES + + + YES + + + {{673, 376}, {320, 480}} + + IBCocoaTouchFramework + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + PadContentController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DetailViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 63 + + + + YES + + AppDelegate + NSObject + + YES + + YES + contentController + window + + + YES + ContentController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + ContentController + NSObject + + IBProjectSource + Classes/ContentController.h + + + + DetailViewController + UIViewController + + YES + + YES + navBar + numberDetail + numberImage + numberTitle + + + YES + UINavigationBar + UITextView + UIImageView + UILabel + + + + IBProjectSource + Classes/iPad/DetailViewController.h + + + + PadContentController + ContentController + + detailViewController + DetailViewController + + + IBProjectSource + Classes/iPad/PadContentController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITextView.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../PageControl.xcodeproj + 3 + 82 + + diff --git a/PageControl/en.lproj/PhoneContent.xib b/PageControl/en.lproj/PhoneContent.xib new file mode 100644 index 0000000..89d76f2 --- /dev/null +++ b/PageControl/en.lproj/PhoneContent.xib @@ -0,0 +1,553 @@ + + + + 528 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + 1292 + + YES + + + 1298 + {{0, 20}, {320, 440}} + + + 1 + MSAxIDEAA + + NO + IBCocoaTouchFramework + + + + 1292 + {{0, 462}, {320, 18}} + + + 1 + MCAwIDAAA + + NO + NO + IBCocoaTouchFramework + + + + {320, 480} + + NO + NO + IBCocoaTouchFramework + YES + + + + + YES + + + scrollView + + + + 29 + + + + pageControl + + + + 30 + + + + contentController + + + + 32 + + + + window + + + + 33 + + + + changePage: + + + 13 + + 34 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 17 + + + PhoneContentController + + + 22 + + + YES + + + + + + + 23 + + + + + 24 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 17.CustomClassName + 17.IBPluginDependency + 22.IBAttributePlaceholdersKey + 22.IBEditorWindowLastContentRect + 22.IBPluginDependency + 22.IBViewEditorWindowController.showingLayoutRectangles + 23.CustomClassName + 23.IBPluginDependency + 24.CustomClassName + 24.IBPluginDependency + + + YES + AppDelegate + UIResponder + PhoneContentController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{363, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + UIPageControl + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIScrollView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 34 + + + + YES + + AppDelegate + NSObject + + YES + + YES + contentController + window + + + YES + ContentController + UIWindow + + + + YES + + YES + contentController + window + + + YES + + contentController + ContentController + + + window + UIWindow + + + + + IBProjectSource + Classes/AppDelegate.h + + + + ContentController + NSObject + + IBProjectSource + Classes/ContentController.h + + + + PhoneContentController + ContentController + + changePage: + id + + + changePage: + + changePage: + id + + + + YES + + YES + pageControl + scrollView + + + YES + UIPageControl + UIScrollView + + + + YES + + YES + pageControl + scrollView + + + YES + + pageControl + UIPageControl + + + scrollView + UIScrollView + + + + + IBProjectSource + Classes/iPhone/PhoneContentController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIPageControl + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIPageControl.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../PageControl.xcodeproj + 3 + 123 + + diff --git a/PageControl/en.lproj/content_iPad.plist b/PageControl/en.lproj/content_iPad.plist new file mode 100755 index 0000000..e5ea358 --- /dev/null +++ b/PageControl/en.lproj/content_iPad.plist @@ -0,0 +1,55 @@ + + + + + + + nameKey + Number One + imageKey + large_one.png + translationsKey + one, uno, 一个, én, en, een, un, eins, ένα, אחת, один + + + nameKey + Number Two + imageKey + large_two.png + translationsKey + two, dos, 二, to, två, twee, deux, zwei, δύο, שתיים, два + + + nameKey + Number Three + imageKey + large_three.png + translationsKey + three, tres, 三, tre, tre, drie, trois, drei, τρία, שלוש, три + + + nameKey + Number Four + imageKey + large_four.png + translationsKey + four, cuatro, 四, fire, fyra, vier, quatre, vier, τέσσερα, ארבע, четыре + + + nameKey + Number Five + imageKey + large_five.png + translationsKey + five, cinco, 五, fem, fem, vijf, cinq, fünf, πέντε, חמש, пять + + + nameKey + Number Six + imageKey + large_six.png + translationsKey + six, seis, 六, seks, sex, zes, six, sechs, έξι, שש, шесть + + + diff --git a/PageControl/en.lproj/content_iPhone.plist b/PageControl/en.lproj/content_iPhone.plist new file mode 100755 index 0000000..62ff54c --- /dev/null +++ b/PageControl/en.lproj/content_iPhone.plist @@ -0,0 +1,43 @@ + + + + + + + nameKey + Number One + imageKey + small_one.png + + + nameKey + Number Two + imageKey + small_two.png + + + nameKey + Number Three + imageKey + small_three.png + + + nameKey + Number Four + imageKey + small_four.png + + + nameKey + Number Five + imageKey + small_five.png + + + nameKey + Number Six + imageKey + small_six.png + + + diff --git a/PageControl/images/Default.png b/PageControl/images/Default.png new file mode 100644 index 0000000..3fe991f Binary files /dev/null and b/PageControl/images/Default.png differ diff --git a/PageControl/images/Icon-72.png b/PageControl/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/PageControl/images/Icon-72.png differ diff --git a/PageControl/images/Icon-Small-50.png b/PageControl/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/PageControl/images/Icon-Small-50.png differ diff --git a/PageControl/images/Icon-Small.png b/PageControl/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/PageControl/images/Icon-Small.png differ diff --git a/PageControl/images/Icon-Small@2x.png b/PageControl/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/PageControl/images/Icon-Small@2x.png differ diff --git a/PageControl/images/Icon.png b/PageControl/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/PageControl/images/Icon.png differ diff --git a/PageControl/images/Icon@2x.png b/PageControl/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/PageControl/images/Icon@2x.png differ diff --git a/PageControl/images/iTunesArtwork b/PageControl/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/PageControl/images/iTunesArtwork differ diff --git a/PageControl/main.m b/PageControl/main.m new file mode 100644 index 0000000..b4a56fe --- /dev/null +++ b/PageControl/main.m @@ -0,0 +1,55 @@ +/* + File: main.m + Abstract: Creates and launches the application. The MainWindow nib will be loaded and the application delegate object will be unarchived from it. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/Popovers.zip b/Popovers.zip new file mode 100644 index 0000000..46ca7c0 Binary files /dev/null and b/Popovers.zip differ diff --git a/Popovers/Classes/DetailViewController.h b/Popovers/Classes/DetailViewController.h new file mode 100644 index 0000000..83c3b4a --- /dev/null +++ b/Popovers/Classes/DetailViewController.h @@ -0,0 +1,89 @@ +/* + File: DetailViewController.h + Abstract: + Displays the detail view of the split view controller. This also contains buttons and a bar button item that all present popovers. + The detail view responds to orientation changes when popovers are visible and re-displays them in the new orientation. + The detail view is also responsible for ensuring that there are never multiple popovers visible at the same time. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface DetailViewController : UIViewController { + UIPopoverController *mainPopoverController; + UIToolbar *toolbar; + id detailItem; + // The popover for use inside of the detail view. + UIPopoverController *detailViewPopover; + // The popover for use from the navigation bar. + UIPopoverController *barButtonItemPopover; + // The custom button in the navigation bar over the detail view. + UIBarButtonItem *myBarButtonItem; + // Custom buttons inside of the detail view. + UIButton *button1; + UIButton *button2; + UIButton *button3; + UIButton *button4; + UIButton *button5; + // Keeping track of the last tapped button for showing the popover from the correct button on rotation. + id lastTappedButton; +} + +@property (nonatomic, retain) IBOutlet UIToolbar *toolbar; +@property (nonatomic, retain) id detailItem; +@property (nonatomic, retain) UIPopoverController *detailViewPopover; +@property (nonatomic, retain) UIPopoverController *barButtonItemPopover; +@property (nonatomic, retain) IBOutlet UIBarButtonItem *myBarButtonItem; +@property (nonatomic, retain) IBOutlet UIButton *button1; +@property (nonatomic, retain) IBOutlet UIButton *button2; +@property (nonatomic, retain) IBOutlet UIButton *button3; +@property (nonatomic, retain) IBOutlet UIButton *button4; +@property (nonatomic, retain) IBOutlet UIButton *button5; +@property (nonatomic, retain) id lastTappedButton; + +- (IBAction)showPopover:(id)sender; +- (IBAction)showPopoverFromBarButtonItem:(id)sender; + +@end diff --git a/Popovers/Classes/DetailViewController.m b/Popovers/Classes/DetailViewController.m new file mode 100644 index 0000000..54e8308 --- /dev/null +++ b/Popovers/Classes/DetailViewController.m @@ -0,0 +1,273 @@ +/* + File: DetailViewController.m + Abstract: + Displays the detail view of the split view controller. This also contains buttons and a bar button item that all present popovers. + The detail view responds to orientation changes when popovers are visible and re-displays them in the new orientation. + The detail view is also responsible for ensuring that there are never multiple popovers visible at the same time. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "DetailViewController.h" +#import "RootViewController.h" +#import "PopoverContentViewController.h" + +@interface DetailViewController () +@property (nonatomic, retain) UIPopoverController *mainPopoverController; +- (void)configureView; +@end + + +@implementation DetailViewController + +@synthesize toolbar, mainPopoverController, detailItem, detailViewPopover, barButtonItemPopover, myBarButtonItem, button1, button2, button3, button4, button5, lastTappedButton; + +#pragma mark - +#pragma mark Managing the detail item + +/* + When setting the detail item, update the view and dismiss the popover controller if it's showing. + */ +- (void)setDetailItem:(id)newDetailItem { + if (detailItem != newDetailItem) { + [detailItem release]; + detailItem = [newDetailItem retain]; + + // Update the view. + [self configureView]; + } + + if (mainPopoverController != nil) { + [mainPopoverController dismissPopoverAnimated:YES]; + } +} + + +- (void)configureView { + // Update the user interface for the detail item. +} + + +#pragma mark - +#pragma mark Split view support + +- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc { + barButtonItem.title = @"Master List"; + NSMutableArray *items = [[toolbar items] mutableCopy]; + [items insertObject:barButtonItem atIndex:0]; + [toolbar setItems:items animated:YES]; + [items release]; + self.mainPopoverController = pc; +} + + +// Called when the view is shown again in the split view, invalidating the button and popover controller. +- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { + NSMutableArray *items = [[toolbar items] mutableCopy]; + [items removeObjectAtIndex:0]; + [toolbar setItems:items animated:YES]; + [items release]; + self.mainPopoverController = nil; +} + + +// Called when the hidden view controller is about to be displayed in a popover. +- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController { + // Check to see if the popover presented from the "Tap" UIBarButtonItem is visible. + if ([barButtonItemPopover isPopoverVisible]) { + // Dismiss the popover. + [barButtonItemPopover dismissPopoverAnimated:YES]; + } +} + + +#pragma mark - +#pragma mark Rotation support + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { + // If the detail popover is presented, dismiss it. + if (detailViewPopover != nil) { + [detailViewPopover dismissPopoverAnimated:YES]; + } +} + + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + // If the last button tapped is not nil, present the popover from that button. + if (lastTappedButton != nil) { + [self showPopover:lastTappedButton]; + } +} + + +// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Layout all buttons in the detail view upon orientation change. + if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { + button1.frame = CGRectMake(20., 64., 160., 160.); + button2.frame = CGRectMake(588., 64., 160., 160.); + button3.frame = CGRectMake(304., 422., 160., 160.); + button4.frame = CGRectMake(20., 824., 160., 160.); + button5.frame = CGRectMake(588., 824., 160., 160.); + } + else { + button1.frame = CGRectMake(20., 64., 160., 160.); + button2.frame = CGRectMake(524., 64., 160., 160.); + button3.frame = CGRectMake(272., 311., 160., 160.); + button4.frame = CGRectMake(20., 568., 160., 160.); + button5.frame = CGRectMake(524., 568., 160., 160.); + } + + return YES; +} + + +#pragma mark - +#pragma mark View lifecycle + +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; + + PopoverContentViewController *content = [[PopoverContentViewController alloc] init]; + + // Setup the popover for use in the detail view. + detailViewPopover = [[UIPopoverController alloc] initWithContentViewController:content]; + detailViewPopover.popoverContentSize = CGSizeMake(320., 320.); + detailViewPopover.delegate = self; + + // Setup the popover for use from the navigation bar. + barButtonItemPopover = [[UIPopoverController alloc] initWithContentViewController:content]; + barButtonItemPopover.popoverContentSize = CGSizeMake(320., 320.); + barButtonItemPopover.delegate = self; + + [content release]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.mainPopoverController = nil; + self.detailViewPopover = nil; + self.barButtonItemPopover = nil; + self.button1 = nil; + self.button2 = nil; + self.button3 = nil; + self.button4 = nil; + self.button5 = nil; +} + + +- (void)dealloc { + [mainPopoverController release]; + [toolbar release]; + [detailItem release]; + [detailViewPopover release]; + [barButtonItemPopover release]; + [button1 release]; + [button2 release]; + [button3 release]; + [button4 release]; + [button5 release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark Popover controller delegates + +- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { + // If a popover is dismissed, set the last button tapped to nil. + lastTappedButton = nil; +} + + +#pragma mark - +#pragma mark DetailViewController methods + +- (IBAction)showPopover:(id)sender { + // Set the sender to a UIButton. + UIButton *tappedButton = (UIButton *)sender; + + // Present the popover from the button that was tapped in the detail view. + [detailViewPopover presentPopoverFromRect:tappedButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; + + // Set the last button tapped to the current button that was tapped. + lastTappedButton = sender; +} + + +- (IBAction)showPopoverFromBarButtonItem:(id)sender { + // Set the sender to a UIBarButtonItem. + UIBarButtonItem *tappedButton = (UIBarButtonItem *)sender; + + // If the master list popover is showing, dismiss it before presenting the popover from the bar button item. + if (mainPopoverController != nil) { + [mainPopoverController dismissPopoverAnimated:YES]; + } + + // If the popover is already showing from the bar button item, dismiss it. Otherwise, present it. + if (barButtonItemPopover.popoverVisible == NO) { + [barButtonItemPopover presentPopoverFromBarButtonItem:tappedButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; + } + else { + [barButtonItemPopover dismissPopoverAnimated:YES]; + } +} + + +@end diff --git a/Popovers/Classes/PopoverContentViewController.h b/Popovers/Classes/PopoverContentViewController.h new file mode 100644 index 0000000..f084ced --- /dev/null +++ b/Popovers/Classes/PopoverContentViewController.h @@ -0,0 +1,54 @@ +/* + File: PopoverContentViewController.h + Abstract: A view controller that is the contents of the popovers in this sample. In this example, the view controller only contains a label with text. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface PopoverContentViewController : UIViewController { + +} + +@end diff --git a/Popovers/Classes/PopoverContentViewController.m b/Popovers/Classes/PopoverContentViewController.m new file mode 100644 index 0000000..58f034a --- /dev/null +++ b/Popovers/Classes/PopoverContentViewController.m @@ -0,0 +1,101 @@ +/* + File: PopoverContentViewController.m + Abstract: A view controller that is the contents of the popovers in this sample. In this example, the view controller only contains a label with text. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PopoverContentViewController.h" + +@implementation PopoverContentViewController + +#pragma mark - +#pragma mark View lifecycle + +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; + + // Add a label to the popover's view controller. + UILabel *popoverLabel = [[UILabel alloc] initWithFrame:CGRectMake(0., 0., 320., 320.)]; + popoverLabel.text = @"POP!"; + popoverLabel.font = [UIFont boldSystemFontOfSize:100.]; + popoverLabel.textAlignment = UITextAlignmentCenter; + popoverLabel.textColor = [UIColor redColor]; + + [self.view addSubview:popoverLabel]; + + [popoverLabel release]; +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Overriden to allow any orientation. + return YES; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/Popovers/Classes/PopoversAppDelegate.h b/Popovers/Classes/PopoversAppDelegate.h new file mode 100644 index 0000000..7c730e7 --- /dev/null +++ b/Popovers/Classes/PopoversAppDelegate.h @@ -0,0 +1,65 @@ +/* + File: PopoversAppDelegate.h + Abstract: The application delegate sets up the initial view and makes the window visible. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class RootViewController; +@class DetailViewController; + +@interface PopoversAppDelegate : NSObject { + UIWindow *window; + UISplitViewController *splitViewController; + RootViewController *rootViewController; + DetailViewController *detailViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UISplitViewController *splitViewController; +@property (nonatomic, retain) IBOutlet RootViewController *rootViewController; +@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController; + +@end diff --git a/Popovers/Classes/PopoversAppDelegate.m b/Popovers/Classes/PopoversAppDelegate.m new file mode 100644 index 0000000..beceb05 --- /dev/null +++ b/Popovers/Classes/PopoversAppDelegate.m @@ -0,0 +1,87 @@ +/* + File: PopoversAppDelegate.m + Abstract: The application delegate sets up the initial view and makes the window visible. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PopoversAppDelegate.h" +#import "RootViewController.h" +#import "DetailViewController.h" + +@implementation PopoversAppDelegate + +@synthesize window, splitViewController, rootViewController, detailViewController; + +#pragma mark - +#pragma mark Application lifecycle + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Add the split view controller's view to the window and display. + [window addSubview:splitViewController.view]; + + // Make the window visible and first responder on launch. + // If you remove this, make sure you've set the UIWindow to Visible on Launch in Interface Builder. + [window makeKeyAndVisible]; + + return YES; +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Save data if appropriate +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [splitViewController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/Popovers/Classes/RootViewController.h b/Popovers/Classes/RootViewController.h new file mode 100644 index 0000000..df9e740 --- /dev/null +++ b/Popovers/Classes/RootViewController.h @@ -0,0 +1,58 @@ +/* + File: RootViewController.h + Abstract: Acts as the master list view controller for the split view controller and adds rows of placeholder items to the table view. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class DetailViewController; + +@interface RootViewController : UITableViewController { + DetailViewController *detailViewController; +} + +@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController; + +@end diff --git a/Popovers/Classes/RootViewController.m b/Popovers/Classes/RootViewController.m new file mode 100644 index 0000000..9cffbd2 --- /dev/null +++ b/Popovers/Classes/RootViewController.m @@ -0,0 +1,126 @@ +/* + File: RootViewController.m + Abstract: Acts as the master list view controller for the split view controller and adds rows of placeholder items to the table view. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "DetailViewController.h" + +@implementation RootViewController + +@synthesize detailViewController; + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewDidLoad { + [super viewDidLoad]; + self.clearsSelectionOnViewWillAppear = NO; + self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0); +} + + +// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + + +#pragma mark - +#pragma mark Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView { + // Return the number of sections. + return 1; +} + + +- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { + // Return the number of rows in the section. + return 10; +} + + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; + } + + // Configure the cell. + cell.textLabel.text = [NSString stringWithFormat:@"Row %i", indexPath.row]; + + return cell; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Relinquish ownership any cached data, images, etc. that aren't in use. +} + + +- (void)viewDidUnload { + // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand. + // For example: self.myOutlet = nil; +} + + +- (void)dealloc { + [detailViewController release]; + [super dealloc]; +} + + +@end + diff --git a/Popovers/Images/Default-Landscape.png b/Popovers/Images/Default-Landscape.png new file mode 100644 index 0000000..aeb39af Binary files /dev/null and b/Popovers/Images/Default-Landscape.png differ diff --git a/Popovers/Images/Default.png b/Popovers/Images/Default.png new file mode 100644 index 0000000..dcbc33b Binary files /dev/null and b/Popovers/Images/Default.png differ diff --git a/Popovers/Images/Icon-72.png b/Popovers/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/Popovers/Images/Icon-72.png differ diff --git a/Popovers/Images/Icon-Small-50.png b/Popovers/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/Popovers/Images/Icon-Small-50.png differ diff --git a/Popovers/Images/Icon-Small.png b/Popovers/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/Popovers/Images/Icon-Small.png differ diff --git a/Popovers/Images/iTunesArtwork b/Popovers/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/Popovers/Images/iTunesArtwork differ diff --git a/Popovers/Popovers-Info.plist b/Popovers/Popovers-Info.plist new file mode 100644 index 0000000..fdfaae8 --- /dev/null +++ b/Popovers/Popovers-Info.plist @@ -0,0 +1,41 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CFBundleIconFiles + + Icon-72.png + Icon-Small.png + Icon-Small-50.png + + + diff --git a/Popovers/Popovers.xcodeproj/behrens.mode1v3 b/Popovers/Popovers.xcodeproj/behrens.mode1v3 new file mode 100644 index 0000000..5be3976 --- /dev/null +++ b/Popovers/Popovers.xcodeproj/behrens.mode1v3 @@ -0,0 +1,1402 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + CB41BF9D11E4E8C10046A629 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-platform-popup + active-buildstyle-popup + NSToolbarFlexibleSpaceItem + clean + build-and-go + com.apple.ide.PBXToolbarStopButton + debugger-enable-breakpoints + NSToolbarFlexibleSpaceItem + get-info + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 256 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + 29B97315FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 7 + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {256, 919}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {273, 937}} + GroupTreeTableConfiguration + + MainColumn + 256 + + RubberWindowFrame + 0 50 1680 978 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 273pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + DetailViewController.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + DetailViewController.m + _historyCapacity + 0 + bookmark + CB41BFAF11E4FF8C0046A629 + history + + CB41BFAD11E4FF8C0046A629 + CB41BFAE11E4FF8C0046A629 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1402, 751}} + RubberWindowFrame + 0 50 1680 978 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 751pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 756}, {1402, 181}} + RubberWindowFrame + 0 50 1680 978 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 181pt + + + Proportion + 1402pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + CB41BF9B11E4E8C10046A629 + 1CE0B1FE06471DED0097A5F4 + CB41BF9C11E4E8C10046A629 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 2 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + CB41BFB011E4FF8C0046A629 + CB41BFB111E4FF8C0046A629 + 1C78EAAD065D492600B07095 + 1CD10A99069EF8BA00B06720 + CB41BF9E11E4E8C10046A629 + /Users/behrens/Sites/Sample Projects/Popovers/Popovers.xcodeproj + + WindowString + 0 50 1680 978 0 0 1680 1028 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 467 386 500 500 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 467 386 500 500 0 0 1680 1028 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + CB41BF9E11E4E8C10046A629 + CB41BF9F11E4E8C10046A629 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 467 386 500 500 0 0 1680 1028 + WindowToolGUID + CB41BF9E11E4E8C10046A629 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 185}} + {{316, 0}, {378, 185}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 185}} + {{0, 185}, {694, 196}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 185}} + RubberWindowFrame + 21 583 694 422 0 0 1680 1028 + + RubberWindowFrame + 21 583 694 422 0 0 1680 1028 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + CB41BFA611E4FC620046A629 + 1C162984064C10D400B95A72 + CB41BFA711E4FC620046A629 + CB41BFA811E4FC620046A629 + CB41BFA911E4FC620046A629 + CB41BFAA11E4FC620046A629 + CB41BFAB11E4FC620046A629 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 21 583 694 422 0 0 1680 1028 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 209}} + RubberWindowFrame + 21 755 650 250 0 0 1680 1028 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + CB41BFAC11E4FC620046A629 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 21 755 650 250 0 0 1680 1028 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/Popovers/Popovers.xcodeproj/jakebehrens.mode1v3 b/Popovers/Popovers.xcodeproj/jakebehrens.mode1v3 new file mode 100644 index 0000000..69aa17d --- /dev/null +++ b/Popovers/Popovers.xcodeproj/jakebehrens.mode1v3 @@ -0,0 +1,1426 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /iOS SDK 4.1 Beta 3/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 9F27AF7F121B464E00B77C4B + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 272 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + 29B97315FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + 9FC6A569126D0BED008D73BA + 9FC6A567126D0BED008D73BA + 9FA2EF5212241B6B001CD8C6 + 1C37FBAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 15 + 14 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {272, 760}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {289, 778}} + GroupTreeTableConfiguration + + MainColumn + 272 + + RubberWindowFrame + 0 59 1440 819 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 289pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + ReadMe.txt + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + ReadMe.txt + _historyCapacity + 0 + bookmark + 9FC6A584126D0C55008D73BA + history + + 9F27AF9D121B490D00B77C4B + 9FEDA5C9125E3E6300D0F59C + 9FEDA5CA125E3E6300D0F59C + 9FEDA5CB125E3E6300D0F59C + 9F2633A01263BCA600DA83F1 + 9F2633A11263BCA600DA83F1 + 9F2634481263D0B700DA83F1 + 9F2634491263D0B700DA83F1 + 9F26344A1263D0B700DA83F1 + 9F26344B1263D0B700DA83F1 + 9F26344C1263D0B700DA83F1 + 9F26344D1263D0B700DA83F1 + 9F26344E1263D0B700DA83F1 + 9F2634501263D0B700DA83F1 + 9F2634511263D0B700DA83F1 + 9F52A42E12664C0600E90460 + 9F52A42F12664C0600E90460 + 9FC6A57C126D0BFE008D73BA + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1146, 515}} + RubberWindowFrame + 0 59 1440 819 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 515pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 520}, {1146, 258}} + RubberWindowFrame + 0 59 1440 819 0 0 1440 878 + + Module + XCDetailModule + Proportion + 258pt + + + Proportion + 1146pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 9FC6A585126D0C55008D73BA + 1CE0B1FE06471DED0097A5F4 + 9FC6A586126D0C55008D73BA + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/iOS SDK 4.1 Beta 3/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 9F27AF80121B464E00B77C4B + /Users/jakebehrens/Code/Sample Code GM/Popovers/Popovers.xcodeproj + + WindowString + 0 59 1440 819 0 0 1440 878 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {845, 257}} + RubberWindowFrame + 372 259 845 539 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 257pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 262}, {845, 236}} + RubberWindowFrame + 372 259 845 539 0 0 1440 878 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 498pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 9F27AF80121B464E00B77C4B + 9FC6A587126D0C55008D73BA + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 372 259 845 539 0 0 1440 878 + WindowToolGUID + 9F27AF80121B464E00B77C4B + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 54 405 694 422 0 0 1440 878 + + RubberWindowFrame + 54 405 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 9FC6A573126D0BF6008D73BA + 1C162984064C10D400B95A72 + 9FC6A574126D0BF6008D73BA + 9FC6A575126D0BF6008D73BA + 9FC6A576126D0BF6008D73BA + 9FC6A577126D0BF6008D73BA + 9FC6A578126D0BF6008D73BA + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 54 405 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1426, 595}} + RubberWindowFrame + 72 105 1426 853 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 1426pt + + + Proportion + 595pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 600}, {1426, 212}} + RubberWindowFrame + 72 105 1426 853 0 0 1680 1028 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 812pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 9FE8960A121B57A000C4240B + 9FE8960B121B57A000C4240B + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 72 105 1426 853 0 0 1680 1028 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 209}} + RubberWindowFrame + 55 573 650 250 0 0 1440 878 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 9FC6A579126D0BF6008D73BA + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 55 573 650 250 0 0 1440 878 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 9FE8960D121B57A000C4240B + + GeometryConfiguration + + Frame + {{0, 0}, {500, 315}} + RubberWindowFrame + 72 602 500 356 0 0 1680 1028 + + Module + XCRefactoringModule + Proportion + 315pt + + + Proportion + 315pt + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + StatusbarIsVisible + + TableOfContents + + 9FE8960E121B57A000C4240B + 9FE8960F121B57A000C4240B + 9FE8960D121B57A000C4240B + + WindowString + 72 602 500 356 0 0 1680 1028 + WindowToolGUID + 9FE8960E121B57A000C4240B + WindowToolIsVisible + + + + + diff --git a/Popovers/Popovers.xcodeproj/project.pbxproj b/Popovers/Popovers.xcodeproj/project.pbxproj new file mode 100755 index 0000000..d0565b7 --- /dev/null +++ b/Popovers/Popovers.xcodeproj/project.pbxproj @@ -0,0 +1,332 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* PopoversAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* PopoversAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2804200B108E984D000629CD /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28042008108E984D000629CD /* RootViewController.m */; }; + 2804200C108E984D000629CD /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2804200A108E984D000629CD /* DetailViewController.m */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 9F26340A1263CAC300DA83F1 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9F2634091263CAC300DA83F1 /* ReadMe.txt */; }; + 9F337C1B12241D47008B0C1E /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F337C1912241D47008B0C1E /* Default-Landscape.png */; }; + 9F337C1C12241D47008B0C1E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F337C1A12241D47008B0C1E /* Default.png */; }; + 9FA2EF5712241B6B001CD8C6 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FA2EF5312241B6B001CD8C6 /* Icon-72.png */; }; + 9FA2EF5812241B6B001CD8C6 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FA2EF5412241B6B001CD8C6 /* Icon-Small-50.png */; }; + 9FA2EF5912241B6B001CD8C6 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FA2EF5512241B6B001CD8C6 /* Icon-Small.png */; }; + 9FA2EF5A12241B6B001CD8C6 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 9FA2EF5612241B6B001CD8C6 /* iTunesArtwork */; }; + 9FC6A56B126D0BED008D73BA /* DetailView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FC6A567126D0BED008D73BA /* DetailView.xib */; }; + 9FC6A56C126D0BED008D73BA /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FC6A569126D0BED008D73BA /* MainWindow.xib */; }; + F4B52CE811991C3100C6ED09 /* PopoverContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B52CE711991C3100C6ED09 /* PopoverContentViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* PopoversAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoversAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* PopoversAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PopoversAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* Popovers.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Popovers.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28042007108E984D000629CD /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28042008108E984D000629CD /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28042009108E984D000629CD /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + 2804200A108E984D000629CD /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* Popovers_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Popovers_Prefix.pch; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Popovers-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Popovers-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + 9F2634091263CAC300DA83F1 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 9F337C1912241D47008B0C1E /* Default-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape.png"; sourceTree = ""; }; + 9F337C1A12241D47008B0C1E /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 9FA2EF5312241B6B001CD8C6 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 9FA2EF5412241B6B001CD8C6 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 9FA2EF5512241B6B001CD8C6 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 9FA2EF5612241B6B001CD8C6 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 9FC6A568126D0BED008D73BA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailView.xib; sourceTree = ""; }; + 9FC6A56A126D0BED008D73BA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + F4B52CE611991C3100C6ED09 /* PopoverContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoverContentViewController.h; sourceTree = ""; }; + F4B52CE711991C3100C6ED09 /* PopoverContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PopoverContentViewController.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* PopoversAppDelegate.h */, + 1D3623250D0F684500981E51 /* PopoversAppDelegate.m */, + 28042007108E984D000629CD /* RootViewController.h */, + 28042008108E984D000629CD /* RootViewController.m */, + 28042009108E984D000629CD /* DetailViewController.h */, + 2804200A108E984D000629CD /* DetailViewController.m */, + F4B52CE611991C3100C6ED09 /* PopoverContentViewController.h */, + F4B52CE711991C3100C6ED09 /* PopoverContentViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Popovers.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 9F2634091263CAC300DA83F1 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* Popovers_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 9FC6A569126D0BED008D73BA /* MainWindow.xib */, + 9FC6A567126D0BED008D73BA /* DetailView.xib */, + 9FA2EF5212241B6B001CD8C6 /* Images */, + 8D1107310486CEB800E47090 /* Popovers-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9FA2EF5212241B6B001CD8C6 /* Images */ = { + isa = PBXGroup; + children = ( + 9FA2EF5312241B6B001CD8C6 /* Icon-72.png */, + 9FA2EF5412241B6B001CD8C6 /* Icon-Small-50.png */, + 9FA2EF5512241B6B001CD8C6 /* Icon-Small.png */, + 9FA2EF5612241B6B001CD8C6 /* iTunesArtwork */, + 9F337C1912241D47008B0C1E /* Default-Landscape.png */, + 9F337C1A12241D47008B0C1E /* Default.png */, + ); + path = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Popovers */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Popovers" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Popovers; + productName = Popovers; + productReference = 1D6058910D05DD3D006BFB54 /* Popovers.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Popovers" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Popovers */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9FA2EF5712241B6B001CD8C6 /* Icon-72.png in Resources */, + 9FA2EF5812241B6B001CD8C6 /* Icon-Small-50.png in Resources */, + 9FA2EF5912241B6B001CD8C6 /* Icon-Small.png in Resources */, + 9FA2EF5A12241B6B001CD8C6 /* iTunesArtwork in Resources */, + 9F337C1B12241D47008B0C1E /* Default-Landscape.png in Resources */, + 9F337C1C12241D47008B0C1E /* Default.png in Resources */, + 9F26340A1263CAC300DA83F1 /* ReadMe.txt in Resources */, + 9FC6A56B126D0BED008D73BA /* DetailView.xib in Resources */, + 9FC6A56C126D0BED008D73BA /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* PopoversAppDelegate.m in Sources */, + 2804200B108E984D000629CD /* RootViewController.m in Sources */, + 2804200C108E984D000629CD /* DetailViewController.m in Sources */, + F4B52CE811991C3100C6ED09 /* PopoverContentViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 9FC6A567126D0BED008D73BA /* DetailView.xib */ = { + isa = PBXVariantGroup; + children = ( + 9FC6A568126D0BED008D73BA /* en */, + ); + name = DetailView.xib; + sourceTree = ""; + }; + 9FC6A569126D0BED008D73BA /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 9FC6A56A126D0BED008D73BA /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Popovers_Prefix.pch; + INFOPLIST_FILE = "Popovers-Info.plist"; + PRODUCT_NAME = Popovers; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Popovers_Prefix.pch; + INFOPLIST_FILE = "Popovers-Info.plist"; + PRODUCT_NAME = Popovers; + SDKROOT = iphoneos4.1; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos4.1; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Popovers" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Popovers" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Popovers/Popovers_Prefix.pch b/Popovers/Popovers_Prefix.pch new file mode 100644 index 0000000..b1c6cd2 --- /dev/null +++ b/Popovers/Popovers_Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'Popovers' target in the 'Popovers' project +// +#import + +#ifndef __IPHONE_3_2 +#warning "This project uses features only available in iPhone SDK 3.2 and later." +#endif + + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Popovers/ReadMe.txt b/Popovers/ReadMe.txt new file mode 100644 index 0000000..0d275a5 --- /dev/null +++ b/Popovers/ReadMe.txt @@ -0,0 +1,45 @@ +Popovers + +================================================================================ +ABSTRACT: + +This sample demonstrates proper use of UIPopoverController in iOS. +UIPopoverController presentation, dismissing, and rotation handling are covered. +The sample is provided using a UISplitViewController in order to show proper handling of UIPopoverControllers being presented from UIBarButtonItems. +Additional handling ensures that multiple UIPopoverControllers are never presented at the same time. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.1 or later + +================================================================================ +RUNTIME REQUIREMENTS: + +iOS 3.2 or later + +================================================================================ +PACKAGING LIST: + +PopoversAppDelegate +The application delegate sets up the initial view and makes the window visible. + +RootViewController +Acts as the master list view controller for the split view controller and adds rows of placeholder items to the table view. + +DetailViewController +Displays the detail view of the split view controller. This also contains buttons and a bar button item that all present popovers. +The detail view responds to orientation changes when popovers are visible and re-displays them in the new orientation. +The detail view is also responsible for ensuring that there are never multiple popovers visible at the same time. + +PopoverContentViewController +A view controller that is the contents of the popovers in this sample. In this example, the view controller only contains a label with text. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.0 +- First version. + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/Popovers/en.lproj/DetailView.xib b/Popovers/en.lproj/DetailView.xib new file mode 100644 index 0000000..7f4245a --- /dev/null +++ b/Popovers/en.lproj/DetailView.xib @@ -0,0 +1,814 @@ + + + + 800 + 10F569 + 788 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 117 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + + YES + + + 290 + {768, 44} + + NO + NO + IBIPadFramework + + YES + + Tap + IBIPadFramework + 1 + + + + + + + 292 + {{588, 64}, {160, 160}} + + NO + IBIPadFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + Tap + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + + + 292 + {{20, 64}, {160, 160}} + + NO + IBIPadFramework + 0 + 0 + + 1 + Tap + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{20, 824}, {160, 160}} + + NO + IBIPadFramework + 0 + 0 + + 1 + Tap + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{588, 824}, {160, 160}} + + NO + IBIPadFramework + 0 + 0 + + 1 + Tap + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{304, 422}, {160, 160}} + + NO + IBIPadFramework + 0 + 0 + + 1 + Tap + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + {768, 1004} + + + NO + + 2 + + IBIPadFramework + + + + + YES + + + toolbar + + + + 65 + + + + showPopover: + + + 7 + + 74 + + + + showPopover: + + + 7 + + 75 + + + + showPopover: + + + 7 + + 76 + + + + showPopover: + + + 7 + + 77 + + + + showPopover: + + + 7 + + 78 + + + + view + + + + 80 + + + + button1 + + + + 82 + + + + button2 + + + + 83 + + + + button3 + + + + 84 + + + + button4 + + + + 85 + + + + button5 + + + + 86 + + + + myBarButtonItem + + + + 90 + + + + showPopoverFromBarButtonItem: + + + + 92 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 8 + + + YES + + + + + + + + + + + 63 + + + YES + + + + + + 69 + + + + + 70 + + + + + 71 + + + + + 72 + + + + + 73 + + + + + 87 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 63.IBPluginDependency + 69.IBPluginDependency + 70.IBPluginDependency + 71.IBPluginDependency + 72.IBPluginDependency + 73.IBPluginDependency + 8.IBEditorWindowLastContentRect + 8.IBPluginDependency + 87.IBPluginDependency + + + YES + DetailViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{458, 91}, {783, 915}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 92 + + + + YES + + DetailViewController + UIViewController + + YES + + YES + showPopover: + showPopoverFromBarButtonItem: + + + YES + id + id + + + + YES + + YES + showPopover: + showPopoverFromBarButtonItem: + + + YES + + showPopover: + id + + + showPopoverFromBarButtonItem: + id + + + + + YES + + YES + button1 + button2 + button3 + button4 + button5 + detailDescriptionLabel + detailItem + lastTappedButton + myBarButtonItem + toolbar + + + YES + UIButton + UIButton + UIButton + UIButton + UIButton + UILabel + id + id + UIBarButtonItem + UIToolbar + + + + YES + + YES + button1 + button2 + button3 + button4 + button5 + detailDescriptionLabel + detailItem + lastTappedButton + myBarButtonItem + toolbar + + + YES + + button1 + UIButton + + + button2 + UIButton + + + button3 + UIButton + + + button4 + UIButton + + + button5 + UIButton + + + detailDescriptionLabel + UILabel + + + detailItem + id + + + lastTappedButton + id + + + myBarButtonItem + UIBarButtonItem + + + toolbar + UIToolbar + + + + + IBProjectSource + Classes/DetailViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Popovers.xcodeproj + 3 + 117 + + diff --git a/Popovers/en.lproj/MainWindow.xib b/Popovers/en.lproj/MainWindow.xib new file mode 100644 index 0000000..689df7c --- /dev/null +++ b/Popovers/en.lproj/MainWindow.xib @@ -0,0 +1,579 @@ + + + + 800 + 10D559 + 761 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 84 + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 292 + {768, 1024} + + 1 + MSAxIDEAA + + NO + NO + + 2 + + IBIPadFramework + YES + + + IBIPadFramework + + + + + 2 + + + 3 + + IBIPadFramework + YES + + + + 2 + + + 1 + + IBIPadFramework + NO + + + 256 + {0, 0} + YES + YES + IBIPadFramework + + + + + Root View Controller + IBIPadFramework + + + + 2 + + + 1 + + IBIPadFramework + NO + + + + + + + DetailView + + 1 + + IBIPadFramework + NO + + + + + + + + window + + + + 4 + + + + delegate + + + + 17 + + + + splitViewController + + + + 43 + + + + rootViewController + + + + 44 + + + + detailViewController + + + + 45 + + + + detailViewController + + + + 46 + + + + delegate + + + + 49 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + 3 + + + + + 37 + + + + + + + + + 38 + + + + + + + + + 39 + + + + + 40 + + + + + + + + 41 + + + + + 42 + + + + + + + UIApplication + UIResponder + {{190, 57}, {783, 799}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + PopoversAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{794, 594}, {1024, 768}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DetailViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 49 + + + + + DetailViewController + UIViewController + + id + UINavigationBar + + + IBProjectSource + Classes/DetailViewController.h + + + + RootViewController + UITableViewController + + detailViewController + DetailViewController + + + IBProjectSource + Classes/RootViewController.h + + + + RootViewController + UITableViewController + + IBUserSource + + + + + PopoversAppDelegate + NSObject + + DetailViewController + RootViewController + UISplitViewController + UIWindow + + + IBProjectSource + Classes/PopoversAppDelegate.h + + + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISplitViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Popovers.xcodeproj + 3 + 84 + + diff --git a/Popovers/main.m b/Popovers/main.m new file mode 100644 index 0000000..75f1e22 --- /dev/null +++ b/Popovers/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file for this sample. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/QuartzDemo.zip b/QuartzDemo.zip new file mode 100644 index 0000000..b22cae5 Binary files /dev/null and b/QuartzDemo.zip differ diff --git a/QuartzDemo/Classes/AppDelegate.h b/QuartzDemo/Classes/AppDelegate.h new file mode 100755 index 0000000..64a796b --- /dev/null +++ b/QuartzDemo/Classes/AppDelegate.h @@ -0,0 +1,56 @@ +/* + File: AppDelegate.h + Abstract: The application delegate. It creates & configures the view and navigation controllers for the application. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface AppDelegate : NSObject +{ + IBOutlet UIWindow *window; + IBOutlet UINavigationController *navigationController; +} + +@end diff --git a/QuartzDemo/Classes/AppDelegate.m b/QuartzDemo/Classes/AppDelegate.m new file mode 100755 index 0000000..07e6eb1 --- /dev/null +++ b/QuartzDemo/Classes/AppDelegate.m @@ -0,0 +1,74 @@ +/* + File: AppDelegate.m + Abstract: The application delegate. It creates & configures the view and navigation controllers for the application. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "MainViewController.h" + +@interface AppDelegate() +@property(nonatomic, readwrite, retain) UIWindow *window; +@property(nonatomic, readwrite, retain) UINavigationController *navigationController; +@end + +@implementation AppDelegate + +@synthesize window, navigationController; + +-(void)applicationDidFinishLaunching:(UIApplication *)application +{ + // add the navigation controller's view to the window + [window addSubview: navigationController.view]; +} + +-(void)dealloc +{ + [navigationController release]; + [window release]; + [super dealloc]; +} + +@end + diff --git a/QuartzDemo/Classes/MainViewController.h b/QuartzDemo/Classes/MainViewController.h new file mode 100644 index 0000000..a8ead29 --- /dev/null +++ b/QuartzDemo/Classes/MainViewController.h @@ -0,0 +1,56 @@ +/* + File: MainViewController.h + Abstract: Implements the main interface to the demo application, allowing the user to display which of Quartz's drawing facilities to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface MainViewController : UITableViewController +{ + NSMutableDictionary *sections; + NSMutableArray *sectionNames; +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Classes/MainViewController.m b/QuartzDemo/Classes/MainViewController.m new file mode 100644 index 0000000..d40c2dc --- /dev/null +++ b/QuartzDemo/Classes/MainViewController.m @@ -0,0 +1,294 @@ +/* + File: MainViewController.m + Abstract: Implements the main interface to the demo application, allowing the user to display which of Quartz's drawing facilities to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MainViewController.h" +#import "QuartzViewController.h" +#import "QuartzLines.h" +#import "QuartzPolygons.h" +#import "QuartzCurves.h" +#import "QuartzImages.h" +#import "QuartzRendering.h" +#import "QuartzBlending.h" +#import "QuartzClipping.h" +#import "QuartzBlendingViewController.h" +#import "QuartzPolyViewController.h" +#import "QuartzGradientViewController.h" +#import "QuartzLineViewController.h" +#import "QuartzDashViewController.h" + +#define kCellIdentifier @"com.apple.samplecode.QuartzDemo.CellIdentifier" + +@interface MainViewController() +-(void)addController:(QuartzViewController*)controller toSection:(NSString*)sectionName; +-(NSInteger)sectionCount; +-(NSInteger)sectionRowCount:(NSInteger)sectionIndex; +-(NSString*)sectionTitle:(NSInteger)sectionIndex; +-(QuartzViewController*)controllerAtIndexPath:(NSIndexPath*)path; +@end + +@implementation MainViewController + +-(void)addController:(QuartzViewController*)controller toSection:(NSString*)sectionName +{ + if(sections == nil) + { + sections = [[NSMutableDictionary alloc] init]; + sectionNames = [[NSMutableArray alloc] init]; + } + NSMutableArray *list = [sections objectForKey:sectionName]; + if(list == nil) + { + list = [NSMutableArray array]; + [sections setValue:list forKey:sectionName]; + [sectionNames addObject:sectionName]; + } + [list addObject:controller]; +} + +-(NSInteger)sectionCount +{ + return sections.count; +} + +-(NSInteger)sectionRowCount:(NSInteger)sectionIndex; +{ + return [[sections objectForKey:[sectionNames objectAtIndex:sectionIndex]] count]; +} + +-(NSString*)sectionTitle:(NSInteger)sectionIndex +{ + return [sectionNames objectAtIndex:sectionIndex]; +} + +-(QuartzViewController*)controllerAtIndexPath:(NSIndexPath*)path +{ + return [[sections objectForKey:[sectionNames objectAtIndex:path.section]] objectAtIndex:path.row]; +} + +-(void)viewDidLoad +{ + [super viewDidLoad]; + + // create our view controllers + QuartzViewController *controller; + + // Line drawing demo + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzLineView class]]; + controller.title = @"Lines"; + controller.demoInfo = @"QuartzLineView"; + [self addController:controller toSection:@"QuartzLines.m"]; + [controller release]; + + // Showing the effects of line caps, joins & width + controller = [[QuartzLineViewController alloc] init]; + controller.title = @"Caps, Joins & Width"; + controller.demoInfo = @"QuartzCapJoinWidthView"; + [self addController:controller toSection:@"QuartzLines.m"]; + [controller release]; + + // Showing the effects of line dash patterns + controller = [[QuartzDashViewController alloc] init]; + controller.title = @"Dash Patterns"; + controller.demoInfo = @"QuartzDashView"; + [self addController:controller toSection:@"QuartzLines.m"]; + [controller release]; + + // Rectangle drawing demo + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzRectView class]]; + controller.title = @"Rectangles"; + controller.demoInfo = @"QuartzRectView"; + [self addController:controller toSection:@"QuartzPolygons.m"]; + [controller release]; + + // Polygon drawing demo + controller = [[QuartzPolyViewController alloc] init]; + controller.title = @"Polygons"; + controller.demoInfo = @"QuartzPolygonView"; + [self addController:controller toSection:@"QuartzPolygons.m"]; + [controller release]; + + // Ellipses, arcs, and as a bonus round-rects! + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzEllipseArcView class]]; + controller.title = @"Ellipses & Arcs"; + controller.demoInfo = @"QuartzEllipseArcView"; + [self addController:controller toSection:@"QuartzCurves.m"]; + [controller release]; + + // Bezier and Quadratic curves + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzBezierView class]]; + controller.title = @"Beziers & Quadratics"; + controller.demoInfo = @"QuartzBezierView"; + [self addController:controller toSection:@"QuartzCurves.m"]; + [controller release]; + + // Images (drawing once and tiling an image) + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzImageView class]]; + controller.title = @"Images & Tiling"; + controller.demoInfo = @"QuartzImageView"; + [self addController:controller toSection:@"QuartzImages.m"]; + [controller release]; + + // Drawing a PDF page + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzPDFView class]]; + controller.title = @"PDF"; + controller.demoInfo = @"QuartzPDFView"; + // Since the PDF page is primarily white, we'll use the default status bar style rather than the black status bar style. + controller.statusStyle = UIStatusBarStyleDefault; + [self addController:controller toSection:@"QuartzImages.m"]; + [controller release]; + + // Text + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzTextView class]]; + controller.title = @"Text"; + controller.demoInfo = @"QuartzTextView"; + [self addController:controller toSection:@"QuartzImages.m"]; + [controller release]; + + // Drawing Patterns + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzPatternView class]]; + controller.title = @"Patterns"; + controller.demoInfo = @"QuartzPatternView"; + [self addController:controller toSection:@"QuartzRendering.m"]; + [controller release]; + + // Drawing Linear and Radial Gradients + controller = [[QuartzGradientViewController alloc] init]; + controller.title = @"Gradients"; + controller.demoInfo = @"QuartzGradientView"; + [self addController:controller toSection:@"QuartzRendering.m"]; + [controller release]; + + // Blending Demo + controller = [[QuartzBlendingViewController alloc] init]; + controller.title = @"Blending Modes"; + controller.demoInfo = @"QuartzBlendingView"; + [self addController:controller toSection:@"QuartzBlending.m"]; + [controller release]; + + // Clipping Demo + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzClippingView class]]; + controller.title = @"Clipping"; + controller.demoInfo = @"QuartzClippingView"; + [self addController:controller toSection:@"QuartzClipping.m"]; + [controller release]; + + // Masking Demo + controller = [[QuartzViewController alloc] initWithNibName:@"DemoView" viewClass:[QuartzMaskingView class]]; + controller.title = @"Masking"; + controller.demoInfo = @"QuartzMaskingView"; + [self addController:controller toSection:@"QuartzClipping.m"]; + [controller release]; +} + +- (void)dealloc +{ + [sections release]; + [sectionNames release]; + [super dealloc]; +} + +#pragma mark UIViewController delegate + +- (void)viewWillAppear:(BOOL)animated +{ + // this UIViewController is about to appear + // make sure we remove the current selection from our table view + NSIndexPath *tableSelection = [self.tableView indexPathForSelectedRow]; + [self.tableView deselectRowAtIndexPath:tableSelection animated:NO]; + // Set the navbar style to its default color for the list view. + self.navigationController.navigationBar.barStyle = UIBarStyleDefault; + // Set the status bar to its default color for the list view. + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; +} + +#pragma mark UITableView delegate methods + +// the table's selection has changed, switch to that item's UIViewController +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + QuartzViewController *targetViewController = [self controllerAtIndexPath:indexPath]; + [[self navigationController] pushViewController:targetViewController animated:YES]; +} + +#pragma mark UITableView data source methods + +// tell our table how many sections or groups it will have (always 1(our case) +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return [self sectionCount]; +} + +// tell our table how many rows it will have,(our case the size of our menuList +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self sectionRowCount:section]; +} + +-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [self sectionTitle:section]; +} + +// tell our table what kind of cell to use and its title for the given row +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellIdentifier] autorelease]; + } + QuartzViewController *vc = [self controllerAtIndexPath:indexPath]; + cell.textLabel.text = vc.title; + cell.detailTextLabel.text = vc.demoInfo; + cell.detailTextLabel.adjustsFontSizeToFitWidth = YES; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + return cell; +} + +@end + diff --git a/QuartzDemo/Classes/QuartzBlendingViewController.h b/QuartzDemo/Classes/QuartzBlendingViewController.h new file mode 100644 index 0000000..5d92966 --- /dev/null +++ b/QuartzDemo/Classes/QuartzBlendingViewController.h @@ -0,0 +1,58 @@ +/* + File: QuartzBlendingViewController.h + Abstract: A QuartzViewController subclass that manages a QuartzBlendingView and a UI to allow for the selection of foreground color, background color and blending mode to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzViewController.h" + +@interface QuartzBlendingViewController : QuartzViewController +{ + IBOutlet UIPickerView *picker; +} + +-(id)init; + +@end diff --git a/QuartzDemo/Classes/QuartzBlendingViewController.m b/QuartzDemo/Classes/QuartzBlendingViewController.m new file mode 100644 index 0000000..9b6cbef --- /dev/null +++ b/QuartzDemo/Classes/QuartzBlendingViewController.m @@ -0,0 +1,284 @@ +/* + File: QuartzBlendingViewController.m + Abstract: A QuartzViewController subclass that manages a QuartzBlendingView and a UI to allow for the selection of foreground color, background color and blending mode to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzBlendingViewController.h" +#import "QuartzBlending.h" + +// Private required methods. +@interface QuartzBlendingViewController() +@property(nonatomic, readwrite, retain) UIPickerView *picker; +@property(nonatomic, readonly) NSArray *colors; +@end + +@implementation QuartzBlendingViewController + +@synthesize picker; + +// These strings represent the actual blend mode constants +// that are passed to CGContextSetBlendMode and as such +// should not be localized in the context of this sample. +static NSString *blendModes[] = { + // PDF Blend Modes + @"Normal", + @"Multiply", + @"Screen", + @"Overlay", + @"Darken", + @"Lighten", + @"ColorDodge", + @"ColorBurn", + @"SoftLight", + @"HardLight", + @"Difference", + @"Exclusion", + @"Hue", + @"Saturation", + @"Color", + @"Luminosity", + // Porter-Duff Blend Modes + @"Clear", + @"Copy", + @"SourceIn", + @"SourceOut", + @"SourceAtop", + @"DestinationOver", + @"DestinationIn", + @"DestinationOut", + @"DestinationAtop", + @"XOR", + @"PlusDarker", + @"PlusLighter", + // Should Quartz provide more blend modes in the future, here would be the place to add them! +}; +static NSInteger blendModeCount = sizeof(blendModes) / sizeof(blendModes[0]); + +-(id)init +{ + return [super initWithNibName:@"BlendView" viewClass:[QuartzBlendingView class]]; +} + +// Setup the picker's default components. +-(void)viewDidLoad +{ + [super viewDidLoad]; + QuartzBlendingView *qbv = (QuartzBlendingView*)self.quartzView; + [picker selectRow:[self.colors indexOfObject:qbv.destinationColor] inComponent:0 animated:NO]; + [picker selectRow:[self.colors indexOfObject:qbv.sourceColor] inComponent:1 animated:NO]; + [picker selectRow:qbv.blendMode inComponent:2 animated:NO]; +} + +-(void)dealloc +{ + [picker release]; picker = nil; + [super dealloc]; +} + +// Calculate the luminance for an arbitrary UIColor instance +CGFloat luminanceForColor(UIColor *color) +{ + CGColorRef cgColor = color.CGColor; + const CGFloat *components = CGColorGetComponents(cgColor); + CGFloat luminance = 0.0; + switch(CGColorSpaceGetModel(CGColorGetColorSpace(cgColor))) + { + case kCGColorSpaceModelMonochrome: + // For grayscale colors, the luminance is the color value + luminance = components[0]; + break; + + case kCGColorSpaceModelRGB: + // For RGB colors, we calculate luminance assuming sRGB Primaries as per + // http://en.wikipedia.org/wiki/Luminance_(relative) + luminance = 0.2126 * components[0] + 0.7152 * components[1] + 0.0722 * components[2]; + break; + + default: + // We don't implement support for non-gray, non-rgb colors at this time. + // Since our only consumer is colorSortByLuminance, we return a larger than normal + // value to ensure that these types of colors are sorted to the end of the list. + luminance = 2.0; + } + return luminance; +} + +// Simple comparison function that sorts the two (presumed) UIColors according to their luminance value. +NSInteger colorSortByLuminance(id color1, id color2, void *context) +{ + CGFloat luminance1 = luminanceForColor(color1); + CGFloat luminance2 = luminanceForColor(color2); + if(luminance1 == luminance2) + { + return NSOrderedSame; + } + else if(luminance1 < luminance2) + { + return NSOrderedAscending; + } + else + { + return NSOrderedDescending; + } +} + +-(NSArray*)colors +{ + static NSArray *colorArray = nil; + if(colorArray == nil) + { + // If you want to add more colors to the demo, here would be the place + // You can also add patterns if you like, they will simply be sorted + // to the end of the list. + NSArray *unsortedArray = [NSArray arrayWithObjects: + [UIColor redColor], + [UIColor greenColor], + [UIColor blueColor], + [UIColor yellowColor], + [UIColor magentaColor], + [UIColor cyanColor], + [UIColor orangeColor], + [UIColor purpleColor], + [UIColor brownColor], + [UIColor whiteColor], + [UIColor lightGrayColor], + [UIColor darkGrayColor], + [UIColor blackColor], + nil]; + colorArray = [[unsortedArray sortedArrayUsingFunction:colorSortByLuminance context:nil] retain]; + } + return colorArray; +} + +#pragma mark UIPickerViewDelegate & UIPickerViewDataSource methods + +-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 3; +} + +-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + NSInteger numComps = 0; + switch(component) + { + case 0: + case 1: + numComps = [self.colors count]; + break; + + case 2: + numComps = blendModeCount; + break; + } + return numComps; +} + +-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component +{ + CGFloat width = 0.0; + switch (component) + { + case 0: + case 1: + width = 48.0; + break; + case 2: + width = 192.0; + break; + } + return width; +} + +#define kColorTag 1 +#define kLabelTag 2 +-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view +{ + switch (component) + { + case 0: + case 1: + if(view.tag != kColorTag) + { + CGRect frame = CGRectZero; + frame.size = [pickerView rowSizeForComponent:component]; + frame = CGRectInset(frame, 4.0, 4.0); + view = [[[UIView alloc] initWithFrame:frame] autorelease]; + view.tag = kColorTag; + view.userInteractionEnabled = NO; + } + view.backgroundColor = [self.colors objectAtIndex:row]; + break; + + case 2: + if(view.tag != kLabelTag) + { + CGRect frame = CGRectZero; + frame.size = [pickerView rowSizeForComponent:component]; + frame = CGRectInset(frame, 4.0, 4.0); + view = [[[UILabel alloc] initWithFrame:frame] autorelease]; + view.tag = kLabelTag; + view.opaque = NO; + view.backgroundColor = [UIColor clearColor]; + view.userInteractionEnabled = NO; + } + UILabel *label = (UILabel*)view; + label.textColor = [UIColor blackColor]; + label.text = blendModes[row]; + label.font = [UIFont boldSystemFontOfSize:18.0]; + break; + } + return view; +} + +-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + QuartzBlendingView *qbv = (QuartzBlendingView*)self.quartzView; + qbv.destinationColor = [self.colors objectAtIndex:[picker selectedRowInComponent:0]]; + qbv.sourceColor = [self.colors objectAtIndex:[picker selectedRowInComponent:1]]; + qbv.blendMode = [picker selectedRowInComponent:2]; +} + +@end diff --git a/QuartzDemo/Classes/QuartzDashViewController.h b/QuartzDemo/Classes/QuartzDashViewController.h new file mode 100644 index 0000000..5c14242 --- /dev/null +++ b/QuartzDemo/Classes/QuartzDashViewController.h @@ -0,0 +1,61 @@ +/* + File: QuartzDashViewController.h + Abstract: A QuartzViewController subclass that manages a QuartzDashView and a UI to allow for the selection of the line dash pattern and phase. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzViewController.h" + +@interface QuartzDashViewController : QuartzViewController +{ + IBOutlet UIPickerView *picker; + IBOutlet UISlider *phase; +} + +-(id)init; +-(IBAction)dashPhase; +-(IBAction)reset; + +@end diff --git a/QuartzDemo/Classes/QuartzDashViewController.m b/QuartzDemo/Classes/QuartzDashViewController.m new file mode 100644 index 0000000..0bbffe2 --- /dev/null +++ b/QuartzDemo/Classes/QuartzDashViewController.m @@ -0,0 +1,138 @@ +/* + File: QuartzDashViewController.m + Abstract: A QuartzViewController subclass that manages a QuartzDashView and a UI to allow for the selection of the line dash pattern and phase. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzDashViewController.h" +#import "QuartzLines.h" + +@interface QuartzDashViewController() +@property(nonatomic, readwrite, retain) UIPickerView *picker; +@end + +@implementation QuartzDashViewController + +@synthesize picker; + +// These strings represent the actual drawing mode constants +// that are passed to CGContextDrawpath and as such +// should not be localized in the context of this sample +typedef struct { + CGFloat pattern[5]; + size_t count; +} Pattern; +static Pattern patterns[] = { + {{10.0, 10.0}, 2}, + {{10.0, 20.0, 10.0}, 3}, + {{10.0, 20.0, 30.0}, 3}, + {{10.0, 20.0, 10.0, 30.0}, 4}, + {{10.0, 10.0, 20.0, 20.0}, 4}, + {{10.0, 10.0, 20.0, 30.0, 50.0}, 5}, +}; +static NSInteger patternCount = sizeof(patterns) / sizeof(patterns[0]); + +-(id)init +{ + return [super initWithNibName:@"DashView" viewClass:[QuartzDashView class]]; +} + +// Setup the picker's default components. +-(void)viewDidLoad +{ + [super viewDidLoad]; + QuartzDashView *ldv = (QuartzDashView*)self.quartzView; + [ldv setDashPattern:patterns[0].pattern count:patterns[0].count]; + [picker selectRow:0 inComponent:0 animated:NO]; +} + +-(void)dealloc +{ + [picker release]; picker = nil; + [super dealloc]; +} + +-(IBAction)dashPhase +{ + QuartzDashView *ldv = (QuartzDashView*)self.quartzView; + ldv.dashPhase = phase.value; +} + +-(IBAction)reset +{ + QuartzDashView *ldv = (QuartzDashView*)self.quartzView; + ldv.dashPhase = 0.0; + phase.value = 0.0; +} + +#pragma mark UIPickerViewDelegate & UIPickerViewDataSource methods + +-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return patternCount; +} + +-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; +{ + Pattern p = patterns[row]; + NSMutableString *title = [NSMutableString stringWithFormat:@"%.0f", p.pattern[0]]; + for(size_t i = 1; i < p.count; ++i) + { + [title appendFormat:@"-%.0f", p.pattern[i]]; + } + return title; +} + +-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + QuartzDashView *ldv = (QuartzDashView*)self.quartzView; + [ldv setDashPattern:patterns[row].pattern count:patterns[row].count]; +} + +@end diff --git a/QuartzDemo/Classes/QuartzGradientViewController.h b/QuartzDemo/Classes/QuartzGradientViewController.h new file mode 100644 index 0000000..0097b44 --- /dev/null +++ b/QuartzDemo/Classes/QuartzGradientViewController.h @@ -0,0 +1,60 @@ +/* + File: QuartzGradientViewController.h + Abstract: A QuartzViewController subclass that manages a QuartzGradientView and a UI to allow for the selection of gradient type and if the gradient extends past its start or end point. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzViewController.h" + +@interface QuartzGradientViewController : QuartzViewController +{ +} + +-(id)init; +-(IBAction)gradientType:(id)sender; +-(IBAction)extendsPastStart:(id)sender; +-(IBAction)extendsPastEnd:(id)sender; + +@end \ No newline at end of file diff --git a/QuartzDemo/Classes/QuartzGradientViewController.m b/QuartzDemo/Classes/QuartzGradientViewController.m new file mode 100644 index 0000000..0a61b2a --- /dev/null +++ b/QuartzDemo/Classes/QuartzGradientViewController.m @@ -0,0 +1,79 @@ +/* + File: QuartzGradientViewController.m + Abstract: A QuartzViewController subclass that manages a QuartzGradientView and a UI to allow for the selection of gradient type and if the gradient extends past its start or end point. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzGradientViewController.h" +#import "QuartzRendering.h" + +@interface QuartzGradientViewController() +@end + +@implementation QuartzGradientViewController + +-(id)init +{ + return [super initWithNibName:@"GradientView" viewClass:[QuartzGradientView class]]; +} + +-(IBAction)gradientType:(id)sender +{ + QuartzGradientView *gdv = (QuartzGradientView*)self.quartzView; + gdv.type = [sender selectedSegmentIndex]; +} + +-(IBAction)extendsPastStart:(id)sender +{ + QuartzGradientView *gdv = (QuartzGradientView*)self.quartzView; + gdv.extendsPastStart = [sender isOn]; +} + +-(IBAction)extendsPastEnd:(id)sender +{ + QuartzGradientView *gdv = (QuartzGradientView*)self.quartzView; + gdv.extendsPastEnd = [sender isOn]; +} + +@end diff --git a/QuartzDemo/Classes/QuartzLineViewController.h b/QuartzDemo/Classes/QuartzLineViewController.h new file mode 100644 index 0000000..ca7178d --- /dev/null +++ b/QuartzDemo/Classes/QuartzLineViewController.h @@ -0,0 +1,60 @@ +/* + File: QuartzLineViewController.h + Abstract: A QuartzViewController subclass that manages a QuartzCapJoinWidthView and a UI to allow for the selection of the line cap, line join and line width to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzViewController.h" + +@interface QuartzLineViewController : QuartzViewController +{ +} + +-(id)init; +-(IBAction)lineCap:(id)sender; +-(IBAction)lineJoin:(id)sender; +-(IBAction)lineWidth:(id)sender; + +@end diff --git a/QuartzDemo/Classes/QuartzLineViewController.m b/QuartzDemo/Classes/QuartzLineViewController.m new file mode 100644 index 0000000..4871efe --- /dev/null +++ b/QuartzDemo/Classes/QuartzLineViewController.m @@ -0,0 +1,79 @@ +/* + File: QuartzLineViewController.m + Abstract: A QuartzViewController subclass that manages a QuartzCapJoinWidthView and a UI to allow for the selection of the line cap, line join and line width to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzLineViewController.h" +#import "QuartzLines.h" + +@interface QuartzLineViewController() +@end + +@implementation QuartzLineViewController + +-(id)init +{ + return [super initWithNibName:@"LineView" viewClass:[QuartzCapJoinWidthView class]]; +} + +-(IBAction)lineCap:(id)sender +{ + QuartzCapJoinWidthView *qld = (QuartzCapJoinWidthView*)self.quartzView; + qld.cap = [sender selectedSegmentIndex]; +} + +-(IBAction)lineJoin:(id)sender +{ + QuartzCapJoinWidthView *qld = (QuartzCapJoinWidthView*)self.quartzView; + qld.join = [sender selectedSegmentIndex]; +} + +-(IBAction)lineWidth:(id)sender +{ + QuartzCapJoinWidthView *qld = (QuartzCapJoinWidthView*)self.quartzView; + qld.width = ((UISlider*)sender).value; +} + +@end diff --git a/QuartzDemo/Classes/QuartzPolyViewController.h b/QuartzDemo/Classes/QuartzPolyViewController.h new file mode 100644 index 0000000..70abd5c --- /dev/null +++ b/QuartzDemo/Classes/QuartzPolyViewController.h @@ -0,0 +1,58 @@ +/* + File: QuartzPolyViewController.h + Abstract: A QuartzViewController subclass that manages a QuartzPolygonView and a UI to allow for the selection of the stroke and fill mode to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzViewController.h" + +@interface QuartzPolyViewController : QuartzViewController +{ + IBOutlet UIPickerView *picker; +} + +-(id)init; + +@end diff --git a/QuartzDemo/Classes/QuartzPolyViewController.m b/QuartzDemo/Classes/QuartzPolyViewController.m new file mode 100644 index 0000000..dc0e188 --- /dev/null +++ b/QuartzDemo/Classes/QuartzPolyViewController.m @@ -0,0 +1,113 @@ +/* + File: QuartzPolyViewController.m + Abstract: A QuartzViewController subclass that manages a QuartzPolygonView and a UI to allow for the selection of the stroke and fill mode to demonstrate. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzPolyViewController.h" +#import "QuartzPolygons.h" + +@interface QuartzPolyViewController() +@property(nonatomic, readwrite, retain) UIPickerView *picker; +@end + +@implementation QuartzPolyViewController + +@synthesize picker; + +// These strings represent the actual drawing mode constants +// that are passed to CGContextDrawpath and as such +// should not be localized in the context of this sample +static NSString *drawModes[] = { + @"Fill",//0 + @"EOFill",//1 + @"Stroke",//2 + @"FillStroke",//3 + @"EOFillStroke"//4 +}; +static NSInteger drawModeCount = sizeof(drawModes) / sizeof(drawModes[0]); + +-(id)init +{ + return [super initWithNibName:@"PolyView" viewClass:[QuartzPolygonView class]]; +} + +// Setup the picker's default components. +-(void)viewDidLoad +{ + [super viewDidLoad]; + QuartzPolygonView *pdv = (QuartzPolygonView*)self.quartzView; + [picker selectRow:pdv.drawingMode inComponent:0 animated:NO]; +} + +-(void)dealloc +{ + [picker release]; picker = nil; + [super dealloc]; +} + +#pragma mark UIPickerViewDelegate & UIPickerViewDataSource methods + +-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return drawModeCount; +} + +-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; +{ + return drawModes[row]; +} + +-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + QuartzPolygonView *pdv = (QuartzPolygonView*)self.quartzView; + pdv.drawingMode = [picker selectedRowInComponent:0]; +} + +@end diff --git a/QuartzDemo/Classes/QuartzView.h b/QuartzDemo/Classes/QuartzView.h new file mode 100644 index 0000000..f41b43d --- /dev/null +++ b/QuartzDemo/Classes/QuartzView.h @@ -0,0 +1,57 @@ +/* + File: QuartzView.h + Abstract: A UIView subclass that is the super class of the other demonstration views in this sample. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface QuartzView : UIView +{ +} + +// As a matter of convinience we'll do all of our drawing here in subclasses of QuartzView. +-(void)drawInContext:(CGContextRef)context; + +@end \ No newline at end of file diff --git a/QuartzDemo/Classes/QuartzView.m b/QuartzDemo/Classes/QuartzView.m new file mode 100644 index 0000000..366dd7b --- /dev/null +++ b/QuartzDemo/Classes/QuartzView.m @@ -0,0 +1,77 @@ +/* + File: QuartzView.m + Abstract: A UIView subclass that is the super class of the other demonstration views in this sample. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzView.h" + +@implementation QuartzView + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + self.backgroundColor = [UIColor blackColor]; + self.opaque = YES; + self.clearsContextBeforeDrawing = YES; + } + return self; +} + +-(void)drawInContext:(CGContextRef)context +{ + // Default is to do nothing! +} + +-(void)drawRect:(CGRect)rect +{ + // Since we use the CGContextRef a lot, it is convienient for our demonstration classes to do the real work + // inside of a method that passes the context as a parameter, rather than having to query the context + // continuously, or setup that parameter for every subclass. + [self drawInContext:UIGraphicsGetCurrentContext()]; +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Classes/QuartzViewController.h b/QuartzDemo/Classes/QuartzViewController.h new file mode 100644 index 0000000..4d14136 --- /dev/null +++ b/QuartzDemo/Classes/QuartzViewController.h @@ -0,0 +1,68 @@ +/* + File: QuartzViewController.h + Abstract: A UIViewController subclass that manages a single QuartzView and allows the user to zoom and pan around the hosted QuartzView. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzViewController : UIViewController +{ + IBOutlet UIScrollView *scrollView; + Class viewClass; + UIBarStyle barStyle; + UIStatusBarStyle statusStyle; + QuartzView *quartzView; + NSString *demoInfo; +} + +@property(nonatomic, readwrite) UIBarStyle barStyle; +@property(nonatomic, readwrite) UIStatusBarStyle statusStyle; +@property(nonatomic, readwrite, copy) NSString *demoInfo; +@property(nonatomic, readonly) QuartzView *quartzView; + +-(id)initWithNibName:(NSString*)nib viewClass:(Class)vc; + +@end \ No newline at end of file diff --git a/QuartzDemo/Classes/QuartzViewController.m b/QuartzDemo/Classes/QuartzViewController.m new file mode 100644 index 0000000..35ab825 --- /dev/null +++ b/QuartzDemo/Classes/QuartzViewController.m @@ -0,0 +1,124 @@ +/* + File: QuartzViewController.m + Abstract: A UIViewController subclass that manages a single QuartzView and allows the user to zoom and pan around the hosted QuartzView. + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzViewController.h" + +@interface QuartzViewController() +@property(nonatomic, retain) UIScrollView *scrollView; +@end + +@implementation QuartzViewController + +@synthesize barStyle, statusStyle, scrollView, demoInfo; + +-(id)initWithNibName:(NSString*)nib viewClass:(Class)vc; +{ + self = [super initWithNibName:nib bundle:nil]; + if (self != nil) + { + // Stash the class to use for drawing for later when the view hierarchy is created + viewClass = vc; + + // Default bar style is black opaque for QuartzViewControllers. + barStyle = UIBarStyleBlackOpaque; + + // Default status bar style is black opaque for QuartzViewControllers. + statusStyle = UIStatusBarStyleBlackOpaque; + } + return self; +} + +-(QuartzView*)quartzView +{ + if(quartzView == nil) + { + quartzView = [[viewClass alloc] initWithFrame:CGRectZero]; + } + return quartzView; +} + +-(void)viewDidLoad +{ + // Add the QuartzView + [scrollView addSubview:self.quartzView]; +} + +-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + // Return YES for supported orientations. + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + +-(void)viewDidUnload +{ + [quartzView release]; quartzView = nil; + [scrollView release]; scrollView = nil; +} + +#pragma mark UIViewController delegate methods + +// called before this controller's view has appeared +-(void)viewWillAppear:(BOOL)animated +{ + // for aesthetic reasons make the nav bar an appropriate color (defaulting to black) for this page + self.navigationController.navigationBar.barStyle = barStyle; + // ditto for the status bar. + [[UIApplication sharedApplication] setStatusBarStyle:statusStyle animated:animated]; + // Reset the scroll view to 1.0 zoom + [scrollView setZoomScale:1.0 animated:NO]; + self.quartzView.frame = scrollView.bounds; + scrollView.contentSize = scrollView.bounds.size; +} + +#pragma mark UIScrollView delegate methods + +-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView +{ + return self.quartzView; +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Info.plist b/QuartzDemo/Info.plist new file mode 100755 index 0000000..47d0749 --- /dev/null +++ b/QuartzDemo/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.5 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/QuartzDemo/Prefix.pch b/QuartzDemo/Prefix.pch new file mode 100755 index 0000000..23a7b9d --- /dev/null +++ b/QuartzDemo/Prefix.pch @@ -0,0 +1,50 @@ +/* + File: Prefix.pch + Abstract: + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifdef __OBJC__ + #import +#endif diff --git a/QuartzDemo/Quartz/QuartzBlending.h b/QuartzDemo/Quartz/QuartzBlending.h new file mode 100644 index 0000000..4c75bf6 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzBlending.h @@ -0,0 +1,63 @@ +/* + File: QuartzBlending.h + Abstract: Demonstrates Quartz Blend modes (QuartzBlendingView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzBlendingView : QuartzView +{ + UIColor *sourceColor; + UIColor *destinationColor; + CGBlendMode blendMode; +} + +-(void)drawInContext:(CGContextRef)context; +@property(nonatomic, readwrite, retain) UIColor *sourceColor; +@property(nonatomic, readwrite, retain) UIColor *destinationColor; +@property(nonatomic, readwrite) CGBlendMode blendMode; + +@end diff --git a/QuartzDemo/Quartz/QuartzBlending.m b/QuartzDemo/Quartz/QuartzBlending.m new file mode 100644 index 0000000..ee432e9 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzBlending.m @@ -0,0 +1,123 @@ +/* + File: QuartzBlending.m + Abstract: Demonstrates Quartz Blend modes (QuartzBlendingView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzBlending.h" + + +@interface QuartzBlendingView() +@end + +@implementation QuartzBlendingView + +@synthesize sourceColor, destinationColor, blendMode; + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + sourceColor = [UIColor whiteColor]; + destinationColor = [UIColor blackColor]; + blendMode = kCGBlendModeNormal; + } + return self; +} + +-(void)dealloc +{ + [sourceColor release]; + [destinationColor release]; + [super dealloc]; +} + +-(void)setSourceColor:(UIColor*)src +{ + if(src != sourceColor) + { + [sourceColor release]; + sourceColor = [src retain]; + [self setNeedsDisplay]; + } +} + +-(void)setDestinationColor:(UIColor*)dest +{ + if(dest != destinationColor) + { + [destinationColor release]; + destinationColor = [dest retain]; + [self setNeedsDisplay]; + } +} + +-(void)setBlendMode:(CGBlendMode)mode +{ + if(mode != blendMode) + { + blendMode = mode; + [self setNeedsDisplay]; + } +} + +-(void)drawInContext:(CGContextRef)context +{ + // Start with a background whose color we don't use in the demo + CGContextSetGrayFillColor(context, 0.2, 1.0); + CGContextFillRect(context, self.bounds); + // We want to just lay down the background without any blending so we use the Copy mode rather than Normal + CGContextSetBlendMode(context, kCGBlendModeCopy); + // Draw a rect with the "background" color - this is the "Destination" for the blending formulas + CGContextSetFillColorWithColor(context, destinationColor.CGColor); + CGContextFillRect(context, CGRectMake(110.0, 20.0, 100.0, 100.0)); + // Set up our blend mode + CGContextSetBlendMode(context, blendMode); + // And draw a rect with the "foreground" color - this is the "Source" for the blending formulas + CGContextSetFillColorWithColor(context, sourceColor.CGColor); + CGContextFillRect(context, CGRectMake(60.0, 45.0, 200.0, 50.0)); +} + +@end diff --git a/QuartzDemo/Quartz/QuartzClipping.h b/QuartzDemo/Quartz/QuartzClipping.h new file mode 100644 index 0000000..da54e6c --- /dev/null +++ b/QuartzDemo/Quartz/QuartzClipping.h @@ -0,0 +1,66 @@ +/* + File: QuartzClipping.h + Abstract: Demonstrates using Quartz for clipping (QuartzClippingView) and masking (QuartzMaskingView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzClippingView : QuartzView +{ + CGImageRef image; +} + +@end + +#pragma mark - + +@interface QuartzMaskingView : QuartzView +{ + CGImageRef maskingImage; + CGImageRef alphaImage; +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzClipping.m b/QuartzDemo/Quartz/QuartzClipping.m new file mode 100644 index 0000000..e9301ca --- /dev/null +++ b/QuartzDemo/Quartz/QuartzClipping.m @@ -0,0 +1,250 @@ +/* + File: QuartzClipping.m + Abstract: Demonstrates using Quartz for clipping (QuartzClippingView) and masking (QuartzMaskingView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzClipping.h" + +@implementation QuartzClippingView + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"Ship.png" ofType:nil]; + UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; + image = CGImageRetain(img.CGImage); + } + return self; +} + +-(void)dealloc +{ + CGImageRelease(image); + [super dealloc]; +} + +-(void)addStarToContext:(CGContextRef)context at:(CGPoint)center radius:(CGFloat)radius angle:(CGFloat)angle +{ + CGFloat x = radius * sinf(angle * M_PI / 5.0) + center.x; + CGFloat y = radius * cosf(angle * M_PI / 5.0) + center.y; + CGContextMoveToPoint(context, x, y); + for(int i = 1; i < 5; ++i) + { + CGFloat x = radius * sinf((i * 4.0 * M_PI + angle) / 5.0) + center.x; + CGFloat y = radius * cosf((i * 4.0 * M_PI + angle) / 5.0) + center.y; + CGContextAddLineToPoint(context, x, y); + } + // And close the subpath. + CGContextClosePath(context); +} + +-(void)drawInContext:(CGContextRef)context +{ + // NOTE + // So that the images in this demo appear right-side-up, we flip the context + // In doing so we need to specify all of our Y positions relative to the height of the view. + // The value we subtract from the height is the Y coordinate for the *bottom* of the image. + CGFloat height = self.bounds.size.height; + CGContextTranslateCTM(context, 0.0, height); + CGContextScaleCTM(context, 1.0, -1.0); + + CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0); + + // We'll draw the original image for comparision + CGContextDrawImage(context, CGRectMake(10.0, height - 100.0, 90.0, 90.0), image); + + // First we'll use clipping rectangles to remove the body of the ship. + // We use CGContextClipToRects() to clip to a set of rectangles. + + CGContextSaveGState(context); + // For this operation we extract the 35 pixel strip on each side of the source image. + CGRect clips[] = + { + CGRectMake(110.0, height - 100.0, 35.0, 90.0), + CGRectMake(165.0, height - 100.0, 35.0, 90.0), + }; + // While convinient, this is just the equivalent of adding each rectangle to the current path, + // then calling CGContextClip(). + CGContextClipToRects(context, clips, sizeof(clips) / sizeof(clips[0])); + CGContextDrawImage(context, CGRectMake(110.0, height - 100.0, 90.0, 90.0), image); + CGContextRestoreGState(context); + + // You can also clip to aribitrary shapes, which can be useful for special effects. + // In this case we are going to clip to a star. + // We will actually clip the image twice, using the different clipping modes. + [self addStarToContext:context at:CGPointMake(55.0, height - 150.0) radius:45.0 angle:0.0]; + CGContextSaveGState(context); + + // Clip to the current path using the non-zero winding number rule. + CGContextClip(context); + + // To make the area we draw to a bit more obvious, we'll the image over a red rectangle. + CGContextFillRect(context, CGRectMake(10.0, height - 190.0, 90.0, 90.0)); + + // And finally draw the image + CGContextDrawImage(context, CGRectMake(10.0, height - 190.0, 90.0, 90.0), image); + CGContextRestoreGState(context); + + [self addStarToContext:context at:CGPointMake(155.0, height - 150.0) radius:45.0 angle:0.0]; + CGContextSaveGState(context); + + // Clip to the current path using the even-odd rule. + CGContextEOClip(context); + + // To make the area we draw to a bit more obvious, we'll the image over a red rectangle. + CGContextFillRect(context, CGRectMake(110.0, height - 190.0, 90.0, 90.0)); + + // And finally draw the image + CGContextDrawImage(context, CGRectMake(110.0, height - 190.0, 90.0, 90.0), image); + CGContextRestoreGState(context); + + // Finally making the path slightly more complex by enscribing it in a rectangle changes what is clipped + // For EO clipping mode this will invert the clip (for non-zero winding this is less predictable). + [self addStarToContext:context at:CGPointMake(255.0, height - 150.0) radius:45.0 angle:0.0]; + CGContextAddRect(context, CGRectMake(210., height - 190., 90., 90.)); + CGContextSaveGState(context); + + // Clip to the current path using the even-odd rule. + CGContextEOClip(context); + + // To make the area we draw to a bit more obvious, we'll the image over a red rectangle. + CGContextFillRect(context, CGRectMake(210.0, height - 190.0, 90.0, 90.0)); + + // And finally draw the image + CGContextDrawImage(context, CGRectMake(210.0, height - 190.0, 90.0, 90.0), image); + CGContextRestoreGState(context); +} + +@end + +@implementation QuartzMaskingView + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + // Load the alpha image, which is just the same Ship.png image used in the clipping demo + NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"Ship.png" ofType:nil]; + UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; + alphaImage = CGImageRetain(img.CGImage); + + // To show the difference with an image mask, we take the above image and process it to extract + // the alpha channel as a mask. + // Allocate data + NSMutableData *data = [NSMutableData dataWithLength:90 * 90 * 1]; + // Create a bitmap context + CGContextRef context = CGBitmapContextCreate([data mutableBytes], 90, 90, 8, 90, NULL, kCGImageAlphaOnly); + // Set the blend mode to copy to avoid any alteration of the source data + CGContextSetBlendMode(context, kCGBlendModeCopy); + // Draw the image to extract the alpha channel + CGContextDrawImage(context, CGRectMake(0.0, 0.0, 90.0, 90.0), alphaImage); + // Now the alpha channel has been copied into our NSData object above, so discard the context and lets make an image mask. + CGContextRelease(context); + // Create a data provider for our data object (NSMutableData is tollfree bridged to CFMutableDataRef, which is compatible with CFDataRef) + CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFMutableDataRef)data); + // Create our new mask image with the same size as the original image + maskingImage = CGImageMaskCreate(90, 90, 8, 8, 90, dataProvider, NULL, YES); + // And release the provider. + CGDataProviderRelease(dataProvider); + } + return self; +} + +-(void)dealloc +{ + CGImageRelease(maskingImage); + CGImageRelease(alphaImage); + [super dealloc]; +} + +-(void)drawInContext:(CGContextRef)context +{ + // NOTE + // So that the images in this demo appear right-side-up, we flip the context + // In doing so we need to specify all of our Y positions relative to the height of the view. + // The value we subtract from the height is the Y coordinate for the *bottom* of the image. + CGFloat height = self.bounds.size.height; + CGContextTranslateCTM(context, 0.0, height); + CGContextScaleCTM(context, 1.0, -1.0); + + CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); + + // Quartz also allows you to mask to an image or image mask, the primary difference being + // how the image data is interpreted. Note that you can use any image + // When you use a regular image, the alpha channel is interpreted as the alpha values to use, + // that is a 0.0 alpha indicates no pass and a 1.0 alpha indicates full pass. + CGContextSaveGState(context); + CGContextClipToMask(context, CGRectMake(10.0, height - 100.0, 90.0, 90.0), alphaImage); + // Because we're clipping, we aren't going to be particularly careful with our rect. + CGContextFillRect(context, self.bounds); + CGContextRestoreGState(context); + + CGContextSaveGState(context); + // You can also use the clip rect given to scale the mask image + CGContextClipToMask(context, CGRectMake(110.0, height - 190.0, 180.0, 180.0), alphaImage); + // As above, not being careful with bounds since we are clipping. + CGContextFillRect(context, self.bounds); + CGContextRestoreGState(context); + + // Alternatively when you use a mask image the mask data is used much like an inverse alpha channel, + // that is 0.0 indicates full pas and 1.0 indicates no pass. + CGContextSaveGState(context); + CGContextClipToMask(context, CGRectMake(10.0, height - 300.0, 90.0, 90.0), maskingImage); + // Because we're clipping, we aren't going to be particularly careful with our rect. + CGContextFillRect(context, self.bounds); + CGContextRestoreGState(context); + + CGContextSaveGState(context); + // You can also use the clip rect given to scale the mask image + CGContextClipToMask(context, CGRectMake(110.0, height - 390.0, 180.0, 180.0), maskingImage); + // As above, not being careful with bounds since we are clipping. + CGContextFillRect(context, self.bounds); + CGContextRestoreGState(context); +} + +@end diff --git a/QuartzDemo/Quartz/QuartzCurves.h b/QuartzDemo/Quartz/QuartzCurves.h new file mode 100644 index 0000000..3a03083 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzCurves.h @@ -0,0 +1,65 @@ +/* + File: QuartzCurves.h + Abstract: Demonstrates using Quartz to draw ellipses & arcs (QuartzEllipseArcView) and bezier & quadratic curves (QuartzBezierView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzEllipseArcView : QuartzView +{ +} + +-(void)drawInContext:(CGContextRef)context; + +@end + +@interface QuartzBezierView : QuartzView +{ +} + +-(void)drawInContext:(CGContextRef)context; + +@end diff --git a/QuartzDemo/Quartz/QuartzCurves.m b/QuartzDemo/Quartz/QuartzCurves.m new file mode 100644 index 0000000..375cf27 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzCurves.m @@ -0,0 +1,193 @@ +/* + File: QuartzCurves.m + Abstract: Demonstrates using Quartz to draw ellipses & arcs (QuartzEllipseArcView) and bezier & quadratic curves (QuartzBezierView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ +#import "QuartzCurves.h" + +@implementation QuartzEllipseArcView + +-(void)drawInContext:(CGContextRef)context +{ + // Drawing with a white stroke color + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + // And draw with a blue fill color + CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0); + // Draw them with a 2.0 stroke width so they are a bit more visible. + CGContextSetLineWidth(context, 2.0); + + // Add an ellipse circumscribed in the given rect to the current path, then stroke it + CGContextAddEllipseInRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0)); + CGContextStrokePath(context); + + // Stroke ellipse convenience that is equivalent to AddEllipseInRect(); StrokePath(); + CGContextStrokeEllipseInRect(context, CGRectMake(30.0, 120.0, 60.0, 60.0)); + + // Fill rect convenience equivalent to AddEllipseInRect(); FillPath(); + CGContextFillEllipseInRect(context, CGRectMake(30.0, 210.0, 60.0, 60.0)); + + // Stroke 2 seperate arcs + CGContextAddArc(context, 150.0, 60.0, 30.0, 0.0, M_PI/2.0, false); + CGContextStrokePath(context); + CGContextAddArc(context, 150.0, 60.0, 30.0, 3.0*M_PI/2.0, M_PI, true); + CGContextStrokePath(context); + + // Stroke 2 arcs together going opposite directions. + CGContextAddArc(context, 150.0, 150.0, 30.0, 0.0, M_PI/2.0, false); + CGContextAddArc(context, 150.0, 150.0, 30.0, 3.0*M_PI/2.0, M_PI, true); + CGContextStrokePath(context); + + // Stroke 2 arcs together going the same direction.. + CGContextAddArc(context, 150.0, 240.0, 30.0, 0.0, M_PI/2.0, false); + CGContextAddArc(context, 150.0, 240.0, 30.0, M_PI, 3.0*M_PI/2.0, false); + CGContextStrokePath(context); + + // Stroke an arc using AddArcToPoint + CGPoint p[3] = + { + CGPointMake(210.0, 30.0), + CGPointMake(210.0, 60.0), + CGPointMake(240.0, 60.0), + }; + CGContextMoveToPoint(context, p[0].x, p[0].y); + CGContextAddArcToPoint(context, p[1].x, p[1].y, p[2].x, p[2].y, 30.0); + CGContextStrokePath(context); + + // Show the two segments that are used to determine the tangent lines to draw the arc. + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextAddLines(context, p, sizeof(p)/sizeof(p[0])); + CGContextStrokePath(context); + + // As a bonus, we'll combine arcs to create a round rectangle! + + // Drawing with a white stroke color + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + + // If you were making this as a routine, you would probably accept a rectangle + // that defines its bounds, and a radius reflecting the "rounded-ness" of the rectangle. + CGRect rrect = CGRectMake(210.0, 90.0, 60.0, 60.0); + CGFloat radius = 10.0; + // NOTE: At this point you may want to verify that your radius is no more than half + // the width and height of your rectangle, as this technique degenerates for those cases. + + // In order to draw a rounded rectangle, we will take advantage of the fact that + // CGContextAddArcToPoint will draw straight lines past the start and end of the arc + // in order to create the path from the current position and the destination position. + + // In order to create the 4 arcs correctly, we need to know the min, mid and max positions + // on the x and y lengths of the given rectangle. + CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); + CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); + + // Next, we will go around the rectangle in the order given by the figure below. + // minx midx maxx + // miny 2 3 4 + // midy 1 9 5 + // maxy 8 7 6 + // Which gives us a coincident start and end point, which is incidental to this technique, but still doesn't + // form a closed path, so we still need to close the path to connect the ends correctly. + // Thus we start by moving to point 1, then adding arcs through each pair of points that follows. + // You could use a similar tecgnique to create any shape with rounded corners. + + // Start at 1 + CGContextMoveToPoint(context, minx, midy); + // Add an arc through 2 to 3 + CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); + // Add an arc through 4 to 5 + CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); + // Add an arc through 6 to 7 + CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); + // Add an arc through 8 to 9 + CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); + // Close the path + CGContextClosePath(context); + // Fill & stroke the path + CGContextDrawPath(context, kCGPathFillStroke); +} + +@end + +@implementation QuartzBezierView + +-(void)drawInContext:(CGContextRef)context +{ + // Drawing with a white stroke color + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + // Draw them with a 2.0 stroke width so they are a bit more visible. + CGContextSetLineWidth(context, 2.0); + + // Draw a bezier curve with end points s,e and control points cp1,cp2 + CGPoint s = CGPointMake(30.0, 120.0); + CGPoint e = CGPointMake(300.0, 120.0); + CGPoint cp1 = CGPointMake(120.0, 30.0); + CGPoint cp2 = CGPointMake(210.0, 210.0); + CGContextMoveToPoint(context, s.x, s.y); + CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y); + CGContextStrokePath(context); + + // Show the control points. + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextMoveToPoint(context, s.x, s.y); + CGContextAddLineToPoint(context, cp1.x, cp1.y); + CGContextMoveToPoint(context, e.x, e.y); + CGContextAddLineToPoint(context, cp2.x, cp2.y); + CGContextStrokePath(context); + + // Draw a quad curve with end points s,e and control point cp1 + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + s = CGPointMake(30.0, 300.0); + e = CGPointMake(270.0, 300.0); + cp1 = CGPointMake(150.0, 180.0); + CGContextMoveToPoint(context, s.x, s.y); + CGContextAddQuadCurveToPoint(context, cp1.x, cp1.y, e.x, e.y); + CGContextStrokePath(context); + + // Show the control point. + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextMoveToPoint(context, s.x, s.y); + CGContextAddLineToPoint(context, cp1.x, cp1.y); + CGContextStrokePath(context); +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzImages.h b/QuartzDemo/Quartz/QuartzImages.h new file mode 100644 index 0000000..f4fb647 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzImages.h @@ -0,0 +1,75 @@ +/* + File: QuartzImages.h + Abstract: Demonstrates using Quartz for drawing images (QuartzImageView), PDF files (QuartzPDFView), and text (QuartzTextView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzImageView : QuartzView +{ + CGImageRef image; +} + +-(void)drawInContext:(CGContextRef)context; + +@end + +@interface QuartzPDFView : QuartzView +{ + CGPDFDocumentRef pdf; +} + +-(void)drawInContext:(CGContextRef)context; + +@end + +@interface QuartzTextView : QuartzView +{ +} + +-(void)drawInContext:(CGContextRef)context; + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzImages.m b/QuartzDemo/Quartz/QuartzImages.m new file mode 100644 index 0000000..c9d3a56 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzImages.m @@ -0,0 +1,207 @@ +/* + File: QuartzImages.m + Abstract: Demonstrates using Quartz for drawing images (QuartzImageView), PDF files (QuartzPDFView), and text (QuartzTextView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzImages.h" + +@implementation QuartzImageView + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"Demo.png" ofType:nil]; + UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; + image = CGImageRetain(img.CGImage); + } + return self; +} + +-(void)dealloc +{ + CGImageRelease(image); + [super dealloc]; +} + +-(void)drawInContext:(CGContextRef)context +{ + CGRect imageRect; + imageRect.origin = CGPointMake(8.0, 8.0); + imageRect.size = CGSizeMake(64.0, 64.0); + + // Note: The images are actually drawn upside down because Quartz image drawing expects + // the coordinate system to have the origin in the lower-left corner, but a UIView + // puts the origin in the upper-left corner. For the sake of brevity (and because + // it likely would go unnoticed for the image used) this is not addressed here. + // For the demonstration of PDF drawing however, it is addressed, as it would definately + // be noticed, and one method of addressing it is shown there. + + // Draw the image in the upper left corner (0,0) with size 64x64 + CGContextDrawImage(context, imageRect, image); + + // Tile the same image across the bottom of the view + // CGContextDrawTiledImage() will fill the entire clipping area with the image, so to avoid + // filling the entire view, we'll clip the view to the rect below. This rect extends + // past the region of the view, but since the view's rectangle has already been applied as a clip + // to our drawing area, it will be intersected with this rect to form the final clipping area + CGContextClipToRect(context, CGRectMake(0.0, 80.0, self.bounds.size.width, self.bounds.size.height)); + + // The origin of the image rect works similarly to the phase parameter for SetLineDash and + // SetPatternPhase and specifies where in the coordinate system the "first" image is drawn. + // The size (previously set to 64x64) specifies the size the image is scaled to before being tiled. + imageRect.origin = CGPointMake(32.0, 112.0); + CGContextDrawTiledImage(context, imageRect, image); + + // Highlight the "first" image from the DrawTiledImage call. + CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5); + CGContextFillRect(context, imageRect); + // And stroke the clipped area + CGContextSetLineWidth(context, 3.0); + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextStrokeRect(context, CGContextGetClipBoundingBox(context)); +} + +@end + +#pragma mark - + +@implementation QuartzPDFView + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("Quartz.pdf"), NULL, NULL); + pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); + CFRelease(pdfURL); + } + return self; +} + +-(void)dealloc +{ + CGPDFDocumentRelease(pdf); + [super dealloc]; +} + +-(void)drawInContext:(CGContextRef)context +{ + // PDF page drawing expects a Lower-Left coordinate system, so we flip the coordinate system + // before we start drawing. + CGContextTranslateCTM(context, 0.0, self.bounds.size.height); + CGContextScaleCTM(context, 1.0, -1.0); + + // Grab the first PDF page + CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); + // We're about to modify the context CTM to draw the PDF page where we want it, so save the graphics state in case we want to do more drawing + CGContextSaveGState(context); + // CGPDFPageGetDrawingTransform provides an easy way to get the transform for a PDF page. It will scale down to fit, including any + // base rotations necessary to display the PDF page correctly. + CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, self.bounds, 0, true); + // And apply the transform. + CGContextConcatCTM(context, pdfTransform); + // Finally, we draw the page and restore the graphics state for further manipulations! + CGContextDrawPDFPage(context, page); + CGContextRestoreGState(context); +} + +@end + +#pragma mark - + +@implementation QuartzTextView + +#define kTextString "Hello From Quartz" +#define kTextStringLength strlen(kTextString) + +-(void)drawInContext:(CGContextRef)context +{ + CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + + // Some initial setup for our text drawing needs. + // First, we will be doing our drawing in Helvetica-36pt with the MacRoman encoding. + // This is an 8-bit encoding that can reference standard ASCII characters + // and many common characters used in the Americas and Western Europe. + CGContextSelectFont(context, "Helvetica", 36.0, kCGEncodingMacRoman); + // Next we set the text matrix to flip our text upside down. We do this because the context itself + // is flipped upside down relative to the expected orientation for drawing text (much like the case for drawing Images & PDF). + CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, -1.0)); + // And now we actually draw some text. This screen will demonstrate the typical drawing modes used. + CGContextSetTextDrawingMode(context, kCGTextFill); + CGContextShowTextAtPoint(context, 10.0, 30.0, kTextString, kTextStringLength); + CGContextSetTextDrawingMode(context, kCGTextStroke); + CGContextShowTextAtPoint(context, 10.0, 70.0, kTextString, kTextStringLength); + CGContextSetTextDrawingMode(context, kCGTextFillStroke); + CGContextShowTextAtPoint(context, 10.0, 110.0, kTextString, kTextStringLength); + + // Now lets try the more complex Glyph functions. These functions allow you to draw any glyph available in a font, + // but provide no assistance with converting characters to glyphs or layout, and as such require considerably more knowledge + // of text to use correctly. Specifically, you need to understand Unicode encoding and how to interpret the information + // present in the font itself, such as the cmap table. + // To get you started, we are going to do the minimum necessary to draw a glyphs into the current context. + CGFontRef helvetica = CGFontCreateWithFontName((CFStringRef)@"Helvetica"); + CGContextSetFont(context, helvetica); + CGContextSetFontSize(context, 12.0); + CGContextSetTextDrawingMode(context, kCGTextFill); + // Next we'll display lots of glyphs from the font. + CGGlyph start = 0; + for(int y = 0; y < 20; ++y) + { + CGGlyph glyphs[32]; + for(int i = 0; i < 32; ++i) + { + glyphs[i] = start + i; + } + start += 32; + CGContextShowGlyphsAtPoint(context, 10.0, 150.0 + 12 * y, glyphs, 32); + } + CGFontRelease(helvetica); +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzLines.h b/QuartzDemo/Quartz/QuartzLines.h new file mode 100644 index 0000000..563406c --- /dev/null +++ b/QuartzDemo/Quartz/QuartzLines.h @@ -0,0 +1,87 @@ +/* + File: QuartzLines.h + Abstract: Demonstrates Quartz line drawing facilities (QuartzLineView), including dash patterns (QuartzDashView), stroke width, line cap and line join (QuartzCapJoinWidthView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzLineView : QuartzView +{ +} + +-(void)drawInContext:(CGContextRef)context; + +@end + +#pragma mark - + +@interface QuartzDashView : QuartzView +{ + CGFloat dashPhase; + CGFloat dashPattern[10]; + size_t dashCount; +} + +-(void)drawInContext:(CGContextRef)context; +@property(nonatomic, readwrite) CGFloat dashPhase; +-(void)setDashPattern:(CGFloat*)pattern count:(size_t)count; + +@end + +#pragma mark - + +@interface QuartzCapJoinWidthView : QuartzView +{ + CGLineCap cap; + CGLineJoin join; + CGFloat width; +} + +@property(nonatomic, readwrite) CGLineCap cap; +@property(nonatomic, readwrite) CGLineJoin join; +@property(nonatomic, readwrite) CGFloat width; + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzLines.m b/QuartzDemo/Quartz/QuartzLines.m new file mode 100644 index 0000000..d32dcdc --- /dev/null +++ b/QuartzDemo/Quartz/QuartzLines.m @@ -0,0 +1,256 @@ +/* + File: QuartzLines.m + Abstract: Demonstrates Quartz line drawing facilities (QuartzLineView), including dash patterns (QuartzDashView), stroke width, line cap and line join (QuartzCapJoinWidthView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzLines.h" + +@implementation QuartzLineView + +-(void)drawInContext:(CGContextRef)context +{ + // Drawing lines with a white stroke color + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + // Draw them with a 2.0 stroke width so they are a bit more visible. + CGContextSetLineWidth(context, 2.0); + + // Draw a single line from left to right + CGContextMoveToPoint(context, 10.0, 30.0); + CGContextAddLineToPoint(context, 310.0, 30.0); + CGContextStrokePath(context); + + // Draw a connected sequence of line segments + CGPoint addLines[] = + { + CGPointMake(10.0, 90.0), + CGPointMake(70.0, 60.0), + CGPointMake(130.0, 90.0), + CGPointMake(190.0, 60.0), + CGPointMake(250.0, 90.0), + CGPointMake(310.0, 60.0), + }; + // Bulk call to add lines to the current path. + // Equivalent to MoveToPoint(points[0]); for(i=1; i= 4.0) // arbitrarily only show when the line is at least twice as wide as our target stroke + { + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextMoveToPoint(context, 40.0, 30.0); + CGContextAddLineToPoint(context, 280.0, 30.0); + CGContextMoveToPoint(context, 40.0, 190.0); + CGContextAddLineToPoint(context, 160.0, 70.0); + CGContextAddLineToPoint(context, 280.0, 190.0); + CGContextSetLineWidth(context, 2.0); + CGContextStrokePath(context); + } +} + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzPolygons.h b/QuartzDemo/Quartz/QuartzPolygons.h new file mode 100644 index 0000000..90370fc --- /dev/null +++ b/QuartzDemo/Quartz/QuartzPolygons.h @@ -0,0 +1,67 @@ +/* + File: QuartzPolygons.h + Abstract: Demonstrates using Quartz to stroke & fill rectangles (QuartzRectView) and polygons (QuartzPolygonView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +@interface QuartzRectView : QuartzView +{ +} + +-(void)drawInContext:(CGContextRef)context; + +@end + +@interface QuartzPolygonView : QuartzView +{ + CGPathDrawingMode drawingMode; +} + +-(void)drawInContext:(CGContextRef)context; +@property(nonatomic, readwrite) CGPathDrawingMode drawingMode; + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzPolygons.m b/QuartzDemo/Quartz/QuartzPolygons.m new file mode 100644 index 0000000..cf9be08 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzPolygons.m @@ -0,0 +1,148 @@ +/* + File: QuartzPolygons.m + Abstract: Demonstrates using Quartz to stroke & fill rectangles (QuartzRectView) and polygons (QuartzPolygonView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzPolygons.h" + +@implementation QuartzRectView + +-(void)drawInContext:(CGContextRef)context +{ + // Drawing with a white stroke color + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + // And drawing with a blue fill color + CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0); + // Draw them with a 2.0 stroke width so they are a bit more visible. + CGContextSetLineWidth(context, 2.0); + + // Add Rect to the current path, then stroke it + CGContextAddRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0)); + CGContextStrokePath(context); + + // Stroke Rect convenience that is equivalent to above + CGContextStrokeRect(context, CGRectMake(30.0, 120.0, 60.0, 60.0)); + + // Stroke rect convenience equivalent to the above, plus a call to CGContextSetLineWidth(). + CGContextStrokeRectWithWidth(context, CGRectMake(30.0, 210.0, 60.0, 60.0), 10.0); + // Demonstate the stroke is on both sides of the path. + CGContextSaveGState(context); + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextStrokeRectWithWidth(context, CGRectMake(30.0, 210.0, 60.0, 60.0), 2.0); + CGContextRestoreGState(context); + + CGRect rects[] = + { + CGRectMake(120.0, 30.0, 60.0, 60.0), + CGRectMake(120.0, 120.0, 60.0, 60.0), + CGRectMake(120.0, 210.0, 60.0, 60.0), + }; + // Bulk call to add rects to the current path. + CGContextAddRects(context, rects, sizeof(rects)/sizeof(rects[0])); + CGContextStrokePath(context); + + // Create filled rectangles via two different paths. + // Add/Fill path + CGContextAddRect(context, CGRectMake(210.0, 30.0, 60.0, 60.0)); + CGContextFillPath(context); + // Fill convienience. + CGContextFillRect(context, CGRectMake(210.0, 120.0, 60.0, 60.0)); +} + +@end + +@implementation QuartzPolygonView + +@synthesize drawingMode; + +-(void)setDrawingMode:(CGPathDrawingMode)mode +{ + if(mode != drawingMode) + { + drawingMode = mode; + [self setNeedsDisplay]; + } +} + +-(void)drawInContext:(CGContextRef)context +{ + // Drawing with a white stroke color + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + // Drawing with a blue fill color + CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0); + // Draw them with a 2.0 stroke width so they are a bit more visible. + CGContextSetLineWidth(context, 2.0); + + CGPoint center; + + // Add a star to the current path + center = CGPointMake(90.0, 90.0); + CGContextMoveToPoint(context, center.x, center.y + 60.0); + for(int i = 1; i < 5; ++i) + { + CGFloat x = 60.0 * sinf(i * 4.0 * M_PI / 5.0); + CGFloat y = 60.0 * cosf(i * 4.0 * M_PI / 5.0); + CGContextAddLineToPoint(context, center.x + x, center.y + y); + } + // And close the subpath. + CGContextClosePath(context); + + // Now add the hexagon to the current path + center = CGPointMake(210.0, 90.0); + CGContextMoveToPoint(context, center.x, center.y + 60.0); + for(int i = 1; i < 6; ++i) + { + CGFloat x = 60.0 * sinf(i * 2.0 * M_PI / 6.0); + CGFloat y = 60.0 * cosf(i * 2.0 * M_PI / 6.0); + CGContextAddLineToPoint(context, center.x + x, center.y + y); + } + // And close the subpath. + CGContextClosePath(context); + + // Now draw the star & hexagon with the current drawing mode. + CGContextDrawPath(context, drawingMode); +} + +@end diff --git a/QuartzDemo/Quartz/QuartzRendering.h b/QuartzDemo/Quartz/QuartzRendering.h new file mode 100644 index 0000000..0f7cfe7 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzRendering.h @@ -0,0 +1,81 @@ +/* + File: QuartzRendering.h + Abstract: Demonstrates using Quartz for drawing gradients (QuartzGradientView) and patterns (QuartzPatternView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "QuartzView.h" + +enum +{ + kLinearGradient = 0, + kRadialGradient = 1 +}; + +@interface QuartzGradientView : QuartzView +{ + CGGradientRef gradient; + int type; + BOOL extendsPastStart, extendsPastEnd; +} + +-(void)drawInContext:(CGContextRef)context; +@property(nonatomic, readwrite) int type; +@property(nonatomic, readwrite) BOOL extendsPastStart; +@property(nonatomic, readwrite) BOOL extendsPastEnd; + +@end + +@interface QuartzPatternView : QuartzView +{ + CGColorRef coloredPatternColor; + + CGPatternRef uncoloredPattern; + CGColorSpaceRef uncoloredPatternColorSpace; +} + +-(void)drawInContext:(CGContextRef)context; + +@end \ No newline at end of file diff --git a/QuartzDemo/Quartz/QuartzRendering.m b/QuartzDemo/Quartz/QuartzRendering.m new file mode 100644 index 0000000..071e407 --- /dev/null +++ b/QuartzDemo/Quartz/QuartzRendering.m @@ -0,0 +1,318 @@ +/* + File: QuartzRendering.m + Abstract: Demonstrates using Quartz for drawing gradients (QuartzGradientView) and patterns (QuartzPatternView). + Version: 2.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "QuartzRendering.h" + +@implementation QuartzGradientView + +@synthesize type, extendsPastStart, extendsPastEnd; + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); + CGFloat colors[] = + { + 204.0 / 255.0, 224.0 / 255.0, 244.0 / 255.0, 1.00, + 29.0 / 255.0, 156.0 / 255.0, 215.0 / 255.0, 1.00, + 0.0 / 255.0, 50.0 / 255.0, 126.0 / 255.0, 1.00, + }; + gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4)); + CGColorSpaceRelease(rgb); + } + return self; +} + +-(void)setType:(int)newType +{ + if(newType != type) + { + type = newType; + [self setNeedsDisplay]; + } +} + +-(void)setExtendsPastStart:(BOOL)yn +{ + if(yn != extendsPastStart) + { + extendsPastStart = yn; + [self setNeedsDisplay]; + } +} + +-(void)setExtendsPastEnd:(BOOL)yn +{ + if(yn != extendsPastEnd) + { + extendsPastEnd = yn; + [self setNeedsDisplay]; + } +} + +-(void)dealloc +{ + CGGradientRelease(gradient); + [super dealloc]; +} + +// Returns an appropriate starting point for the demonstration of a linear gradient +CGPoint demoLGStart(CGRect bounds) +{ + return CGPointMake(bounds.origin.x, bounds.origin.y + bounds.size.height * 0.25); +} + +// Returns an appropriate ending point for the demonstration of a linear gradient +CGPoint demoLGEnd(CGRect bounds) +{ + return CGPointMake(bounds.origin.x, bounds.origin.y + bounds.size.height * 0.75); +} + +// Returns the center point for for the demonstration of the radial gradient +CGPoint demoRGCenter(CGRect bounds) +{ + return CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); +} + +// Returns an appropriate inner radius for the demonstration of the radial gradient +CGFloat demoRGInnerRadius(CGRect bounds) +{ + CGFloat r = bounds.size.width < bounds.size.height ? bounds.size.width : bounds.size.height; + return r * 0.125; +} + +// Returns an appropriate outer radius for the demonstration of the radial gradient +CGFloat demoRGOuterRadius(CGRect bounds) +{ + CGFloat r = bounds.size.width < bounds.size.height ? bounds.size.width : bounds.size.height; + return r * 0.5; +} + +-(CGGradientDrawingOptions)drawingOptions +{ + CGGradientDrawingOptions options = 0; + if(extendsPastStart) + { + options |= kCGGradientDrawsBeforeStartLocation; + } + if(extendsPastEnd) + { + options |= kCGGradientDrawsAfterEndLocation; + } + return options; +} + +-(void)drawInContext:(CGContextRef)context +{ + // Use the clip bounding box, sans a generous border + CGRect clip = CGRectInset(CGContextGetClipBoundingBox(context), 20.0, 20.0); + + CGPoint start, end; + CGFloat startRadius, endRadius; + + // Clip to area to draw the gradient, and draw it. Since we are clipping, we save the graphics state + // so that we can revert to the previous larger area. + CGContextSaveGState(context); + CGContextClipToRect(context, clip); + + CGGradientDrawingOptions options = [self drawingOptions]; + switch(type) + { + case kLinearGradient: + // A linear gradient requires only a starting & ending point. + // The colors of the gradient are linearly interpolated along the line segment connecting these two points + // A gradient location of 0.0 means that color is expressed fully at the 'start' point + // a location of 1.0 means that color is expressed fully at the 'end' point. + // The gradient fills outwards perpendicular to the line segment connectiong start & end points + // (which is why we need to clip the context, or the gradient would fill beyond where we want it to). + // The gradient options (last) parameter determines what how to fill the clip area that is "before" and "after" + // the line segment connecting start & end. + start = demoLGStart(clip); + end = demoLGEnd(clip); + CGContextDrawLinearGradient(context, gradient, start, end, options); + CGContextRestoreGState(context); + break; + + case kRadialGradient: + // A radial gradient requires a start & end point as well as a start & end radius. + // Logically a radial gradient is created by linearly interpolating the center, radius and color of each + // circle using the start and end point for the center, start and end radius for the radius, and the color ramp + // inherant to the gradient to create a set of stroked circles that fill the area completely. + // The gradient options specify if this interpolation continues past the start or end points as it does with + // linear gradients. + start = end = demoRGCenter(clip); + startRadius = demoRGInnerRadius(clip); + endRadius = demoRGOuterRadius(clip); + CGContextDrawRadialGradient(context, gradient, start, startRadius, end, endRadius, options); + CGContextRestoreGState(context); + break; + } + + // Show the clip rect + CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); + CGContextStrokeRectWithWidth(context, clip, 2.0); +} + +@end + +@implementation QuartzPatternView + +// Colored patterns specify colors as part of their drawing +void ColoredPatternCallback(void *info, CGContextRef context) +{ + // Dark Blue + CGContextSetRGBFillColor(context, 29.0 / 255.0, 156.0 / 255.0, 215.0 / 255.0, 1.00); + CGContextFillRect(context, CGRectMake(0.0, 0.0, 8.0, 8.0)); + CGContextFillRect(context, CGRectMake(8.0, 8.0, 8.0, 8.0)); + + // Light Blue + CGContextSetRGBFillColor(context, 204.0 / 255.0, 224.0 / 255.0, 244.0 / 255.0, 1.00); + CGContextFillRect(context, CGRectMake(8.0, 0.0, 8.0, 8.0)); + CGContextFillRect(context, CGRectMake(0.0, 8.0, 8.0, 8.0)); +} + +// Uncolored patterns take their color from the given context +void UncoloredPatternCallback(void *info, CGContextRef context) +{ + CGContextFillRect(context, CGRectMake(0.0, 0.0, 8.0, 8.0)); + CGContextFillRect(context, CGRectMake(8.0, 8.0, 8.0, 8.0)); +} + +-(id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if(self != nil) + { + // Colored Pattern setup + CGPatternCallbacks coloredPatternCallbacks = {0, ColoredPatternCallback, NULL}; + // First we need to create a CGPatternRef that specifies the qualities of our pattern. + CGPatternRef coloredPattern = CGPatternCreate( + NULL, // 'info' pointer for our callback + CGRectMake(0.0, 0.0, 16.0, 16.0), // the pattern coordinate space, drawing is clipped to this rectangle + CGAffineTransformIdentity, // a transform on the pattern coordinate space used before it is drawn. + 16.0, 16.0, // the spacing (horizontal, vertical) of the pattern - how far to move after drawing each cell + kCGPatternTilingNoDistortion, + true, // this is a colored pattern, which means that you only specify an alpha value when drawing it + &coloredPatternCallbacks); // the callbacks for this pattern. + + // To draw a pattern, you need a pattern colorspace. + // Since this is an colored pattern, the parent colorspace is NULL, indicating that it only has an alpha value. + CGColorSpaceRef coloredPatternColorSpace = CGColorSpaceCreatePattern(NULL); + CGFloat alpha = 1.0; + // Since this pattern is colored, we'll create a CGColorRef for it to make drawing it easier and more efficient. + // From here on, the colored pattern is referenced entirely via the associated CGColorRef rather than the + // originally created CGPatternRef. + coloredPatternColor = CGColorCreateWithPattern(coloredPatternColorSpace, coloredPattern, &alpha); + CGColorSpaceRelease(coloredPatternColorSpace); + CGPatternRelease(coloredPattern); + + // Uncolored Pattern setup + CGPatternCallbacks uncoloredPatternCallbacks = {0, UncoloredPatternCallback, NULL}; + // As above, we create a CGPatternRef that specifies the qualities of our pattern + uncoloredPattern = CGPatternCreate( + NULL, // 'info' pointer + CGRectMake(0.0, 0.0, 16.0, 16.0), // coordinate space + CGAffineTransformIdentity, // transform + 16.0, 16.0, // spacing + kCGPatternTilingNoDistortion, + false, // this is an uncolored pattern, thus to draw it we need to specify both color and alpha + &uncoloredPatternCallbacks); // callbacks for this pattern + + // With an uncolored pattern we still need to create a pattern colorspace, but now we need a parent colorspace + // We'll use the DeviceRGB colorspace here. We'll need this colorspace along with the CGPatternRef to draw this pattern later. + CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); + uncoloredPatternColorSpace = CGColorSpaceCreatePattern(deviceRGB); + CGColorSpaceRelease(deviceRGB); + } + return self; +} + +-(void)dealloc +{ + CGColorRelease(coloredPatternColor); + CGPatternRelease(uncoloredPattern); + CGColorSpaceRelease(uncoloredPatternColorSpace); + [super dealloc]; +} + +-(void)drawInContext:(CGContextRef)context +{ + // Draw the colored pattern. Since we have a CGColorRef for this pattern, we just set + // that color current and draw. + CGContextSetFillColorWithColor(context, coloredPatternColor); + CGContextFillRect(context, CGRectMake(10.0, 10.0, 90.0, 90.0)); + + // You can also stroke with a pattern. + CGContextSetStrokeColorWithColor(context, coloredPatternColor); + CGContextStrokeRectWithWidth(context, CGRectMake(120.0, 10.0, 90.0, 90.0), 8.0); + + // Since we aren't encapsulating our pattern in a CGColorRef for the uncolored pattern case, setup requires two steps. + // First you have to set the context's current colorspace (fill or stroke) to a pattern colorspace, + // indicating to Quartz that you want to draw a pattern. + CGContextSetFillColorSpace(context, uncoloredPatternColorSpace); + // Next you set the pattern and the color that you want the pattern to draw with. + CGFloat color1[] = {1.0, 0.0, 0.0, 1.0}; + CGContextSetFillPattern(context, uncoloredPattern, color1); + // And finally you draw! + CGContextFillRect(context, CGRectMake(10.0, 120.0, 90.0, 90.0)); + // As long as the current colorspace is a pattern colorspace, you are free to change the pattern or pattern color + CGFloat color2[] = {0.0, 1.0, 0.0, 1.0}; + CGContextSetFillPattern(context, uncoloredPattern, color2); + CGContextFillRect(context, CGRectMake(10.0, 230.0, 90.0, 90.0)); + + // And of course, just like the colored case, you can stroke with a pattern as well. + CGContextSetStrokeColorSpace(context, uncoloredPatternColorSpace); + CGContextSetStrokePattern(context, uncoloredPattern, color1); + CGContextStrokeRectWithWidth(context, CGRectMake(120.0, 120.0, 90.0, 90.0), 8.0); + // As long as the current colorspace is a pattern colorspace, you are free to change the pattern or pattern color + CGContextSetStrokePattern(context, uncoloredPattern, color2); + CGContextStrokeRectWithWidth(context, CGRectMake(120.0, 230.0, 90.0, 90.0), 8.0); +} + +@end \ No newline at end of file diff --git a/QuartzDemo/QuartzDemo.xcodeproj/project.pbxproj b/QuartzDemo/QuartzDemo.xcodeproj/project.pbxproj new file mode 100755 index 0000000..045e9d5 --- /dev/null +++ b/QuartzDemo/QuartzDemo.xcodeproj/project.pbxproj @@ -0,0 +1,485 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 180169520D74A304009C73C4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1801694F0D74A304009C73C4 /* AppDelegate.m */; }; + 180169530D74A304009C73C4 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 180169510D74A304009C73C4 /* MainViewController.m */; }; + 1801697A0D74A7D6009C73C4 /* QuartzViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 180169790D74A7D6009C73C4 /* QuartzViewController.m */; }; + 180169850D74A9B3009C73C4 /* QuartzView.m in Sources */ = {isa = PBXBuildFile; fileRef = 180169840D74A9B3009C73C4 /* QuartzView.m */; }; + 189B559911D5305000C7FC9F /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 189B559211D5305000C7FC9F /* Icon-72.png */; }; + 189B559A11D5305000C7FC9F /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 189B559311D5305000C7FC9F /* Icon-Small-50.png */; }; + 189B559B11D5305000C7FC9F /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 189B559411D5305000C7FC9F /* Icon-Small.png */; }; + 189B559C11D5305000C7FC9F /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 189B559511D5305000C7FC9F /* Icon-Small@2x.png */; }; + 189B559D11D5305000C7FC9F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 189B559611D5305000C7FC9F /* Icon.png */; }; + 189B559E11D5305000C7FC9F /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 189B559711D5305000C7FC9F /* Icon@2x.png */; }; + 189B559F11D5305000C7FC9F /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 189B559811D5305000C7FC9F /* iTunesArtwork */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 631D0B910DDCF1F2005A1D7E /* Quartz.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 631D0B8D0DDCF1F2005A1D7E /* Quartz.pdf */; }; + 631D0B920DDCF1F2005A1D7E /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 631D0B8F0DDCF1F2005A1D7E /* MainWindow.xib */; }; + 632AE2F7103F2F6500B27215 /* QuartzClipping.m in Sources */ = {isa = PBXBuildFile; fileRef = 632AE2F6103F2F6500B27215 /* QuartzClipping.m */; }; + 634E29360FB238D700914D43 /* QuartzBlending.m in Sources */ = {isa = PBXBuildFile; fileRef = 634E29350FB238D700914D43 /* QuartzBlending.m */; }; + 635355FF0F72F83A00069877 /* DemoView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 635355FD0F72F83A00069877 /* DemoView.xib */; }; + 637E16830D81F47F008C6A09 /* Demo.png in Resources */ = {isa = PBXBuildFile; fileRef = 637E16800D81F47F008C6A09 /* Demo.png */; }; + 63C2117710F403A50032417F /* DashView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63C2117510F403A50032417F /* DashView.xib */; }; + 63C2118C10F405550032417F /* QuartzDashViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C2118B10F405550032417F /* QuartzDashViewController.m */; }; + 63C2152610F7ED6E0032417F /* Ship.png in Resources */ = {isa = PBXBuildFile; fileRef = 63C2152510F7ED6E0032417F /* Ship.png */; }; + 63C2176810FCFCFE0032417F /* QuartzCurves.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C2176710FCFCFE0032417F /* QuartzCurves.m */; }; + 63C2176B10FCFD160032417F /* QuartzImages.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C2176A10FCFD160032417F /* QuartzImages.m */; }; + 63C2176E10FCFD1B0032417F /* QuartzLines.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C2176D10FCFD1B0032417F /* QuartzLines.m */; }; + 63C2177110FCFD380032417F /* QuartzPolygons.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C2177010FCFD380032417F /* QuartzPolygons.m */; }; + 63C2177410FCFD520032417F /* QuartzRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C2177310FCFD520032417F /* QuartzRendering.m */; }; + 63CADE8910F1526300CE551A /* QuartzPolyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CADE8810F1526300CE551A /* QuartzPolyViewController.m */; }; + 63CADEBC10F1552A00CE551A /* PolyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63CADEBA10F1552A00CE551A /* PolyView.xib */; }; + 63CADF7510F159AA00CE551A /* QuartzGradientViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CADF7410F159AA00CE551A /* QuartzGradientViewController.m */; }; + 63CADF7D10F15AB700CE551A /* GradientView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63CADF7B10F15AB700CE551A /* GradientView.xib */; }; + 63CADFF810F1635200CE551A /* LineView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63CADFF610F1635200CE551A /* LineView.xib */; }; + 63CADFFC10F1637700CE551A /* QuartzLineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CADFFB10F1637700CE551A /* QuartzLineViewController.m */; }; + 63F0AB770F8C236D00568150 /* BlendView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63F0AB750F8C236D00568150 /* BlendView.xib */; }; + 63F0AB7C0F8C23DA00568150 /* QuartzBlendingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F0AB7B0F8C23DA00568150 /* QuartzBlendingViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1801694E0D74A304009C73C4 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1801694F0D74A304009C73C4 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 180169500D74A304009C73C4 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 180169510D74A304009C73C4 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 180169780D74A7D6009C73C4 /* QuartzViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzViewController.h; sourceTree = ""; }; + 180169790D74A7D6009C73C4 /* QuartzViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzViewController.m; sourceTree = ""; }; + 180169830D74A9B3009C73C4 /* QuartzView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzView.h; sourceTree = ""; }; + 180169840D74A9B3009C73C4 /* QuartzView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzView.m; sourceTree = ""; }; + 189B559211D5305000C7FC9F /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 189B559311D5305000C7FC9F /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 189B559411D5305000C7FC9F /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 189B559511D5305000C7FC9F /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 189B559611D5305000C7FC9F /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 189B559711D5305000C7FC9F /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 189B559811D5305000C7FC9F /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* QuartzDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QuartzDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 631D0B8E0DDCF1F2005A1D7E /* Quartz.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = Quartz.pdf; path = Resources/en.lproj/Quartz.pdf; sourceTree = ""; }; + 631D0B900DDCF1F2005A1D7E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/MainWindow.xib; sourceTree = ""; }; + 632AE2F5103F2F6500B27215 /* QuartzClipping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzClipping.h; sourceTree = ""; }; + 632AE2F6103F2F6500B27215 /* QuartzClipping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzClipping.m; sourceTree = ""; }; + 634E29340FB238D700914D43 /* QuartzBlending.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzBlending.h; sourceTree = ""; }; + 634E29350FB238D700914D43 /* QuartzBlending.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzBlending.m; sourceTree = ""; }; + 635355FE0F72F83A00069877 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/DemoView.xib; sourceTree = ""; }; + 637E16800D81F47F008C6A09 /* Demo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Demo.png; path = Resources/Demo.png; sourceTree = ""; }; + 637E16BA0D81FEFE008C6A09 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 63A425480DBF10AF0012B64A /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 63C2117610F403A50032417F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/DashView.xib; sourceTree = ""; }; + 63C2118A10F405550032417F /* QuartzDashViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzDashViewController.h; sourceTree = ""; }; + 63C2118B10F405550032417F /* QuartzDashViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzDashViewController.m; sourceTree = ""; }; + 63C2152510F7ED6E0032417F /* Ship.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Ship.png; path = Resources/Ship.png; sourceTree = ""; }; + 63C2176610FCFCFE0032417F /* QuartzCurves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzCurves.h; sourceTree = ""; }; + 63C2176710FCFCFE0032417F /* QuartzCurves.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzCurves.m; sourceTree = ""; }; + 63C2176910FCFD160032417F /* QuartzImages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzImages.h; sourceTree = ""; }; + 63C2176A10FCFD160032417F /* QuartzImages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzImages.m; sourceTree = ""; }; + 63C2176C10FCFD1B0032417F /* QuartzLines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzLines.h; sourceTree = ""; }; + 63C2176D10FCFD1B0032417F /* QuartzLines.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzLines.m; sourceTree = ""; }; + 63C2176F10FCFD380032417F /* QuartzPolygons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzPolygons.h; sourceTree = ""; }; + 63C2177010FCFD380032417F /* QuartzPolygons.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzPolygons.m; sourceTree = ""; }; + 63C2177210FCFD520032417F /* QuartzRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzRendering.h; sourceTree = ""; }; + 63C2177310FCFD520032417F /* QuartzRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzRendering.m; sourceTree = ""; }; + 63CADE8710F1526300CE551A /* QuartzPolyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzPolyViewController.h; sourceTree = ""; }; + 63CADE8810F1526300CE551A /* QuartzPolyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzPolyViewController.m; sourceTree = ""; }; + 63CADEBB10F1552A00CE551A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/PolyView.xib; sourceTree = ""; }; + 63CADF7310F159AA00CE551A /* QuartzGradientViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzGradientViewController.h; sourceTree = ""; }; + 63CADF7410F159AA00CE551A /* QuartzGradientViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzGradientViewController.m; sourceTree = ""; }; + 63CADF7C10F15AB700CE551A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/GradientView.xib; sourceTree = ""; }; + 63CADFF710F1635200CE551A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/LineView.xib; sourceTree = ""; }; + 63CADFFA10F1637700CE551A /* QuartzLineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzLineViewController.h; sourceTree = ""; }; + 63CADFFB10F1637700CE551A /* QuartzLineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzLineViewController.m; sourceTree = ""; }; + 63F0AB760F8C236D00568150 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/BlendView.xib; sourceTree = ""; }; + 63F0AB7A0F8C23DA00568150 /* QuartzBlendingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzBlendingViewController.h; sourceTree = ""; }; + 63F0AB7B0F8C23DA00568150 /* QuartzBlendingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzBlendingViewController.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1801694E0D74A304009C73C4 /* AppDelegate.h */, + 1801694F0D74A304009C73C4 /* AppDelegate.m */, + 180169500D74A304009C73C4 /* MainViewController.h */, + 180169510D74A304009C73C4 /* MainViewController.m */, + 180169830D74A9B3009C73C4 /* QuartzView.h */, + 180169840D74A9B3009C73C4 /* QuartzView.m */, + 180169780D74A7D6009C73C4 /* QuartzViewController.h */, + 180169790D74A7D6009C73C4 /* QuartzViewController.m */, + 63F0AB7A0F8C23DA00568150 /* QuartzBlendingViewController.h */, + 63F0AB7B0F8C23DA00568150 /* QuartzBlendingViewController.m */, + 63CADE8710F1526300CE551A /* QuartzPolyViewController.h */, + 63CADE8810F1526300CE551A /* QuartzPolyViewController.m */, + 63CADF7310F159AA00CE551A /* QuartzGradientViewController.h */, + 63CADF7410F159AA00CE551A /* QuartzGradientViewController.m */, + 63CADFFA10F1637700CE551A /* QuartzLineViewController.h */, + 63CADFFB10F1637700CE551A /* QuartzLineViewController.m */, + 63C2118A10F405550032417F /* QuartzDashViewController.h */, + 63C2118B10F405550032417F /* QuartzDashViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 180169B40D74CEA4009C73C4 /* Quartz */ = { + isa = PBXGroup; + children = ( + 634E29340FB238D700914D43 /* QuartzBlending.h */, + 634E29350FB238D700914D43 /* QuartzBlending.m */, + 632AE2F5103F2F6500B27215 /* QuartzClipping.h */, + 632AE2F6103F2F6500B27215 /* QuartzClipping.m */, + 63C2176610FCFCFE0032417F /* QuartzCurves.h */, + 63C2176710FCFCFE0032417F /* QuartzCurves.m */, + 63C2176910FCFD160032417F /* QuartzImages.h */, + 63C2176A10FCFD160032417F /* QuartzImages.m */, + 63C2176C10FCFD1B0032417F /* QuartzLines.h */, + 63C2176D10FCFD1B0032417F /* QuartzLines.m */, + 63C2176F10FCFD380032417F /* QuartzPolygons.h */, + 63C2177010FCFD380032417F /* QuartzPolygons.m */, + 63C2177210FCFD520032417F /* QuartzRendering.h */, + 63C2177310FCFD520032417F /* QuartzRendering.m */, + ); + path = Quartz; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* QuartzDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 63A425480DBF10AF0012B64A /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 180169B40D74CEA4009C73C4 /* Quartz */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 189B559211D5305000C7FC9F /* Icon-72.png */, + 189B559311D5305000C7FC9F /* Icon-Small-50.png */, + 189B559411D5305000C7FC9F /* Icon-Small.png */, + 189B559511D5305000C7FC9F /* Icon-Small@2x.png */, + 189B559611D5305000C7FC9F /* Icon.png */, + 189B559711D5305000C7FC9F /* Icon@2x.png */, + 189B559811D5305000C7FC9F /* iTunesArtwork */, + 631D0B8D0DDCF1F2005A1D7E /* Quartz.pdf */, + 631D0B8F0DDCF1F2005A1D7E /* MainWindow.xib */, + 635355FD0F72F83A00069877 /* DemoView.xib */, + 63F0AB750F8C236D00568150 /* BlendView.xib */, + 63CADEBA10F1552A00CE551A /* PolyView.xib */, + 63CADF7B10F15AB700CE551A /* GradientView.xib */, + 63CADFF610F1635200CE551A /* LineView.xib */, + 63C2117510F403A50032417F /* DashView.xib */, + 637E16BA0D81FEFE008C6A09 /* Info.plist */, + 637E16800D81F47F008C6A09 /* Demo.png */, + 63C2152510F7ED6E0032417F /* Ship.png */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* QuartzDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "QuartzDemo" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = QuartzDemo; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* QuartzDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "QuartzDemo" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* QuartzDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 637E16830D81F47F008C6A09 /* Demo.png in Resources */, + 631D0B910DDCF1F2005A1D7E /* Quartz.pdf in Resources */, + 631D0B920DDCF1F2005A1D7E /* MainWindow.xib in Resources */, + 635355FF0F72F83A00069877 /* DemoView.xib in Resources */, + 63F0AB770F8C236D00568150 /* BlendView.xib in Resources */, + 63CADEBC10F1552A00CE551A /* PolyView.xib in Resources */, + 63CADF7D10F15AB700CE551A /* GradientView.xib in Resources */, + 63CADFF810F1635200CE551A /* LineView.xib in Resources */, + 63C2117710F403A50032417F /* DashView.xib in Resources */, + 63C2152610F7ED6E0032417F /* Ship.png in Resources */, + 189B559911D5305000C7FC9F /* Icon-72.png in Resources */, + 189B559A11D5305000C7FC9F /* Icon-Small-50.png in Resources */, + 189B559B11D5305000C7FC9F /* Icon-Small.png in Resources */, + 189B559C11D5305000C7FC9F /* Icon-Small@2x.png in Resources */, + 189B559D11D5305000C7FC9F /* Icon.png in Resources */, + 189B559E11D5305000C7FC9F /* Icon@2x.png in Resources */, + 189B559F11D5305000C7FC9F /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 180169520D74A304009C73C4 /* AppDelegate.m in Sources */, + 180169530D74A304009C73C4 /* MainViewController.m in Sources */, + 1801697A0D74A7D6009C73C4 /* QuartzViewController.m in Sources */, + 180169850D74A9B3009C73C4 /* QuartzView.m in Sources */, + 63F0AB7C0F8C23DA00568150 /* QuartzBlendingViewController.m in Sources */, + 634E29360FB238D700914D43 /* QuartzBlending.m in Sources */, + 632AE2F7103F2F6500B27215 /* QuartzClipping.m in Sources */, + 63CADE8910F1526300CE551A /* QuartzPolyViewController.m in Sources */, + 63CADF7510F159AA00CE551A /* QuartzGradientViewController.m in Sources */, + 63CADFFC10F1637700CE551A /* QuartzLineViewController.m in Sources */, + 63C2118C10F405550032417F /* QuartzDashViewController.m in Sources */, + 63C2176810FCFCFE0032417F /* QuartzCurves.m in Sources */, + 63C2176B10FCFD160032417F /* QuartzImages.m in Sources */, + 63C2176E10FCFD1B0032417F /* QuartzLines.m in Sources */, + 63C2177110FCFD380032417F /* QuartzPolygons.m in Sources */, + 63C2177410FCFD520032417F /* QuartzRendering.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 631D0B8D0DDCF1F2005A1D7E /* Quartz.pdf */ = { + isa = PBXVariantGroup; + children = ( + 631D0B8E0DDCF1F2005A1D7E /* Quartz.pdf */, + ); + name = Quartz.pdf; + sourceTree = ""; + }; + 631D0B8F0DDCF1F2005A1D7E /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 631D0B900DDCF1F2005A1D7E /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 635355FD0F72F83A00069877 /* DemoView.xib */ = { + isa = PBXVariantGroup; + children = ( + 635355FE0F72F83A00069877 /* en */, + ); + name = DemoView.xib; + sourceTree = ""; + }; + 63C2117510F403A50032417F /* DashView.xib */ = { + isa = PBXVariantGroup; + children = ( + 63C2117610F403A50032417F /* en */, + ); + name = DashView.xib; + sourceTree = ""; + }; + 63CADEBA10F1552A00CE551A /* PolyView.xib */ = { + isa = PBXVariantGroup; + children = ( + 63CADEBB10F1552A00CE551A /* en */, + ); + name = PolyView.xib; + sourceTree = ""; + }; + 63CADF7B10F15AB700CE551A /* GradientView.xib */ = { + isa = PBXVariantGroup; + children = ( + 63CADF7C10F15AB700CE551A /* en */, + ); + name = GradientView.xib; + sourceTree = ""; + }; + 63CADFF610F1635200CE551A /* LineView.xib */ = { + isa = PBXVariantGroup; + children = ( + 63CADFF710F1635200CE551A /* en */, + ); + name = LineView.xib; + sourceTree = ""; + }; + 63F0AB750F8C236D00568150 /* BlendView.xib */ = { + isa = PBXVariantGroup; + children = ( + 63F0AB760F8C236D00568150 /* en */, + ); + name = BlendView.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = Info.plist; + ONLY_ACTIVE_ARCH = NO; + PREBINDING = NO; + PRODUCT_NAME = QuartzDemo; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = QuartzDemo; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "QuartzDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "QuartzDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/QuartzDemo/ReadMe.txt b/QuartzDemo/ReadMe.txt new file mode 100644 index 0000000..6f13322 --- /dev/null +++ b/QuartzDemo/ReadMe.txt @@ -0,0 +1,80 @@ +QuartzDemo + +QuartzDemo is an iPhone OS application that demonstrates many of the Quartz2D APIs made available by the CoreGraphics framework. Quartz2D forms the foundation of all drawing on iPhone OS and provides facilities for drawing lines, polygons, curves, images, gradients, PDF and many other graphical facilities. + +In this sample stroked paths are typically drawn in white. Lines and other graphical elements drawn in red are meant to show some aspect of how the element was constructed, such as the path used to construct the object, or a clipping rectangle used to limit drawing to a particular area and are not part of the actual demonstrated result. Filled paths and areas use colors other than red, with a red fill used to similar effect as with stroked paths. + +Build Requirements + +iOS 4.0 SDK + +Runtime Requirements + +iPhone OS 3.2 or later + +Source File List + +Classes/AppDelegate.h/m: +The application delegate. It creates and configures the view & navigation controllers for the application. + +Classes/MainViewController.h/m: +Implements the main interface to the demo application, allowing the user to display which of Quartz's drawing facilities to demonstrate. + +Classes/QuartzView.h/m: +A UIView subclass that is the super class of the other demonstration views in this sample. + +Classes/QuartzViewController.h/m: +A UIViewController subclass that manages a single QuartzView and allows the user to zoom and pan around the hosted QuartzView. + +Classes/QuartzBlendingViewController.h/m: +A QuartzViewController subclass that manages a QuartzBlendingView and a UI to allow for the selection of foreground color, background color and blending mode to demonstrate. + +Classes/QuartzPolyViewController.h/m: +A QuartzViewController subclass that manages a QuartzPolygonView and a UI to allow for the selection of the stroke and fill mode to demonstrate. + +Classes/QuartzGradientController.h/m: +A QuartzViewController subclass that manages a QuartzGradientView and a UI to allow for the selection of gradient type and if the gradient extends past its start or end point. + +Classes/QuartzLineViewController.h/m: +A QuartzViewController subclass that manages a QuartzCapJoinWidthView and a UI to allow for the selection of the line cap, line join and line width to demonstrate. + +Classes/QuartzDashViewController.h/m: +A QuartzViewController subclass that manages a QuartzDashView and a UI to allow for the selection of the line dash pattern and phase. + +Quartz/QuartzLines.h/m: +Demonstrates Quartz line drawing facilities (QuartzLineView), including dash patterns (QuartzDashView), stroke width, line cap and line join (QuartzCapJoinWidthView). + +Quartz/QuartzPolygons.h/m: +Demonstrates using Quartz to stroke & fill rectangles (QuartzRectView) and polygons (QuartzPolygonView). + +Quartz/QuartzCurves.h/m: +Demonstrates using Quartz to draw ellipses & arcs (QuartzEllipseArcView) and bezier & quadratic curves (QuartzBezierView). + +Quartz/QuartzImages.h/m: +Demonstrates using Quartz for drawing images (QuartzImageView), PDF files (QuartzPDFView), and text (QuartzTextView). + +Quartz/QuartzRendering.h/.m: +Demonstrates using Quartz for drawing gradients (QuartzGradientView) and patterns (QuartzPatternView). + +Quartz/QuartzBlending.h/.m: +Demonstrates Quartz Blend modes (QuartzBlendingView). + +Quartz/QuartzClipping.h/m: +Demonstrates using Quartz for clipping (QuartzClippingView) and masking (QuartzMaskingView). + +main.m: +The application's main entry point. + +Changes From Previous Versions + +2.5: Changed deployment target back to iPhone OS 3.2 and added CFBundleIconFiles in Info.plist. +2.4: Upgraded project to build with the iOS 4.0 SDK. +2.3: Added masking and clipping demos in QuartzClipping.h/m. Made some of the demos dynamic. Reorganized some of the class names. +2.2: Changed the demo classes to be subclasses of the QuartzView class. Improved QuartzViewController to allow the user to zoom and pan the demo views, and to improve its low memory handling. Added a Blending demo. +2.1: Fixed a memory management error in the MainViewController. +2.0: First public release. +1.3: Now uses nibs. Moved gradient drawing into QuartzRendering.h/m and added a pattern drawing demo. +1.2: Updated for Beta 5 for changes to UITableViewDelegate. +1.1: Updated for Beta 4 for changes to UINavigationBarController and UINavigationBar. + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/QuartzDemo/Resources/Demo.png b/QuartzDemo/Resources/Demo.png new file mode 100644 index 0000000..6af4203 Binary files /dev/null and b/QuartzDemo/Resources/Demo.png differ diff --git a/QuartzDemo/Resources/Ship.png b/QuartzDemo/Resources/Ship.png new file mode 100755 index 0000000..4ad0bd4 Binary files /dev/null and b/QuartzDemo/Resources/Ship.png differ diff --git a/QuartzDemo/Resources/en.lproj/BlendView.xib b/QuartzDemo/Resources/en.lproj/BlendView.xib new file mode 100644 index 0000000..1582070 --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/BlendView.xib @@ -0,0 +1,445 @@ + + + + 768 + 10A432 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 236} + + + 3 + MAA + + YES + YES + NO + 4 + NO + + + + 264 + {{0, 244}, {320, 216}} + + + YES + YES + + + {320, 460} + + + + + + + + YES + + + dataSource + + + + 6 + + + + delegate + + + + 7 + + + + scrollView + + + + 8 + + + + view + + + + 9 + + + + picker + + + + 10 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + 3 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 3.IBPluginDependency + 4.IBPluginDependency + + + YES + QuartzBlendingViewController + UIResponder + {{340, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 13 + + + + YES + + QuartzBlendingViewController + QuartzViewController + + picker + UIPickerView + + + IBProjectSource + Classes/QuartzBlendingViewController.h + + + + QuartzViewController + UIViewController + + scrollView + UIScrollView + + + IBProjectSource + Classes/QuartzViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIPickerView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIPickerView.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.0 + + diff --git a/QuartzDemo/Resources/en.lproj/DashView.xib b/QuartzDemo/Resources/en.lproj/DashView.xib new file mode 100644 index 0000000..066702a --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/DashView.xib @@ -0,0 +1,618 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 206} + + + 3 + MAA + + YES + YES + NO + 4 + NO + + + + 267 + {{78, 214}, {193, 23}} + + NO + YES + YES + 0 + 0 + -20 + 20 + + + + 268 + {{20, 214}, {53, 21}} + + NO + YES + NO + Phase: + + 1 + MSAxIDEAA + + 1 + + + + 1 + 10 + + + + 264 + {{0, 244}, {320, 216}} + + NO + YES + YES + YES + + + + 265 + {{277, 212}, {23, 23}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + 0 + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA + + + 3 + MC41AA + + + + {320, 460} + + + 3 + MAA + + 2 + + + + + + + + YES + + + scrollView + + + + 8 + + + + view + + + + 9 + + + + picker + + + + 28 + + + + dataSource + + + + 30 + + + + delegate + + + + 31 + + + + phase + + + + 33 + + + + reset + + + 7 + + 34 + + + + dashPhase + + + 13 + + 35 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + 14 + + + + + 20 + + + + + 27 + + + + + 32 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 14.IBPluginDependency + 20.IBPluginDependency + 27.IBPluginDependency + 32.IBPluginDependency + 4.IBPluginDependency + + + YES + QuartzDashViewController + UIResponder + {{340, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 35 + + + + YES + + QuartzDashViewController + QuartzViewController + + YES + + YES + dashPhase + reset + + + YES + id + id + + + + YES + + YES + phase + picker + + + YES + UISlider + UIPickerView + + + + IBProjectSource + Classes/QuartzDashViewController.h + + + + QuartzViewController + UIViewController + + scrollView + UIScrollView + + + IBProjectSource + Classes/QuartzViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIPickerView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIPickerView.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISlider + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISlider.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.1 + + diff --git a/QuartzDemo/Resources/en.lproj/DemoView.xib b/QuartzDemo/Resources/en.lproj/DemoView.xib new file mode 100644 index 0000000..9b08b93 --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/DemoView.xib @@ -0,0 +1,390 @@ + + + + 528 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 480} + + YES + YES + 4 + NO + + + {320, 480} + + + 3 + MAA + + + + + + YES + + + view + + + + 3 + + + + scrollView + + + + 5 + + + + delegate + + + + 6 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + + + YES + QuartzViewController + UIResponder + {{224, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 8 + + + + YES + + QuartzViewController + UIViewController + + redraw + id + + + scrollView + UIScrollView + + + IBProjectSource + Classes/QuartzViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.1 + + diff --git a/QuartzDemo/Resources/en.lproj/GradientView.xib b/QuartzDemo/Resources/en.lproj/GradientView.xib new file mode 100644 index 0000000..ffb3168 --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/GradientView.xib @@ -0,0 +1,628 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 319} + + + 3 + MAA + + YES + YES + NO + 4 + NO + + + + 265 + {{148, 327}, {139, 44}} + + NO + NO + 1 + 2 + 0 + + YES + Linear + Radial + + + YES + + + + + YES + + + + + YES + {0, 0} + {0, 0} + + + YES + + + + + + + 265 + {{148, 378}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 265 + {{148, 413}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 268 + {{97, 338}, {43, 21}} + + NO + YES + NO + Type: + + 1 + MSAxIDEAA + + 1 + + + + 1 + 10 + + + + 268 + {{32, 381}, {108, 21}} + + NO + YES + NO + Extends Start: + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + 268 + {{38, 416}, {102, 21}} + + NO + YES + NO + Extends End: + + 1 + MSAxIDEAA + + + + 1 + 10 + + + {320, 460} + + + + + + + + YES + + + scrollView + + + + 8 + + + + view + + + + 9 + + + + gradientType: + + + 13 + + 20 + + + + extendsPastStart: + + + 13 + + 21 + + + + extendsPastEnd: + + + 13 + + 22 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + 14 + + + + + 15 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + 19 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 19.IBPluginDependency + 4.IBPluginDependency + + + YES + QuartzGradientViewController + UIResponder + {{154, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 22 + + + + YES + + QuartzGradientViewController + QuartzViewController + + YES + + YES + extendsPastEnd: + extendsPastStart: + gradientType: + + + YES + id + id + id + + + + IBProjectSource + Classes/QuartzGradientViewController.h + + + + QuartzViewController + UIViewController + + scrollView + UIScrollView + + + IBProjectSource + Classes/QuartzViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISegmentedControl + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISegmentedControl.h + + + + UISwitch + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISwitch.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.1 + + diff --git a/QuartzDemo/Resources/en.lproj/LineView.xib b/QuartzDemo/Resources/en.lproj/LineView.xib new file mode 100644 index 0000000..1bdc037 --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/LineView.xib @@ -0,0 +1,666 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 308} + + + 3 + MAA + + YES + YES + NO + 4 + NO + + + + 267 + {{71, 418}, {230, 23}} + + NO + YES + YES + 0 + 0 + 20 + 1 + 20 + + + + 267 + {{70, 316}, {230, 44}} + + NO + NO + 1 + 3 + 0 + + YES + Butt + Round + Square + + + YES + + + + + + YES + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + 267 + {{70, 367}, {230, 44}} + + NO + NO + 1 + 3 + 0 + + YES + Miter + Round + Bevel + + + YES + + + + + + YES + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + 268 + {{25, 327}, {36, 21}} + + NO + YES + NO + Cap: + + 1 + MSAxIDEAA + + 1 + + + + 1 + 10 + + + + 268 + {{26, 378}, {36, 21}} + + NO + YES + NO + Join: + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + 268 + {{13, 418}, {49, 21}} + + NO + YES + NO + Width: + + 1 + MSAxIDEAA + + + + 1 + 10 + + + {320, 460} + + + + + + + + YES + + + scrollView + + + + 8 + + + + view + + + + 9 + + + + lineCap: + + + 13 + + 24 + + + + lineJoin: + + + 13 + + 25 + + + + lineWidth: + + + 13 + + 26 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + 14 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + 19 + + + + + 20 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 14.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 19.IBPluginDependency + 20.IBPluginDependency + 4.IBPluginDependency + + + YES + QuartzLineViewController + UIResponder + {{340, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 26 + + + + YES + + QuartzLineViewController + QuartzViewController + + YES + + YES + lineCap: + lineJoin: + lineWidth: + + + YES + id + id + id + + + + IBProjectSource + Classes/QuartzLineViewController.h + + + + QuartzViewController + UIViewController + + scrollView + UIScrollView + + + IBProjectSource + Classes/QuartzViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISegmentedControl + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISegmentedControl.h + + + + UISlider + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISlider.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.1 + + diff --git a/QuartzDemo/Resources/en.lproj/MainWindow.xib b/QuartzDemo/Resources/en.lproj/MainWindow.xib new file mode 100644 index 0000000..5a4192c --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/MainWindow.xib @@ -0,0 +1,577 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + + + 3 + MAA + + 2 + + + NO + NO + YES + + + + + NO + + + + + 256 + {{0, -44}, {0, 44}} + NO + YES + YES + + + YES + + QuartzDemo + + + 274 + {320, 416} + + + + 3 + MQA + + NO + YES + NO + 1 + 0 + YES + 44 + 22 + 22 + + + QuartzDemo + + + + + + + + + + YES + + + window + + + + 15 + + + + navigationController + + + + 16 + + + + delegate + + + + 17 + + + + dataSource + + + + 31 + + + + delegate + + + + 32 + + + + + YES + + 0 + + + + + + 2 + + + + + -1 + + + File's Owner + + + -2 + + + + + 3 + + + YES + + + + + + + 5 + + + + + 14 + + + AppDelegate + + + 24 + + + YES + + + + + + + 25 + + + + + 28 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 14.CustomClassName + 14.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 24.CustomClassName + 24.IBPluginDependency + 25.IBPluginDependency + 3.IBEditorWindowLastContentRect + 3.IBPluginDependency + 5.IBPluginDependency + + + YES + UIApplication + UIResponder + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{574, 271}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + MainViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{537, 460}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 32 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + MainViewController + UITableViewController + + IBProjectSource + Classes/MainViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.1 + + diff --git a/QuartzDemo/Resources/en.lproj/PolyView.xib b/QuartzDemo/Resources/en.lproj/PolyView.xib new file mode 100644 index 0000000..27164f3 --- /dev/null +++ b/QuartzDemo/Resources/en.lproj/PolyView.xib @@ -0,0 +1,445 @@ + + + + 768 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 236} + + + 3 + MAA + + YES + YES + NO + 4 + NO + + + + 264 + {{0, 244}, {320, 216}} + + + YES + YES + + + {320, 460} + + + + + + + + YES + + + dataSource + + + + 6 + + + + delegate + + + + 7 + + + + scrollView + + + + 8 + + + + view + + + + 9 + + + + picker + + + + 10 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + 3 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 3.IBPluginDependency + 4.IBPluginDependency + + + YES + QuartzPolyViewController + UIResponder + {{340, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 13 + + + + YES + + QuartzPolyViewController + QuartzViewController + + picker + UIPickerView + + + IBProjectSource + Classes/QuartzPolyViewController.h + + + + QuartzViewController + UIViewController + + scrollView + UIScrollView + + + IBProjectSource + Classes/QuartzViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIPickerView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIPickerView.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../../QuartzDemo.xcodeproj + 3 + 3.1 + + diff --git a/QuartzDemo/Resources/en.lproj/Quartz.pdf b/QuartzDemo/Resources/en.lproj/Quartz.pdf new file mode 100644 index 0000000..9e279aa Binary files /dev/null and b/QuartzDemo/Resources/en.lproj/Quartz.pdf differ diff --git a/QuartzDemo/images/Icon-72.png b/QuartzDemo/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/QuartzDemo/images/Icon-72.png differ diff --git a/QuartzDemo/images/Icon-Small-50.png b/QuartzDemo/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/QuartzDemo/images/Icon-Small-50.png differ diff --git a/QuartzDemo/images/Icon-Small.png b/QuartzDemo/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/QuartzDemo/images/Icon-Small.png differ diff --git a/QuartzDemo/images/Icon-Small@2x.png b/QuartzDemo/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/QuartzDemo/images/Icon-Small@2x.png differ diff --git a/QuartzDemo/images/Icon.png b/QuartzDemo/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/QuartzDemo/images/Icon.png differ diff --git a/QuartzDemo/images/Icon@2x.png b/QuartzDemo/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/QuartzDemo/images/Icon@2x.png differ diff --git a/QuartzDemo/images/iTunesArtwork b/QuartzDemo/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/QuartzDemo/images/iTunesArtwork differ diff --git a/QuartzDemo/main.m b/QuartzDemo/main.m new file mode 100755 index 0000000..05c9a0c --- /dev/null +++ b/QuartzDemo/main.m @@ -0,0 +1,56 @@ +/* + File: main.m +Abstract: The application's main entry point + Version: 2.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/README.md b/README.md index 1a5326f..699b8d1 100644 --- a/README.md +++ b/README.md @@ -423,13 +423,15 @@ Last Revision: Version 1.2, 2012-01-19 #iAdSuite# -iAdSuite is a set of five samples demonstrating how to manage an ADBannerView in 4 common scenarios: An application with a single view controller (BasicBanner, ContainerBanner), an application that uses a UITabBarViewController (TabbedBanner), an application that uses a UINavigationViewController (NavigationBanner) and an application that uses a UISplitViewController (SplitViewBanner). +iAdSuite is a set of samples demonstrating how to manage an ADBannerView in many common scenarios, each scenario demonstrated in a particular sample application. -All of the samples use a simple view controller that display a read-only UITextView (managed by the TextViewController class) along with a label that shows a running timer. The ADBannerView is placed at the bottom of the view in all cases, and all orientations are supported by each sample. The BasicBanner and ContainerBanner are configured to support both iPhone and iPad idioms, the TabbedBanner and NavigationBanner to support only the iPhone idiom, and the SplitViewBanner to support only the iPad idiom. +In many of the samples the content is represented by a simple TextViewController view controller that displays some text in a read-only UITextView and runs a timer. The UITextView represents your application's content and the timer represents ongoing activity in your application that you will want to pause when the advertisement takes over the user interface. The MediumRectBanner sample uses a UICollectionView with image content instead, adding the banners as additional cells. + +The traditional banner (represented with the ADAdTypeBanner constant) is expected to be placed at or near the bottom of the screen and placed to consume the full width of the screen. New in iOS 6 is the Medium Rect sized banner (represented with the ADAdTypeMediumRectangle constant) which is intended to be placed inline with other content from your application. It is highly recommended that you create only a single instance of each type of banner that you use (so if you use both a banner and medium rect type, you would have at most 1 instance of each) and that you share these instances among the places in your UI that they are used. [URL](https://developer.apple.com/library/ios/#samplecode/iAdSuite/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010198) -Last Revision: Version 2.0, 2011-10-31 +Last Revision: Version 2.1, 2012-10-22 #SimpleStocks# @@ -884,4 +886,617 @@ This sample demonstrates various advanced networking techniques with NSURLConnec [URL](https://developer.apple.com/library/ios/#samplecode/AdvancedURLConnections/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009558) -Last Revision: Version 1.2, 2011-01-26 \ No newline at end of file +Last Revision: Version 1.2, 2011-01-26 + +#AdvancedTableViewCells# + +AdvancedTableViewCells includes three different cells that all display content in the same form as the App Store application. One uses individual subviews (image views, labels, etc.) to display the content. Another uses a single view that draws all of the content. A third uses a single view to draw most of the content and separate views for the remainder. + +[URL](https://developer.apple.com/library/ios/#samplecode/AdvancedTableViewCells/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009111) + +Last Revision: Version 1.5, 2011-01-11 + +#MoveMe# + +This application illustrates simple drawing, touch handling, and animation using UIKit and Core Animation. + +A touch inside a placard animates it in two ways: Its transform is changed such that it appears to pulse, and it is moved such that its center is directly under the touch. + +A drag moves the placard so that it remains centered under the touch. When the touch ends, the placard is animated back to the center of the screen, and its original (identity) transform restored. + +[URL](https://developer.apple.com/library/ios/#samplecode/MoveMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007315) + +Last Revision: Version 2.10, 2010-12-23 + +#MessageComposer# + +This application shows how to target older OS versions while building with newly released APIs. It also illustrates how to use the MessageUI framework to compose and send email and SMS messages from within your application. + +[URL](https://developer.apple.com/library/ios/#samplecode/MessageComposer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010161) + +Last Revision: Version 1.1, 2010-11-08 + +#Icons# + +This sample demonstrates the proper use of application icons on iOS. This is a universal binary that supports iPhone/iPod touch/iPad and includes support for high resolution displays. + +Each icon has one dimension of the pixel dimensions on it to display which icon is being used by various areas of iOS. The various icons display when using the Homescreen, Spotlight, the Settings app, different devices, and when creating an Ad Hoc build and adding it to iTunes. + +[URL](https://developer.apple.com/library/ios/#samplecode/Icons/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010442) + +Last Revision: Version 1.0, 2010-10-22 + +#WiTap# + +The WiTap sample application demonstrates how to achieve network communication between applications. Using Bonjour, the application both advertises itself on the local network and displays a list of other instances of this application on the network. + +[URL](https://developer.apple.com/library/ios/#samplecode/WiTap/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007321) + +Last Revision: Version 1.8, 2010-10-22 + +#MVCNetworking# + +MVCNetworking is a sample that shows how to create a network application using the Model-View-Controller design pattern. Specifically, it displays a photo gallery by getting the gallery's XML description, thumbnails and photos from a web server, and uses Core Data to cache this information locally. + +[URL](https://developer.apple.com/library/ios/#samplecode/MVCNetworking/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010443-Intro-DontLinkElementID_2) + +Last Revision: Version 1.0, 2010-10-22 + +#GKTapper# + +GKTapper is a sample application that shows how to support GameCenter Leaderboards and Achievements. It also demonstrates using GKLeaderboardViewController and GKAchievementViewController to display this data. + +[URL](https://developer.apple.com/library/ios/#samplecode/GKTapper/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010283) + +Last Revision: Version 1.1, 2010-12-10 + +#iPhoneACFileConvertTest# + +Demonstrates using the Audio Converter APIs to convert from a PCM audio format to a compressed format. + +Four encoding formats may be chosen in the UI along with different sample rates for the produced output.caf file. AAC encoding using Audio Converter requires 4.1 or later and a hardware capable device such as the iPhone 3GS. If run on a device which does not support hardware assisted AAC encoding, the AAC encoding choice will be dimmed. + +Interruption handling during processing is also demonstrated. Hardware assisted encoding requires specific interruption handling since the codec state may change due to the interruption. + +All the relevant audio specific code is in the file AudioConverterFileConvert.cpp. + +Also see the companion to this sample - iPhoneExtAudioFileConvertTest. + +[URL](https://developer.apple.com/library/ios/#samplecode/iPhoneACFileConvertTest/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010581) + +Last Revision: Version 1.0, 2010-12-10 + +#Popovers# + +This sample demonstrates proper use of UIPopoverController in iOS. UIPopoverController presentation, dismissing, and rotation handling are covered. The sample is provided using a UISplitViewController in order to show proper handling of UIPopoverControllers being presented from UIBarButtonItems. Additional handling ensures that multiple UIPopoverControllers are never presented at the same time. + +[URL](https://developer.apple.com/library/ios/#samplecode/Popovers/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010436) + +Last Revision: Version 1.0, 2010-10-20 + +#aurioTouch# + +aurioTouch demonstrates use of the remote i/o audio unit for handling audio input and output. The application can display the input audio in one of the forms, a regular time domain waveform, a frequency domain waveform (computed by performing a fast fourier transform on the incoming signal), and a sonogram view (a view displaying the frequency content of a signal over time, with the color signaling relative power, the y axis being frequency and the x as time). + +The code in auriouTouch uses the remote i/o audio unit (AURemoteIO) for input and output of audio, and OpenGL for display of the input waveform. The application also uses Audio Session Services to manage route changes (as described in Core Audio Overview). + +[URL](https://developer.apple.com/library/ios/#samplecode/aurioTouch/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007770) + +Last Revision: Version 1.21, 2010-10-20 + +#PageControl# + +This application primarily demonstrates use of UIScrollView's paging functionality to use horizontal scrolling as a mechanism for navigating between different pages of content. With the iPad, this type of user interface is not really necessary since the screen is larger allowing for more content and detailed information. + +Designed as a universal application for both iPhone and iPad, this sample shows how to use two different sets of content, depending on which device the sample is running. The idea is that the iPhone uses a "smaller" set of images, while the iPad uses a "larger" set of images plus more detailed information. As a universal app this sample shows how to factor out these two types of UI and data based on the device. + +For the iPhone - The app uses UIScrollView and UIPageControl to move between pages. For the iPad - The app uses one large UIView with tiled pages, each page presenting a popover to display more detailed information. + +Based on the UIDevice idiom type, the UIApplication delegate loads two different set of nib files, one for the iPhone and the other for the iPad. To direct this kind of UI factoring, the sample uses a base class called "ContentController". Subclasses of ContentController are used to support each device. Hence, the app loads two different user interfaces (or xibs) as well as two different sets of data driven by the ContentController. + +[URL](https://developer.apple.com/library/ios/#samplecode/PageControl/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007795) + +Last Revision: Version 1.4, 2010-10-18 + +#ListAdder# + +This sample demonstrates the technique of thread confinement using NSOperation. It was written to support TN2109 "Simple and Reliable Threading with NSOperation". + +[URL](https://developer.apple.com/library/ios/#samplecode/ListAdder/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010275) + +Last Revision: Version 1.0, 2010-08-27 + +#BatteryStatus# + +Demonstrates the use of the battery status properties and notifications provided via the iOS SDK. + +[URL](https://developer.apple.com/library/ios/#samplecode/BatteryStatus/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008812) + +Last Revision: Version 1.1, 2010-07-22 + +#Reachability# + +The Reachability sample application demonstrates how to use the SystemConfiguration framework to monitor the network state of an iPhone or iPod touch. In particular, it demonstrates how to know when IP can be routed and when traffic will be routed through a Wireless Wide Area Network (WWAN) interface such as EDGE or 3G. + +[URL](https://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324) + +Last Revision: Version 2.2, 2010-07-20 + +#GLImageProcessing# + +The GLImageProcessing sample application demonstrates how to implement simple image processing filters (Brightness, Contrast, Saturation, Hue rotation, Sharpness) using OpenGL ES1.1. The sample also shows how to create simple procedural button icons using CoreGraphics. + +By looking at the code you'll see how to set up an OpenGL ES view and use it for applying a filter to a texture. The application creates a texture from an image loaded from disk. It pads the image to a power of two, if required by the GPU. + +The Debug configuration in the Xcode project defines DEBUG and ASSERT preprocessor macros, to enable additional error checking. + +To use this sample, open it in Xcode and click Build and Go. Use the slider to control the current filter. Only a single filter is applied at a time. + +[URL](https://developer.apple.com/library/ios/#samplecode/GLImageProcessing/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009053) + +Last Revision: Version 1.2, 2010-06-29 + +#TouchCells# + +Demonstrates how to implement trackable-settable UIControls embedded in a UITableView. This approach is handy if an application already uses its accessory view to the right of the table cell, but still wants a check mark view that supports toggling states of individual row items. The green check mark on the left provides this need which is trackable (checked/unchecked) independent of table selection. This is a similar user interface to that of Mail's Inbox table where mail items can be individually checked and unchecked for deletion. + +[URL](https://developer.apple.com/library/ios/#samplecode/TouchCells/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008062) + +Last Revision: Version 1.4, 2010-06-29 + +#HazardMap# + +Demonstrates how to create a custom Map Kit overlay to display USGS earthquake hazard data. It shows how to create a custom Map Kit overlay and corresponding view to display USGS earthquake hazard data on top of an MKMapView. + +For more information on earthquake hazard data, see "http://earthquake.usgs.gov/hazards/products/conterminous/2008/data/". + +[URL](https://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010049) + +Last Revision: Version 1.1, 2010-08-24 + +#SeismicXML# + +The SeismicXML sample application demonstrates how to use NSXMLParser to parse XML data. When you launch the application it downloads and parses an RSS feed from the United States Geological Survey (USGS) that provides data on recent earthquakes around the world. It displays the location, date, and magnitude of each earthquake, along with a color-coded graphic that indicates the severity of the earthquake. The XML parsing occurs on a background thread using NSOperation and updates the earthquakes table view with batches of parsed objects. + +[URL](https://developer.apple.com/library/ios/#samplecode/SeismicXML/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007323) + +Last Revision: Version 2.3, 2010-08-18 + +#AppPrefs# + +Demonstrates how to display your app's preferences or settings in the "Settings" system application. A settings bundle, included in your application’s bundle directory, contains the information needed by the Settings application to display your preferences and make it possible for the user to modify them. It then saves any configured values in the defaults database so that your application can retrieve them at runtime. + +This sample also shows how to dynamically update it's UI when its settings are changed while the app is in the background via "NSUserDefaultsDidChangeNotification". + +This sample offers an Xcode project already pre-configured to build your Settings bundle as a target. To customize your settings UI, change the Root.plist file. + +[URL](https://developer.apple.com/library/ios/#samplecode/AppPrefs/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007799) + +Last Revision: Version 1.5, 2010-06-29 + +#GLSprite# + +The GLSprite sample application shows how to create a texture from an image. By looking at the code, you'll learn how to use Core Graphics to create a bitmap context and draw an image into the context. You'll then see how to use OpenGL ES to create a texture from the image data. + +[URL](https://developer.apple.com/library/ios/#samplecode/GLSprite/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007325) + +Last Revision: Version 1.9, 2010-08-18 + +#GLPaint# + +The GLPaint sample application demonstrates how to support single finger painting using OpenGL ES. This sample also shows how to detect a "shake" motion of the device. By looking at the code you'll see how to set up an OpenGL ES view and use it for rendering painting strokes. The application creates a brush texture from an image by first drawing the image into a Core Graphics bitmap context. It then uses the bitmap data for the texture. The image used for a texture must have dimensions that are a power of 2. + +[URL](https://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007328) + +Last Revision: Version 1.11, 2010-08-04 + +#Audio Mixer (MixerHost)# + +MixerHost demonstrates how to use the Multichannel Mixer audio unit in an iOS application. It also demonstrates how to use a render callback function to provide audio to an audio unit input bus. In this sample, the audio delivered by the callback comes from two short loops read from disk. You could use a similar callback, however, to synthesize sounds to feed into a mixer unit. This sample is described in Audio Unit Hosting Guide for iOS. + +[URL](https://developer.apple.com/library/ios/#samplecode/MixerHost/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010210) + +Last Revision: Version 1.0, 2010-07-27 + +#Audio UI Sounds (SysSound)# + +Demonstrates use of System Sound Services (AudioToolbox/AudioServices.h) to play alerts and user-interface sound effects, and to invoke vibration. + +[URL](https://developer.apple.com/library/ios/#samplecode/SysSound/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008018) + +Last Revision: Version 1.1, 2010-07-27 + +#EADemo# + +The sample can be used with any Made For iPod (MFI) device designed for use with the External Accessory Framework. The application will display an External Accessory attached device in the Accessories window, provide information registered by the MFI device, and provides methods to send and receive data to the device. + +[URL](https://developer.apple.com/library/ios/#samplecode/EADemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010079) + +Last Revision: Version 1.1, 2010-07-26 + +#iPhoneExtAudioFileConvertTest# + +Demonstrates using ExtAudioFile API to convert from one audio format and file type to another. + +Four encoding formats may be chosen in the UI along with different sample rates for the produced output.caf file. AAC encoding requires both iPhone OS 3.1 and a hardware capable device such as the iPhone 3GS. If run on a device which does not support hardware assisted AAC encoding, the AAC encoding choice will be dimmed. + +Interruption handling during processing is also demonstrated. Hardware assisted encoding requires specific interruption handling since the codec state may change due to the interruption. + +All the relevant audio specific code is in the file ExtAudioFileConvert.cpp. + +[URL](https://developer.apple.com/library/ios/#samplecode/iPhoneExtAudioFileConvertTest/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009222) + +Last Revision: Version 1.1, 2010-07-22 + +#GenericKeychain# + +This sample shows how to add, query for, remove, and update a keychain item of generic class type. Also demonstrates the use of shared keychain items. All classes exhibit very similar behavior so the included examples will scale to the other classes of Keychain Item: Internet Password, Certificate, Key, and Identity. + +[URL](https://developer.apple.com/library/ios/#samplecode/GenericKeychain/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007797) + +Last Revision: Version 1.2, 2010-07-22 + +#LocateMe# + +This demonstrates the two primary use cases for the Core Location Framework: getting the user's location and tracking changes to the user's location. + +[URL](https://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801) + +Last Revision: Version 2.2, 2010-07-09 + +#XMLPerformance# + +This sample explores two approaches to parsing XML, focusing on performance with respect to speed, memory footprint, and user experience. The XML data used is the current "Top 300" songs from the iTunes store. The data itself is not particularly important to the sample - it was chosen because of its simplicity, availability, and because the size (approximately 850KB) is sufficient to demonstrate the performance issues central to the sample. + +[URL](https://developer.apple.com/library/ios/#samplecode/XMLPerformance/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008094) + +Last Revision: Version 1.3, 2010-07-08 + +#iPhoneMultichannelMixerTest# + +Demonstrates how to build an Audio Unit Graph connecting a Multichannel Mixer instance to the RemoteIO unit. Two input busses are created each with input volume controls. An overall mixer output volume control is also provided and each bus may be enabled or disabled. + +[URL](https://developer.apple.com/library/ios/#samplecode/iPhoneMultichannelMixerTest/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009113) + +Last Revision: Version 1.1, 2010-07-07 + +#GLES2Sample# + +PowerVR SGX platforms support both OpenGL ES 1.1 and 2.0. This sample demonstrates how to create an OpenGL ES 1.1 and 2.0 compatible project. When running on PowerVR MBX platforms (e.g.,1st and 2nd generation iPod touch, 1st generation iPhone, iPhone 3G), the sample draws using OpenGL ES 1.1; when running on PowerVR SGX platforms (e.g., iPhone 3GS and 3rd generation iPod touch), the sample draws using OpenGL ES 2.0. + +[URL](https://developer.apple.com/library/ios/#samplecode/GLES2Sample/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009188) + +Last Revision: Version 1.1, 2010-07-07 + +#GLGravity# + +The GLGravity sample application demonstrates how to use the UIAccelerometer class in combination with OpenGL rendering. It shows how to extract the gravity vector from the accelerometer values using a basic low-pass filter, and how to build an OpenGL transformation matrix from it. + +[URL](https://developer.apple.com/library/ios/#samplecode/GLGravity/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007327) + +Last Revision: Version 2.2, 2010-07-06 + +#WeatherMap# + +Demonstrates the use of the MapKit framework, displaying a map view with custom MKAnnotationViews. + +An annotation object on a map is any object that conforms to the MKAnnotation protocol and is displayed on the screen as a MKAnnotationView. Through the use of the MKAnnotation protocol and MKAnnotationView, this application identifies four major cities in North America with fictitious weather information. + +[URL](https://developer.apple.com/library/ios/#samplecode/WeatherMap/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009491) + +Last Revision: Version 1.1, 2010-07-01 + +#Formulaic# + +Formulaic is a sample iPhone app that illustrates how to effectively use the iPhone Accessibility API. Using the Accessibility API allows your app to work correctly with VoiceOver. + +The app draws a graph of a formula and allows the user to change certain constants in the formula, however its main purpose is to illustrate the iPhone Accessibility API. + +[URL](https://developer.apple.com/library/ios/#samplecode/Formulaic/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008932) + +Last Revision: Version 1.2, 2010-07-01 + +#TaggedLocations# + +This sample illustrates how to manipulate attributes and relationships in an iPhone application. + +The application extends the the completed project from the Core Data Tutorial for iPhone OS. The first screen displays a table view of events, which encapsulate a time stamp, a geographical location expressed in latitude and longitude, and a name for the event. The user can add, remove, and edit events using the first screen. + +Events have a to-many relationship to tags (which have an inverse to-many relationship to events). Tags have a name which describes a feature of an event. Tags are displayed in a second table view; when a tag is related to the selected event, a check mark is displayed in the corresponding row. + +[URL](https://developer.apple.com/library/ios/#samplecode/TaggedLocations/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008914) + +Last Revision: Version 1.3, 2010-06-29 + +#HeaderFooter# + +Demonstrates how to implement and customize the 2 UIView properties of UITableView: header ('tableHeaderView') and footer ('tableFooterView'). It is designed to somewhat resemble the "Contacts" application, showing you ways to design your own header and footer content. It uses the UITableViewStyle: UITableViewStyleGrouped to achieve a more similar appearance as well. + +[URL](https://developer.apple.com/library/ios/#samplecode/HeaderFooter/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007989) + +Last Revision: Version 1.3, 2010-06-29 + +#oalTouch# + +The code uses OpenAL to play a single audio source. Move source or listener position by dragging icons around on the grid. Turn accelerometer functionality on to set listener orientation by tilting the device. + +[URL](https://developer.apple.com/library/ios/#samplecode/oalTouch/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007769) + +Last Revision: Version 1.9, 2010-06-29 + +#AQOfflineRenderTest# + +Demonstrates using Audio Queue offline render functionality and the AudioQueueOfflineRender API. The sample produces LPCM output buffers from an ALAC encoded source which are then written to a .caf file. The output.caf file is then played back confirming the offline functionality worked as expected. All the code demonstrating the Audio Queue is in a single file called aqofflinerender.cpp. + +[URL](https://developer.apple.com/library/ios/#samplecode/AQOfflineRenderTest/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008413) + +Last Revision: Version 1.2, 2010-06-28 + +#AccelerometerGraph# + +AccelerometerGraph sample application graphs the motion of the device. It demonstrates how to use the UIAccelerometer class and how to use Quartz2D and Core Animation to provide a high performance graph view. It also demonstrates a low-pass filter that you can use to isolate the effects of gravity, and a high-pass filter that you can use to remove the effects of gravity. + +[URL](https://developer.apple.com/library/ios/#samplecode/AccelerometerGraph/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007410) + +Last Revision: Version 2.5, 2010-06-28 + +#Teslameter# + +This application implements a Teslameter, a magnetic field detector. It displays the raw x, y, and z magnetometer values, a plotted history of those values, and a computed magnitude (size or strength) of the magnetic field. + +The use of the Core Location API for getting "heading" data is contained in the TeslameterViewController class. It creates a CLLocationManager object and uses it to get heading by invoking -[CLLocationManager startUpdatingHeading]. It implements the CLLocationManagerDelegate APIs for receiving heading and updates its user interface accordingly. + +[URL](https://developer.apple.com/library/ios/#samplecode/Teslameter/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008931) + +Last Revision: Version 1.2, 2010-06-28 + +#SimpleEKDemo# + +The application uses table views to display EKCalendar object and EKEvent objects retrieved from an EKEventStore object. It implements EKEventViewController for viewing and editing existing EKEvents, and uses EKEventEditViewController for creating new EKEvents. + +[URL](https://developer.apple.com/library/ios/#samplecode/SimpleEKDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010160) + +Last Revision: Version 1.0, 2010-06-25 + +#SimpleEKDemo# + +The application uses table views to display EKCalendar object and EKEvent objects retrieved from an EKEventStore object. It implements EKEventViewController for viewing and editing existing EKEvents, and uses EKEventEditViewController for creating new EKEvents. + +[URL](https://developer.apple.com/library/ios/#samplecode/SimpleEKDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010160) + +Last Revision: Version 1.0, 2010-06-25 + +#MapCallouts# + +Demonstrates the use of the MapKit framework, displaying a map view with custom MKAnnotations each with custom callouts. An annotation object on a map is any object that conforms to the MKAnnotation protocol and is displayed on the screen as a MKAnnotationView. Through the use of the MKAnnotation protocol and MKAnnotationView, this application shows how you can extend annotations with custom strings and left/right calloutAccessoryViews. + +[URL](https://developer.apple.com/library/ios/#samplecode/MapCallouts/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009746) + +Last Revision: Version 1.2, 2010-06-25 + +#DateSectionTitles# + +This application shows how to create section information for NSFetchedResultsController using dates. + +A single table view controller displays events sorted by date and grouped into sections by year and month. The Event entity has three attributes: + +* timeStamp (persistent NSDate object). + +The time stamp represents the time the event occurred. + +* title (persistent NSString object). + +The title of each event as it will be displayed on a row in the table view (this is not to be confused with section title). When the default data is created in the application delegate, the title is initialized to a string representation of the date. + +* sectionIdentifier (transient NSString object). + +The sectionIdentifier is used to divide the events into sections in the table view. It is a string value representing the number ((year * 1000) + month). Using this value, events can be correctly ordered chronologically regardless of the actual name of the month. It is calculated and cached on demand in the custom accessor method. + +The sorting is all done at fetch time by the fetched results controller. The section name transformations are UI level and have no effect on the order of data. + +[URL](https://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009939) + +Last Revision: Version 1.2, 2010-06-25 + +#WorldCities# + +Demonstrates basic use of MapKit, including displaying a map view and setting its region. + +A list of cities are stored in a plist file loaded at launch time. Each city is represented by a "WorldCity" class which consists of a name, a latitude, and a longitude. The user can select from a pre-defined world cities. When a world cities is selected, the map view animates to a region with the coordinates of the world cities in the center of the view. The user can also choose between map types - Standard, Satellite, and Hybrid - using the segmented control in the toolbar of the main view. + +[URL](https://developer.apple.com/library/ios/#samplecode/WorldCities/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009466) + +Last Revision: Version 1.1, 2010-06-25 + +#QuartzDemo# + +QuartzDemo is an iPhone OS application that demonstrates many of the Quartz2D APIs made available by the CoreGraphics framework. Quartz2D forms the foundation of all drawing on iPhone OS and provides facilities for drawing lines, polygons, curves, images, gradients, PDF and many other graphical facilities. + +[URL](https://developer.apple.com/library/ios/#samplecode/QuartzDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007531) + +Last Revision: Version 2.5, 2010-06-25 + +#iPhoneMixerEQGraphTest# + +iPhoneMixerEQGraphTest demonstrates how to build an Audio Unit Graph connecting a MultiChannel Mixer to the iPodEQ unit then to the RemoteIO unit. + +Two input busses are created each with input volume controls. An overall mixer output volume control is also provided and each bus may be enabled or disabled. The iPodEQ may be enabled or disabled and a preset EQ curve may be chosen via a picker in the iPod Equalizer view. iPhoneMixerEQGraphTest uses 44.1kHz source and sets the hardware sample rate to 44.1kHz to avoid any extraneous sample rate conversions. + +Touching the "Play Audio" button simply calls AUGraphStart while "Stop Audio" calls AUGraphStop. Changing AU volume is performed via AudioUnitSetParameter. The iPodEQ unit presets are returned by using AudioUnitGetProperty asking for the kAudioUnitProperty_FactoryPresets CFArrayRef. A current preset is then selected calling AudioUnitSetProperty using the kAudioUnitProperty_PresentPreset property and passing in the appropriate AUPreset. Note that the AU Host owns the returned CFArray and should release it when done. + +Audio data is provided from two stereo audio files. The audio data is AAC compressed and ExtAudioFile is used to convert this data to the Core Audio Canonical uncompressed LPCM client format for input to the multichannel mixer. + +All the relevant audio code is in the file AUGraphController.mm + +[URL](https://developer.apple.com/library/ios/#samplecode/iPhoneMixerEQGraphTest/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009555) + +Last Revision: Version 1.2, 2010-06-25 + +#GLTextureAtlas# + +This sample demonstrates how to use a texture atlas to draw multiple objects with different textures simultaneously using OpenGL ES. The application uses a texture atlas in the PVR format. By adding in degenerated triangles, and compute 3D transformations ourselves using matrices, we are able to collapse all the draw calls into one. + +[URL](https://developer.apple.com/library/ios/#samplecode/GLTextureAtlas/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009014) + +Last Revision: Version 1.5, 2010-06-25 + +#TransWeb# + +Demonstrates how to implement UIWebView with a transparent background. + +To achieve this you need to make the HTML body's background color transparent by doing the following - + +1) set the UIWebView's backgroundColor property to [UIColor clearColor] + +2) use the UIWebView's content in the html: + +3) the UIWebView's opaque property set to NO + +[URL](https://developer.apple.com/library/ios/#samplecode/TransWeb/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008614) + +Last Revision: Version 1.4, 2010-06-25 + +#LaunchMe# + +The LaunchMe sample application demonstrates how to register a new URL type. Registering a new URL type allows other applications to interact with yours. This sample also shows how to handle an incoming openURL: message from another application. When servicing an openURL: message from another application, you must be very careful to validate the URL in the message before allowing your application to proceed. After you build and run LaunchMe, it displays a dialog with instructions on how to use the application. + +[URL](https://developer.apple.com/library/ios/#samplecode/LaunchMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007417) + +Last Revision: Version 1.6, 2010-06-24 + +#TableViewSuite# + +This sample shows how to use UITableView through a progression of increasingly advanced applications that display information about time zones. + +The first example shows a simple list of the time zone names. It shows how to display a simple data set in a table view. + +The second example shows the time zones split into sections by region, with the region name as the section heading. It shows how to create an indexed table view. + +The third example shows the time zones split into sections alphabetically, with the first letter of their locale name as the section heading. It shows how to set up a table view to display an index. + +When implementing a table view cell, there's a tension between optimal scrolling performance and optimal edit/reordering performance. You should typically use subviews in the cell's content view. + +When you have an edit or reordering control, using subviews makes the implementation easier, and the animations perform better because UIKit doesn't have to redraw during animations. + +Subviews have two costs: + +1) Initialization. This can be largely mitigated by reusing table cells. 2) Compositing. This can be largely mitigated by making the views opaque. Often, one translucent subview is fine, but more than one frequently causes frame drops while scrolling. + +If the content is complex, however (more than about three subviews), scrolling performance may suffer. If this becomes a problem, you can instead draw directly in a subview of the table view cell's content view. + +The fourth example displays more information about each time zone, such as the time and relative day in that time zone. Its main aim is to show how you can customize a table view cell using subviews. It also introduces custom classes to represent regions and time zones to help reduce the overhead of calculating the required information -- these are also used in the fifth example. + +The fifth example is an extension of the fourth. It displays even more information about each time zone, such as the time and relative day in that time zone. Its shows how you can create a custom table view cell that contains a custom view that draws its content in -drawRect:. + +[URL](https://developer.apple.com/library/ios/#samplecode/TableViewSuite/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007318) + +Last Revision: Version 2.4, 2010-06-24 + +#Scrolling# + +Demonstrates how to implement two different style UIScrollViews. The first scroller contains multiple images, showing how to layout large content with multiple chunks of data (in our case 5 separate UIImageViews). + +The second scroller simply displays one image, matching its contentSize to the image size. The app's primary UIViewController manages both scrollers. Refer to this sample for best practices in how to implement content with a single image or with multiple images. + +[URL](https://developer.apple.com/library/ios/#samplecode/Scrolling/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008023) + +Last Revision: Version 1.1, 2010-06-23 + +#TheElements# + +TheElements is a sample application that provides access to the data contained in the Periodic Table of the Elements. The Periodic Table of the Elements catalogs all the known atomic elements in the universe. + +TheElements provides this data in multiple formats, allowing you to sort the data by name, atomic number, symbol name, and an element's physical state at room temperature. + +TheElements is structured as a Model-View-Controller application. There is distinct separation of the model data, the views used to present that data, and the controllers which act as a liaison between the model and controller. + +The application illustrates the following techniques: configuring and responding to selections in a tab bar, displaying information in a tableview using both plain and grouped style table views, using navigation controllers to navigate deeper into a data structure, subclassing UIView, providing a custom UITableViewCell consisting of multiple subviews, implementing the UITableViewDelegate protocol, implementing the UITableViewDataSource protocol, reacting to taps in views, open a URL to an external web site using Safari, flipping view content from front to back, and creating a reflection of a view in the interface. + +[URL](https://developer.apple.com/library/ios/#samplecode/TheElements/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007419) + +Last Revision: Version 1.11, 2010-06-23 + +#SimpleUndo# + +The root view controller displays information (title, author, and copyright date) about a book. The user can edit this information by tapping Edit in the navigation bar. When editing starts, the root view controller creates an undo manager to record changes. The undo manager supports up to three levels of undo and redo. When the user taps Done, changes are considered to be committed and the undo manager is disposed of. + +[URL](https://developer.apple.com/library/ios/#samplecode/SimpleUndo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008408) + +Last Revision: Version 1.1, 2010-06-23 + +#Accessory# + +Demonstrates how to implement a custom accessory view for your UITableView in the form of a checkmark button. It shows you how to override the appearance or control of the accessory view, much like that of "UITableViewCellAccessoryDetailDisclosureButton". It implements the custom accessory view by setting the table's "accessoryView" property with a UIButton of type "UIButtonTypeCustom". It can be toggled by selecting the entire table row by implementing UITableView's "didSelectRowAtIndexPath". The green checkmark is trackable (checked/unchecked), and can be toggled independent of table selection. + +[URL](https://developer.apple.com/library/ios/#samplecode/Accessory/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008066) + +Last Revision: Version 1.2, 2010-06-23 + +#MailComposer# + +See new sample code "MessageComposer" which includes both Mail and Messages features. + +This application shows how to target older OS versions while building with newly released APIs. It also illustrates how to use the MessageUI framework to edit and send email messages from within your application. + +Tap the "Compose Mail" button to display an email composition interface if your device is running iPhone OS 3.0 or launch the Mail application, otherwise. + +[URL](https://developer.apple.com/library/ios/#samplecode/MailComposer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008865) + +Last Revision: Version 1.1, 2010-06-22 + +#DateCell# + +Demonstrates formatted display of date objects in UITableViewCells and use of UIDatePicker to edit those values. + +Using a grouped style UITableViewController, the sample has two UITableViewCells to draw the primary title and NSDate value. This is accomplished using the built-in cell type "UITableViewCellStyleValue1" which supports left and right text. In addition, this sample shows how to use NSDateFormatter class to achieve the custom cell's date-formatted appearance. + +[URL](https://developer.apple.com/library/ios/#samplecode/DateCell/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008866) + +Last Revision: Version 1.1, 2010-06-17 + +#TableSearch# + +Demonstrates how to search the contents of a UITableView using UISearchBar and UISearchDisplayController, effectively filtering in and out the contents of that table. If an iPhone/iPod Touch application has large amounts of table data, this sample shows how to filter it down to a manageable amount if memory usage is a concern or you just want users to scroll through less table content. + +[URL](https://developer.apple.com/library/ios/#samplecode/TableSearch/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007848) + +Last Revision: Version 1.5, 2010-06-17 + +#BonjourWeb# + +This application illustrates the fundamentals of browsing for network services using Bonjour. The BonjourBrowser hierarchically displays Bonjour domains and services as table views in a navigation controller. The contents of the table views are discovered and updated dynamically using NSNetServiceBrowser objects. Tapping an item in the services table causes the corresponding NSNetService object to be resolved asynchronously. When that resolution completes, a delegate method is called which constructs a URL and opens it in Safari. + +[URL](https://developer.apple.com/library/ios/#samplecode/BonjourWeb/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007415) + +Last Revision: Version 2.9, 2010-06-16 + +#AddMusic# + +AddMusic demonstrates basic use of iPod library access, part of the Media Player framework. You use iPod library access to play songs, audio books, and audio podcasts that are synced from a user's desktop iTunes library. This sample uses the Media Player framework's built-in user interface for choosing music. AddMusic also demonstrates how to mix application audio with iPod library audio. The sample includes code for configuring application audio behavior using the AVAudioSession class and Audio Session Services. + + [URL](https://developer.apple.com/library/ios/#samplecode/AddMusic/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008845) + +Last Revision: Version 1.1.1, 2009-10-01 + +#GKTank# + +GKTank is a sample application that shows how to use the GKSession and GKPeerPickerController classes in the GameKit framework to add Peer-to-Peer Connectivity to an application. + +[URL](https://developer.apple.com/library/ios/#samplecode/GKTank/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008918) + +Last Revision: Version 1.0.1, 2009-06-08 + +#Not Include# +[FastEnumerationSample](https://developer.apple.com/library/ios/samplecode/FastEnumerationSample/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009411) + +[Quartz Composer SQLiteQuery](https://developer.apple.com/library/ios/samplecode/SQLiteQuery/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009327) + +[Quartz Composer IMStatus](https://developer.apple.com/library/ios/samplecode/IMStatus/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009321) + +[Quartz Composer HistogramOperation](https://developer.apple.com/library/ios/samplecode/HistogramOperation/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009319) + +[Quartz Composer iPatch](https://developer.apple.com/library/ios/samplecode/iPatch/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009322) + +[Quartz Composer Conceptual Compositions](https://developer.apple.com/library/ios/samplecode/Conceptual/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009227) + +[Birthdays](https://developer.apple.com/library/ios/samplecode/Birthdays/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003982) \ No newline at end of file diff --git a/Reachability.zip b/Reachability.zip new file mode 100644 index 0000000..166b1b3 Binary files /dev/null and b/Reachability.zip differ diff --git a/Reachability/Airport.png b/Reachability/Airport.png new file mode 100644 index 0000000..76e1256 Binary files /dev/null and b/Reachability/Airport.png differ diff --git a/Reachability/Classes/Reachability.h b/Reachability/Classes/Reachability.h new file mode 100644 index 0000000..317982f --- /dev/null +++ b/Reachability/Classes/Reachability.h @@ -0,0 +1,88 @@ +/* + + File: Reachability.h + Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import +#import + +typedef enum { + NotReachable = 0, + ReachableViaWiFi, + ReachableViaWWAN +} NetworkStatus; +#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification" + +@interface Reachability: NSObject +{ + BOOL localWiFiRef; + SCNetworkReachabilityRef reachabilityRef; +} + +//reachabilityWithHostName- Use to check the reachability of a particular host name. ++ (Reachability*) reachabilityWithHostName: (NSString*) hostName; + +//reachabilityWithAddress- Use to check the reachability of a particular IP address. ++ (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; + +//reachabilityForInternetConnection- checks whether the default route is available. +// Should be used by applications that do not connect to a particular host ++ (Reachability*) reachabilityForInternetConnection; + +//reachabilityForLocalWiFi- checks whether a local wifi connection is available. ++ (Reachability*) reachabilityForLocalWiFi; + +//Start listening for reachability notifications on the current run loop +- (BOOL) startNotifier; +- (void) stopNotifier; + +- (NetworkStatus) currentReachabilityStatus; +//WWAN may be available, but not active until a connection has been established. +//WiFi may require a connection for VPN on Demand. +- (BOOL) connectionRequired; +@end + + diff --git a/Reachability/Classes/Reachability.m b/Reachability/Classes/Reachability.m new file mode 100644 index 0000000..5ecdcf4 --- /dev/null +++ b/Reachability/Classes/Reachability.m @@ -0,0 +1,273 @@ +/* + + File: Reachability.m + Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs. + + Version: 2.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under + Apple's copyrights in this original Apple software (the "Apple Software"), to + use, reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions + of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may be used + to endorse or promote products derived from the Apple Software without specific + prior written permission from Apple. Except as expressly stated in this notice, + no other rights or licenses, express or implied, are granted by Apple herein, + including but not limited to any patent rights that may be infringed by your + derivative works or by other works in which the Apple Software may be + incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF + CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF + APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import +#import +#import +#import +#import + +#import + +#import "Reachability.h" + +#define kShouldPrintReachabilityFlags 1 + +static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment) +{ +#if kShouldPrintReachabilityFlags + + NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n", + (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-', + (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', + + (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', + (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', + (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', + (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', + (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', + (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', + (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-', + comment + ); +#endif +} + + +@implementation Reachability +static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) +{ + #pragma unused (target, flags) + NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback"); + NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback"); + + //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively + // in case someon uses the Reachablity object in a different thread. + NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init]; + + Reachability* noteObject = (Reachability*) info; + // Post a notification to notify the client that the network reachability changed. + [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject]; + + [myPool release]; +} + +- (BOOL) startNotifier +{ + BOOL retVal = NO; + SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL}; + if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)) + { + if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) + { + retVal = YES; + } + } + return retVal; +} + +- (void) stopNotifier +{ + if(reachabilityRef!= NULL) + { + SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + } +} + +- (void) dealloc +{ + [self stopNotifier]; + if(reachabilityRef!= NULL) + { + CFRelease(reachabilityRef); + } + [super dealloc]; +} + ++ (Reachability*) reachabilityWithHostName: (NSString*) hostName; +{ + Reachability* retVal = NULL; + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]); + if(reachability!= NULL) + { + retVal= [[[self alloc] init] autorelease]; + if(retVal!= NULL) + { + retVal->reachabilityRef = reachability; + retVal->localWiFiRef = NO; + } + } + return retVal; +} + ++ (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; +{ + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); + Reachability* retVal = NULL; + if(reachability!= NULL) + { + retVal= [[[self alloc] init] autorelease]; + if(retVal!= NULL) + { + retVal->reachabilityRef = reachability; + retVal->localWiFiRef = NO; + } + } + return retVal; +} + ++ (Reachability*) reachabilityForInternetConnection; +{ + struct sockaddr_in zeroAddress; + bzero(&zeroAddress, sizeof(zeroAddress)); + zeroAddress.sin_len = sizeof(zeroAddress); + zeroAddress.sin_family = AF_INET; + return [self reachabilityWithAddress: &zeroAddress]; +} + ++ (Reachability*) reachabilityForLocalWiFi; +{ + struct sockaddr_in localWifiAddress; + bzero(&localWifiAddress, sizeof(localWifiAddress)); + localWifiAddress.sin_len = sizeof(localWifiAddress); + localWifiAddress.sin_family = AF_INET; + // IN_LINKLOCALNETNUM is defined in as 169.254.0.0 + localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); + Reachability* retVal = [self reachabilityWithAddress: &localWifiAddress]; + if(retVal!= NULL) + { + retVal->localWiFiRef = YES; + } + return retVal; +} + +#pragma mark Network Flag Handling + +- (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags +{ + PrintReachabilityFlags(flags, "localWiFiStatusForFlags"); + + BOOL retVal = NotReachable; + if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect)) + { + retVal = ReachableViaWiFi; + } + return retVal; +} + +- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags +{ + PrintReachabilityFlags(flags, "networkStatusForFlags"); + if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) + { + // if target host is not reachable + return NotReachable; + } + + BOOL retVal = NotReachable; + + if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) + { + // if target host is reachable and no connection is required + // then we'll assume (for now) that your on Wi-Fi + retVal = ReachableViaWiFi; + } + + + if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || + (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) + { + // ... and the connection is on-demand (or on-traffic) if the + // calling application is using the CFSocketStream or higher APIs + + if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) + { + // ... and no [user] intervention is needed + retVal = ReachableViaWiFi; + } + } + + if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) + { + // ... but WWAN connections are OK if the calling application + // is using the CFNetwork (CFSocketStream?) APIs. + retVal = ReachableViaWWAN; + } + return retVal; +} + +- (BOOL) connectionRequired; +{ + NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef"); + SCNetworkReachabilityFlags flags; + if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) + { + return (flags & kSCNetworkReachabilityFlagsConnectionRequired); + } + return NO; +} + +- (NetworkStatus) currentReachabilityStatus +{ + NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef"); + NetworkStatus retVal = NotReachable; + SCNetworkReachabilityFlags flags; + if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) + { + if(localWiFiRef) + { + retVal = [self localWiFiStatusForFlags: flags]; + } + else + { + retVal = [self networkStatusForFlags: flags]; + } + } + return retVal; +} +@end diff --git a/Reachability/Classes/ReachabilityAppDelegate.h b/Reachability/Classes/ReachabilityAppDelegate.h new file mode 100644 index 0000000..f0669d0 --- /dev/null +++ b/Reachability/Classes/ReachabilityAppDelegate.h @@ -0,0 +1,70 @@ +/* + +File: ReachabilityAppDelegate.h +Abstract: The application's controller. + +Version: 2.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class Reachability; +@interface ReachabilityAppDelegate: NSObject { + IBOutlet UIWindow* window; + IBOutlet UIView* contentView; + IBOutlet UILabel* summaryLabel; + + IBOutlet UITextField* remoteHostLabel; + IBOutlet UIImageView* remoteHostIcon; + IBOutlet UITextField* remoteHostStatusField; + + IBOutlet UIImageView* internetConnectionIcon; + IBOutlet UITextField* internetConnectionStatusField; + + IBOutlet UIImageView* localWiFiConnectionIcon; + IBOutlet UITextField* localWiFiConnectionStatusField; + + Reachability* hostReach; + Reachability* internetReach; + Reachability* wifiReach; +} +@end diff --git a/Reachability/Classes/ReachabilityAppDelegate.m b/Reachability/Classes/ReachabilityAppDelegate.m new file mode 100644 index 0000000..d6affc9 --- /dev/null +++ b/Reachability/Classes/ReachabilityAppDelegate.m @@ -0,0 +1,158 @@ +/* + +File: ReachabilityAppDelegate.m +Abstract: The application's controller. + +Version: 2.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "ReachabilityAppDelegate.h" +#import "Reachability.h" + +@implementation ReachabilityAppDelegate + +- (void) configureTextField: (UITextField*) textField imageView: (UIImageView*) imageView reachability: (Reachability*) curReach +{ + NetworkStatus netStatus = [curReach currentReachabilityStatus]; + BOOL connectionRequired= [curReach connectionRequired]; + NSString* statusString= @""; + switch (netStatus) + { + case NotReachable: + { + statusString = @"Access Not Available"; + imageView.image = [UIImage imageNamed: @"stop-32.png"] ; + //Minor interface detail- connectionRequired may return yes, even when the host is unreachable. We cover that up here... + connectionRequired= NO; + break; + } + + case ReachableViaWWAN: + { + statusString = @"Reachable WWAN"; + imageView.image = [UIImage imageNamed: @"WWAN5.png"]; + break; + } + case ReachableViaWiFi: + { + statusString= @"Reachable WiFi"; + imageView.image = [UIImage imageNamed: @"Airport.png"]; + break; + } + } + if(connectionRequired) + { + statusString= [NSString stringWithFormat: @"%@, Connection Required", statusString]; + } + textField.text= statusString; +} + +- (void) updateInterfaceWithReachability: (Reachability*) curReach +{ + if(curReach == hostReach) + { + [self configureTextField: remoteHostStatusField imageView: remoteHostIcon reachability: curReach]; + NetworkStatus netStatus = [curReach currentReachabilityStatus]; + BOOL connectionRequired= [curReach connectionRequired]; + + summaryLabel.hidden = (netStatus != ReachableViaWWAN); + NSString* baseLabel= @""; + if(connectionRequired) + { + baseLabel= @"Cellular data network is available.\n Internet traffic will be routed through it after a connection is established."; + } + else + { + baseLabel= @"Cellular data network is active.\n Internet traffic will be routed through it."; + } + summaryLabel.text= baseLabel; + } + if(curReach == internetReach) + { + [self configureTextField: internetConnectionStatusField imageView: internetConnectionIcon reachability: curReach]; + } + if(curReach == wifiReach) + { + [self configureTextField: localWiFiConnectionStatusField imageView: localWiFiConnectionIcon reachability: curReach]; + } + +} + +//Called by Reachability whenever status changes. +- (void) reachabilityChanged: (NSNotification* )note +{ + Reachability* curReach = [note object]; + NSParameterAssert([curReach isKindOfClass: [Reachability class]]); + [self updateInterfaceWithReachability: curReach]; +} + + +- (void) applicationDidFinishLaunching: (UIApplication* )application +{ + #pragma unused(application) + contentView.backgroundColor = [UIColor groupTableViewBackgroundColor]; + + summaryLabel.hidden = YES; + + + // Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the + // method "reachabilityChanged" will be called. + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil]; + + //Change the host name here to change the server your monitoring + remoteHostLabel.text = [NSString stringWithFormat: @"Remote Host: %@", @"www.apple.com"]; + hostReach = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain]; + [hostReach startNotifier]; + [self updateInterfaceWithReachability: hostReach]; + + internetReach = [[Reachability reachabilityForInternetConnection] retain]; + [internetReach startNotifier]; + [self updateInterfaceWithReachability: internetReach]; + + wifiReach = [[Reachability reachabilityForLocalWiFi] retain]; + [wifiReach startNotifier]; + [self updateInterfaceWithReachability: wifiReach]; + + [window makeKeyAndVisible]; + +} +@end diff --git a/Reachability/Default.png b/Reachability/Default.png new file mode 100644 index 0000000..ab51ddb Binary files /dev/null and b/Reachability/Default.png differ diff --git a/Reachability/English.lproj/MainWindow.xib b/Reachability/English.lproj/MainWindow.xib new file mode 100644 index 0000000..af5f331 --- /dev/null +++ b/Reachability/English.lproj/MainWindow.xib @@ -0,0 +1,568 @@ + + + + 512 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + YES + + + 1298 + + YES + + + 1306 + {{8, 318}, {303, 99}} + + NO + YES + NO + Q2VsbHVsYXIgZGF0YSBuZXR3b3JrIGlzIGF2YWlsYWJsZS4KSW50ZXJuZXQgdHJhZmZpYyB3aWxsIGJl +IHJvdXRlZCB0aHJvdWdoIGl0Lg + + 1 + MSAwIDAAA + + + 1 + NO + 1.400000e+01 + 0 + 1 + + + + 1316 + {{20, 61}, {32, 32}} + + NO + NO + 4 + NO + + + + 1316 + {{20, 155}, {32, 32}} + + NO + NO + 4 + NO + + + + 1316 + {{60, 62}, {240, 31}} + + NO + NO + 0 + + 3 + + 3 + MAA + + 2 + + + YES + YES + 1.200000e+01 + + + + + 1316 + {{20, 25}, {280, 29}} + + NO + NO + 0 + Remote Host: + + 3 + MAA + + + + Helvetica + 1.900000e+01 + 16 + + YES + YES + 2.900000e+01 + + + + + 1316 + {{60, 155}, {240, 31}} + + NO + NO + 0 + + 3 + + 3 + MAA + + + YES + YES + 1.200000e+01 + + + + + 1316 + {{20, 117}, {280, 29}} + + NO + NO + 0 + TCP/IP Routing Available + + 3 + MAA + + + + YES + YES + 2.900000e+01 + + + + + 1316 + {{20, 253}, {32, 32}} + + NO + NO + 4 + NO + + + + 1316 + {{60, 254}, {240, 31}} + + NO + NO + 0 + + 3 + + 3 + MAA + + + YES + YES + 1.200000e+01 + + + + + 1316 + {{20, 216}, {280, 29}} + + NO + NO + 0 + Local WiFi + + 3 + MAA + + + + YES + YES + 2.900000e+01 + + + + {320, 480} + + + 3 + MQA + + + NO + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + delegate + + + + 5 + + + + window + + + + 6 + + + + contentView + + + + 8 + + + + summaryLabel + + + + 10 + + + + internetConnectionStatusField + + + + 21 + + + + remoteHostIcon + + + + 24 + + + + remoteHostLabel + + + + 27 + + + + remoteHostStatusField + + + + 28 + + + + internetConnectionIcon + + + + 30 + + + + localWiFiConnectionIcon + + + + 35 + + + + localWiFiConnectionStatusField + + + + 36 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 4 + + + ReachabilityAppDelegate + + + 7 + + + YES + + + + + + + + + + + + + + + 9 + + + + + -2 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 15 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + 19 + + + + + 29 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 15.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 19.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 29.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + 7.IBPluginDependency + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{287, 643}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ReachabilityAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 36 + + + + YES + + ReachabilityAppDelegate + NSObject + + YES + + YES + contentView + internetConnectionIcon + internetConnectionStatusField + localWiFiConnectionIcon + localWiFiConnectionStatusField + remoteHostIcon + remoteHostLabel + remoteHostStatusField + summaryLabel + window + + + YES + UIView + UIImageView + UITextField + UIImageView + UITextField + UIImageView + UITextField + UITextField + UILabel + UIWindow + + + + IBProjectSource + Classes/ReachabilityAppDelegate.h + + + + + 0 + Reachability.xcodeproj + 3 + 3.0 + + diff --git a/Reachability/Images/Icon-72.png b/Reachability/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/Reachability/Images/Icon-72.png differ diff --git a/Reachability/Images/Icon-Small-50.png b/Reachability/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/Reachability/Images/Icon-Small-50.png differ diff --git a/Reachability/Images/Icon-Small.png b/Reachability/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/Reachability/Images/Icon-Small.png differ diff --git a/Reachability/Images/Icon-Small@2x.png b/Reachability/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/Reachability/Images/Icon-Small@2x.png differ diff --git a/Reachability/Images/Icon.png b/Reachability/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/Reachability/Images/Icon.png differ diff --git a/Reachability/Images/Icon@2x.png b/Reachability/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/Reachability/Images/Icon@2x.png differ diff --git a/Reachability/Images/iTunesArtwork b/Reachability/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/Reachability/Images/iTunesArtwork differ diff --git a/Reachability/Info.plist b/Reachability/Info.plist new file mode 100644 index 0000000..334d2bf --- /dev/null +++ b/Reachability/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + Reachability + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.2 + NSMainNibFile + MainWindow + UIStatusBarHidden + + LSRequiresIPhoneOS + + + diff --git a/Reachability/Network.png b/Reachability/Network.png new file mode 100644 index 0000000..f5679c3 Binary files /dev/null and b/Reachability/Network.png differ diff --git a/Reachability/Reachability.xcodeproj/project.pbxproj b/Reachability/Reachability.xcodeproj/project.pbxproj new file mode 100644 index 0000000..608235c --- /dev/null +++ b/Reachability/Reachability.xcodeproj/project.pbxproj @@ -0,0 +1,376 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 02084CDB11E53A7500199A4D /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 02084CDA11E53A7500199A4D /* iTunesArtwork */; }; + 025B4FF211CAE2EB004E3314 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B4FEB11CAE2EB004E3314 /* Icon-72.png */; }; + 025B4FF311CAE2EB004E3314 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B4FEC11CAE2EB004E3314 /* Icon-Small-50.png */; }; + 025B4FF411CAE2EB004E3314 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B4FED11CAE2EB004E3314 /* Icon-Small.png */; }; + 025B4FF511CAE2EB004E3314 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B4FEE11CAE2EB004E3314 /* Icon-Small@2x.png */; }; + 025B4FF611CAE2EB004E3314 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B4FEF11CAE2EB004E3314 /* Icon.png */; }; + 025B4FF711CAE2EB004E3314 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B4FF011CAE2EB004E3314 /* Icon@2x.png */; }; + 025B501511CAE3CD004E3314 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 025B501411CAE3CD004E3314 /* MainWindow.xib */; }; + 02C021BA0FA263C7006AFB5F /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 02C021B90FA263C7006AFB5F /* Reachability.m */; }; + 1D3623260D0F684500981E51 /* ReachabilityAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* ReachabilityAppDelegate.m */; }; + 1D4F2F9A0D10AC310045FB13 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D4F2F990D10AC310045FB13 /* Default.png */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 414AF4950D5FDBA400072C1E /* WWAN5.png in Resources */ = {isa = PBXBuildFile; fileRef = 414AF4930D5FDBA400072C1E /* WWAN5.png */; }; + 414AF4960D5FDBA400072C1E /* Airport.png in Resources */ = {isa = PBXBuildFile; fileRef = 414AF4940D5FDBA400072C1E /* Airport.png */; }; + 418B52B50D64ED9A00D0F015 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 418561090D5E57F70036FBAB /* SystemConfiguration.framework */; }; + 418B52B70D64EDA900D0F015 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 41A855100D62A5670049A9B9 /* stop-32.png in Resources */ = {isa = PBXBuildFile; fileRef = 41A8550F0D62A5670049A9B9 /* stop-32.png */; }; + 844866C10DB922FC009556CD /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 844866C00DB922FC009556CD /* icon.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 02084CDA11E53A7500199A4D /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 025B4FEB11CAE2EB004E3314 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 025B4FEC11CAE2EB004E3314 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 025B4FED11CAE2EB004E3314 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 025B4FEE11CAE2EB004E3314 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 025B4FEF11CAE2EB004E3314 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 025B4FF011CAE2EB004E3314 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 02C021B80FA263C7006AFB5F /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; + 02C021B90FA263C7006AFB5F /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* ReachabilityAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ReachabilityAppDelegate.h; sourceTree = ""; tabWidth = 4; usesTabs = 0; }; + 1D3623250D0F684500981E51 /* ReachabilityAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = ReachabilityAppDelegate.m; sourceTree = ""; tabWidth = 4; usesTabs = 0; }; + 1D4F2F990D10AC310045FB13 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* Reachability.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Reachability.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28CE467A0DA6896A003A8F85 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainWindow.xib; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Reachability_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability_Prefix.pch; sourceTree = ""; }; + 414AF4930D5FDBA400072C1E /* WWAN5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = WWAN5.png; sourceTree = ""; }; + 414AF4940D5FDBA400072C1E /* Airport.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Airport.png; sourceTree = ""; }; + 418561090D5E57F70036FBAB /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 41A8550F0D62A5670049A9B9 /* stop-32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "stop-32.png"; sourceTree = ""; }; + 41AD131B0D60E5BE00475B51 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 844866C00DB922FC009556CD /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 844866CF0DB9233D009556CD /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 418B52B50D64ED9A00D0F015 /* SystemConfiguration.framework in Frameworks */, + 418B52B70D64EDA900D0F015 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 025B4FEA11CAE2EB004E3314 /* Images */ = { + isa = PBXGroup; + children = ( + 02084CDA11E53A7500199A4D /* iTunesArtwork */, + 025B4FEB11CAE2EB004E3314 /* Icon-72.png */, + 025B4FEC11CAE2EB004E3314 /* Icon-Small-50.png */, + 025B4FED11CAE2EB004E3314 /* Icon-Small.png */, + 025B4FEE11CAE2EB004E3314 /* Icon-Small@2x.png */, + 025B4FEF11CAE2EB004E3314 /* Icon.png */, + 025B4FF011CAE2EB004E3314 /* Icon@2x.png */, + ); + path = Images; + sourceTree = ""; + }; + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* ReachabilityAppDelegate.h */, + 1D3623250D0F684500981E51 /* ReachabilityAppDelegate.m */, + 02C021B80FA263C7006AFB5F /* Reachability.h */, + 02C021B90FA263C7006AFB5F /* Reachability.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Reachability.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 844866CF0DB9233D009556CD /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Reachability_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 025B4FEA11CAE2EB004E3314 /* Images */, + 844866C00DB922FC009556CD /* icon.png */, + 025B501411CAE3CD004E3314 /* MainWindow.xib */, + 41A8550F0D62A5670049A9B9 /* stop-32.png */, + 414AF4930D5FDBA400072C1E /* WWAN5.png */, + 414AF4940D5FDBA400072C1E /* Airport.png */, + 1D4F2F990D10AC310045FB13 /* Default.png */, + 41AD131B0D60E5BE00475B51 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 418561090D5E57F70036FBAB /* SystemConfiguration.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Reachability */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Reachability" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Reachability; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* Reachability.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Reachability" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Reachability */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D4F2F9A0D10AC310045FB13 /* Default.png in Resources */, + 414AF4950D5FDBA400072C1E /* WWAN5.png in Resources */, + 414AF4960D5FDBA400072C1E /* Airport.png in Resources */, + 41A855100D62A5670049A9B9 /* stop-32.png in Resources */, + 025B501511CAE3CD004E3314 /* MainWindow.xib in Resources */, + 844866C10DB922FC009556CD /* icon.png in Resources */, + 025B4FF211CAE2EB004E3314 /* Icon-72.png in Resources */, + 025B4FF311CAE2EB004E3314 /* Icon-Small-50.png in Resources */, + 025B4FF411CAE2EB004E3314 /* Icon-Small.png in Resources */, + 025B4FF511CAE2EB004E3314 /* Icon-Small@2x.png in Resources */, + 025B4FF611CAE2EB004E3314 /* Icon.png in Resources */, + 025B4FF711CAE2EB004E3314 /* Icon@2x.png in Resources */, + 02084CDB11E53A7500199A4D /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* ReachabilityAppDelegate.m in Sources */, + 02C021BA0FA263C7006AFB5F /* Reachability.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 025B501411CAE3CD004E3314 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 28CE467A0DA6896A003A8F85 /* English */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Reachability_Prefix.pch; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO; + GCC_WARN_INHIBIT_ALL_WARNINGS = NO; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = NO; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + PRODUCT_NAME = Reachability; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_RESOURCE_RULES_PATH = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Reachability_Prefix.pch; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO; + GCC_WARN_INHIBIT_ALL_WARNINGS = NO; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = NO; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + OTHER_CODE_SIGN_FLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = Reachability; + SDKROOT = iphoneos4.0; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Reachability" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Reachability" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Reachability/Reachability_Prefix.pch b/Reachability/Reachability_Prefix.pch new file mode 100644 index 0000000..05b388a --- /dev/null +++ b/Reachability/Reachability_Prefix.pch @@ -0,0 +1,52 @@ +/* + +File: Reachability_Prefix.pch +Abstract: This file is included for support purposes and isn't necessary for +understanding this sample. + +Version: 2.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Reachability/ReadMe.txt b/Reachability/ReadMe.txt new file mode 100644 index 0000000..55459dc --- /dev/null +++ b/Reachability/ReadMe.txt @@ -0,0 +1,96 @@ +Reachability + +======================================================================== +DESCRIPTION: + +The Reachability sample application demonstrates how to use the System +Configuration framework to monitor the network state of an iPhone or +iPod touch. In particular, it demonstrates how to know when IP can be +routed and when traffic will be routed through a Wireless Wide Area +Network (WWAN) interface such as EDGE or 3G. + +Note: Reachability cannot tell your application if you can connect to a +particular host, only that an interface is available that might allow a +connection, and whether that interface is the WWAN. + +======================================================================== +USING THE SAMPLE + +Build and run the sample using Xcode. When running the iPhone Simulator, +you can exercise the application by disconnecting the Ethernet cable, +turning off AirPort, or by joining an ad-hoc local Wi-Fi network. + +By default, the application uses www.apple.com for its remote host. You +can change the host it uses in ReachabilityAppDelegate.m by modifying +the call to [Reachability reachabilityWithHostName] in +-applicationDidFinishLaunching. + +IMPORTANT: Reachability must use DNS to resolve the host name before it +can determine the Reachability of that host, and this may take time on +certain network connections. Because of this, the API will return +NotReachable until name resolution has completed. This delay may be +visible in the interface on some networks. + +The Reachability sample demonstrates the asynchronous use of the +SCNetworkReachability API. You can use the API synchronously, but do not +issue a synchronous check by hostName on the main thread. If the device +cannot reach a DNS server or is on a slow network, a synchronous call to +the SCNetworkReachabilityGetFlags function can block for up to 30 +seconds trying to resolve the hostName. If this happens on the main +thread, the application watchdog will kill the application after 20 +seconds of inactivity. + +SCNetworkReachability API's do not currently provide a means to detect +support for GameKit Peer To Peer networking over BlueTooth. + +======================================================================== +BUILD REQUIREMENTS + +iOS 4.0 + +======================================================================== +RUNTIME REQUIREMENTS + +iOS 4.0 + +======================================================================== +PACKAGING LIST + +Reachability.h Reachability.m +-Basic demonstration of how to use the SystemConfiguration Reachablity APIs. + +ReachabilityAppDelegate.h ReachabilityAppDelegate.m +-The application's controller. + +======================================================================== +CHANGES FROM PREVIOUS VERSIONS +Version 2.2 +-Updated sample for iOS 4.0 + +Version 2.1 +-Removed [super init] from class method. +-Fixed spelling error in method names. +-Fixed several warnings. + +Version 2.0 +-Greatly simplified UI code. +-Rewrote Reachability object to be fully asychronous and simplify. +monitoring of multiple SCNetworkReachabilityRefs. +-Added code showing how to monitor wether a connection will be required. + +Version 1.5 +- Updated for and tested with iPhone OS 2.0. First public release. + +Version 1.4 +- Updated for Beta 7. + +Version 1.3 +- Updated for Beta 6. - Added LSRequiresIPhoneOS key to Info.plist. + +Version 1.2 +- Updated for Beta 4. Added code signing. + +Version 1.1 +- Updated for Beta 3 to use a nib file. + +Copyright (C) Apple Inc. All rights reserved. \ No newline at end of file diff --git a/Reachability/WWAN5.png b/Reachability/WWAN5.png new file mode 100644 index 0000000..b475a21 Binary files /dev/null and b/Reachability/WWAN5.png differ diff --git a/Reachability/icon.png b/Reachability/icon.png new file mode 100644 index 0000000..955e114 Binary files /dev/null and b/Reachability/icon.png differ diff --git a/Reachability/main.m b/Reachability/main.m new file mode 100644 index 0000000..2b91702 --- /dev/null +++ b/Reachability/main.m @@ -0,0 +1,57 @@ +/* + +File: main.m +Abstract: Main entry point. + +Version: 2.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. +("Apple") in consideration of your agreement to the following terms, and your +use, installation, modification or redistribution of this Apple software +constitutes acceptance of these terms. If you do not agree with these terms, +please do not use, install, modify or redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and subject +to these terms, Apple grants you a personal, non-exclusive license, under +Apple's copyrights in this original Apple software (the "Apple Software"), to +use, reproduce, modify and redistribute the Apple Software, with or without +modifications, in source and/or binary forms; provided that if you redistribute +the Apple Software in its entirety and without modifications, you must retain +this notice and the following text and disclaimers in all such redistributions +of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products derived from the Apple Software without specific +prior written permission from Apple. Except as expressly stated in this notice, +no other rights or licenses, express or implied, are granted by Apple herein, +including but not limited to any patent rights that may be infringed by your +derivative works or by other works in which the Apple Software may be +incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN +COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR +DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF +CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + + +#import + +int main(int argc, char* argv[]) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/Reachability/red.png b/Reachability/red.png new file mode 100644 index 0000000..4d100b6 Binary files /dev/null and b/Reachability/red.png differ diff --git a/Reachability/stop-32.png b/Reachability/stop-32.png new file mode 100644 index 0000000..b5639d3 Binary files /dev/null and b/Reachability/stop-32.png differ diff --git a/Scrolling.zip b/Scrolling.zip new file mode 100644 index 0000000..9be66a3 Binary files /dev/null and b/Scrolling.zip differ diff --git a/Scrolling/AppDelegate.h b/Scrolling/AppDelegate.h new file mode 100755 index 0000000..26c83b3 --- /dev/null +++ b/Scrolling/AppDelegate.h @@ -0,0 +1,61 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for installing our view controller. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class MyViewController; + +@interface AppDelegate : NSObject +{ + IBOutlet UIWindow *window; + IBOutlet MyViewController *myViewController; +} + +@property (nonatomic, retain) UIWindow *window; +@property (nonatomic, retain) MyViewController *myViewController; + +@end diff --git a/Scrolling/AppDelegate.m b/Scrolling/AppDelegate.m new file mode 100755 index 0000000..c01d73e --- /dev/null +++ b/Scrolling/AppDelegate.m @@ -0,0 +1,70 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for installing our view controller. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MyViewController.h" + +@implementation AppDelegate; + +@synthesize window, myViewController; + +- (void)dealloc +{ + [myViewController release]; + [window release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + [window addSubview:myViewController.view]; + [window makeKeyAndVisible]; +} + +@end diff --git a/Scrolling/Info.plist b/Scrolling/Info.plist new file mode 100755 index 0000000..26e5862 --- /dev/null +++ b/Scrolling/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + NSMainNibFile + MainWindow + UIStatusBarStyle + UIStatusBarStyleBlackOpaque + LSRequiresIPhoneOS + + + diff --git a/Scrolling/MyViewController.h b/Scrolling/MyViewController.h new file mode 100644 index 0000000..40e9920 --- /dev/null +++ b/Scrolling/MyViewController.h @@ -0,0 +1,61 @@ +/* + File: MyViewController.h + Abstract: The main view controller of this app. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class MyScrollView; + +@interface MyViewController : UIViewController +{ + IBOutlet UIScrollView *scrollView1; // holds five small images to scroll horizontally + IBOutlet UIScrollView *scrollView2; // holds one large image to scroll in both directions +} + +@property (nonatomic, retain) UIView *scrollView1; +@property (nonatomic, retain) UIView *scrollView2; + +@end diff --git a/Scrolling/MyViewController.m b/Scrolling/MyViewController.m new file mode 100644 index 0000000..df2a36e --- /dev/null +++ b/Scrolling/MyViewController.m @@ -0,0 +1,150 @@ +/* + File: MyViewController.m + Abstract: The main view controller of this app. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyViewController.h" + +@implementation MyViewController + +@synthesize scrollView1, scrollView2; + +const CGFloat kScrollObjHeight = 199.0; +const CGFloat kScrollObjWidth = 280.0; +const NSUInteger kNumImages = 5; + + +- (void)layoutScrollImages +{ + UIImageView *view = nil; + NSArray *subviews = [scrollView1 subviews]; + + // reposition all image subviews in a horizontal serial fashion + CGFloat curXLoc = 0; + for (view in subviews) + { + if ([view isKindOfClass:[UIImageView class]] && view.tag > 0) + { + CGRect frame = view.frame; + frame.origin = CGPointMake(curXLoc, 0); + view.frame = frame; + + curXLoc += (kScrollObjWidth); + } + } + + // set the content size so it can be scrollable + [scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)]; +} + +- (void)viewDidLoad +{ + self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor]; + + // 1. setup the scrollview for multiple images and add it to the view controller + // + // note: the following can be done in Interface Builder, but we show this in code for clarity + [scrollView1 setBackgroundColor:[UIColor blackColor]]; + [scrollView1 setCanCancelContentTouches:NO]; + scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite; + scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview + scrollView1.scrollEnabled = YES; + + // pagingEnabled property default is NO, if set the scroller will stop or snap at each photo + // if you want free-flowing scroll, don't set this property. + scrollView1.pagingEnabled = YES; + + // load all the images from our bundle and add them to the scroll view + NSUInteger i; + for (i = 1; i <= kNumImages; i++) + { + NSString *imageName = [NSString stringWithFormat:@"image%d.jpg", i]; + UIImage *image = [UIImage imageNamed:imageName]; + UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; + + // setup each frame to a default height and width, it will be properly placed when we call "updateScrollList" + CGRect rect = imageView.frame; + rect.size.height = kScrollObjHeight; + rect.size.width = kScrollObjWidth; + imageView.frame = rect; + imageView.tag = i; // tag our images for later use when we place them in serial fashion + [scrollView1 addSubview:imageView]; + [imageView release]; + } + + [self layoutScrollImages]; // now place the photos in serial layout within the scrollview + + // 2. setup the scrollview for one image and add it to the view controller + // + [scrollView2 setBackgroundColor:[UIColor blackColor]]; + [scrollView2 setCanCancelContentTouches:NO]; + scrollView2.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview + scrollView2.indicatorStyle = UIScrollViewIndicatorStyleWhite; + UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image0.jpg"]]; + [scrollView2 addSubview:imageView]; + [scrollView2 setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)]; + [scrollView2 setScrollEnabled:YES]; + [imageView release]; +} + +- (void)dealloc +{ + [scrollView1 release]; + [scrollView2 release]; + + [super dealloc]; +} + +- (void)didReceiveMemoryWarning +{ + // invoke super's implementation to do the Right Thing, but also release the input controller since we can do that + // In practice this is unlikely to be used in this application, and it would be of little benefit, + // but the principle is the important thing. + // + [super didReceiveMemoryWarning]; +} + +@end + diff --git a/Scrolling/Prefix.pch b/Scrolling/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/Scrolling/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Scrolling/ReadMe.txt b/Scrolling/ReadMe.txt new file mode 100644 index 0000000..28d7b5e --- /dev/null +++ b/Scrolling/ReadMe.txt @@ -0,0 +1,30 @@ +Scrolling + +Demonstrates how to implement two different style UIScrollViews. The first scroller contains multiple images, showing how to layout large content with multiple chunks of data (in our case 5 separate UIImageViews). +The second scroller simply displays one image, matching its contentSize to the image size. The app's primary UIViewController manages both scrollers. Refer to this sample for best practices in how to implement content with a single image or with multiple images. + + +Build Requirements +iOS 4.0 SDK + + +Runtime Requirements +iPhone OS 3.2 or later + + +Using the Sample +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. When launched observe both scroll views and examine the contents of each. Scroll through the top scroller with horizontal direction only, scroll the bottom scroll in vertical and horizontal directions. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application's delegate to setup its window and content. +MyViewController.h/.m - The main UIViewController containing both scroll views. + + +Changes from Previous Versions +1.0 - First release. +1.1 - Upgraded project to build with the iOS 4.0 SDK. + + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/Scrolling/Scrolling.xcodeproj/project.pbxproj b/Scrolling/Scrolling.xcodeproj/project.pbxproj new file mode 100755 index 0000000..e68f0c1 --- /dev/null +++ b/Scrolling/Scrolling.xcodeproj/project.pbxproj @@ -0,0 +1,325 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 182A8D7811D2BE9E00E156CC /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7111D2BE9E00E156CC /* Icon-72.png */; }; + 182A8D7911D2BE9E00E156CC /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7211D2BE9E00E156CC /* Icon-Small-50.png */; }; + 182A8D7A11D2BE9E00E156CC /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7311D2BE9E00E156CC /* Icon-Small.png */; }; + 182A8D7B11D2BE9E00E156CC /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7411D2BE9E00E156CC /* Icon-Small@2x.png */; }; + 182A8D7C11D2BE9E00E156CC /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7511D2BE9E00E156CC /* Icon.png */; }; + 182A8D7D11D2BE9E00E156CC /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7611D2BE9E00E156CC /* Icon@2x.png */; }; + 182A8D7E11D2BE9E00E156CC /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D7711D2BE9E00E156CC /* iTunesArtwork */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 53095FF40D9C4D1A00F143AD /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF00D9C4D1A00F143AD /* MyViewController.m */; }; + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF30D9C4D1A00F143AD /* AppDelegate.m */; }; + 5309602E0D9C4E0800F143AD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5309602D0D9C4E0800F143AD /* QuartzCore.framework */; }; + 53D080390E5362EE008EBE62 /* image5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 53D080330E5362EE008EBE62 /* image5.jpg */; }; + 53D0803A0E5362EE008EBE62 /* image0.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 53D080340E5362EE008EBE62 /* image0.jpg */; }; + 53D0803B0E5362EE008EBE62 /* image4.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 53D080350E5362EE008EBE62 /* image4.jpg */; }; + 53D0803C0E5362EE008EBE62 /* image3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 53D080360E5362EE008EBE62 /* image3.jpg */; }; + 53D0803D0E5362EE008EBE62 /* image2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 53D080370E5362EE008EBE62 /* image2.jpg */; }; + 53D0803E0E5362EE008EBE62 /* image1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 53D080380E5362EE008EBE62 /* image1.jpg */; }; + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EACC050DDA319F00908D73 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 182A8D7111D2BE9E00E156CC /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 182A8D7211D2BE9E00E156CC /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 182A8D7311D2BE9E00E156CC /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 182A8D7411D2BE9E00E156CC /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 182A8D7511D2BE9E00E156CC /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 182A8D7611D2BE9E00E156CC /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 182A8D7711D2BE9E00E156CC /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* Scrolling.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Scrolling.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53095FEF0D9C4D0500F143AD /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53095FF00D9C4D1A00F143AD /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 53095FF10D9C4D1A00F143AD /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5309602D0D9C4E0800F143AD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 53D080330E5362EE008EBE62 /* image5.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = image5.jpg; path = images/image5.jpg; sourceTree = ""; }; + 53D080340E5362EE008EBE62 /* image0.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = image0.jpg; path = images/image0.jpg; sourceTree = ""; }; + 53D080350E5362EE008EBE62 /* image4.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = image4.jpg; path = images/image4.jpg; sourceTree = ""; }; + 53D080360E5362EE008EBE62 /* image3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = image3.jpg; path = images/image3.jpg; sourceTree = ""; }; + 53D080370E5362EE008EBE62 /* image2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = image2.jpg; path = images/image2.jpg; sourceTree = ""; }; + 53D080380E5362EE008EBE62 /* image1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = image1.jpg; path = images/image1.jpg; sourceTree = ""; }; + 53DAF44A0E5B2806002A9460 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 53EACC060DDA319F00908D73 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 5309602E0D9C4E0800F143AD /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Scrolling.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53DAF44A0E5B2806002A9460 /* ReadMe.txt */, + 53AF8AEC0D9C50B700726DBA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 182A8D7111D2BE9E00E156CC /* Icon-72.png */, + 182A8D7211D2BE9E00E156CC /* Icon-Small-50.png */, + 182A8D7311D2BE9E00E156CC /* Icon-Small.png */, + 182A8D7411D2BE9E00E156CC /* Icon-Small@2x.png */, + 182A8D7511D2BE9E00E156CC /* Icon.png */, + 182A8D7611D2BE9E00E156CC /* Icon@2x.png */, + 182A8D7711D2BE9E00E156CC /* iTunesArtwork */, + 53D080330E5362EE008EBE62 /* image5.jpg */, + 53D080340E5362EE008EBE62 /* image0.jpg */, + 53D080350E5362EE008EBE62 /* image4.jpg */, + 53D080360E5362EE008EBE62 /* image3.jpg */, + 53D080370E5362EE008EBE62 /* image2.jpg */, + 53D080380E5362EE008EBE62 /* image1.jpg */, + 8D1107310486CEB800E47090 /* Info.plist */, + 53EACC050DDA319F00908D73 /* MainWindow.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5309602D0D9C4E0800F143AD /* QuartzCore.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53AF8AEC0D9C50B700726DBA /* Sources */ = { + isa = PBXGroup; + children = ( + 53095FEF0D9C4D0500F143AD /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */, + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */, + 53095FF10D9C4D1A00F143AD /* MyViewController.h */, + 53095FF00D9C4D1A00F143AD /* MyViewController.m */, + ); + name = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Scrolling */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Scrolling" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Scrolling; + productName = IBTest; + productReference = 1D6058910D05DD3D006BFB54 /* Scrolling.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Scrolling" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Scrolling */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */, + 53D080390E5362EE008EBE62 /* image5.jpg in Resources */, + 53D0803A0E5362EE008EBE62 /* image0.jpg in Resources */, + 53D0803B0E5362EE008EBE62 /* image4.jpg in Resources */, + 53D0803C0E5362EE008EBE62 /* image3.jpg in Resources */, + 53D0803D0E5362EE008EBE62 /* image2.jpg in Resources */, + 53D0803E0E5362EE008EBE62 /* image1.jpg in Resources */, + 182A8D7811D2BE9E00E156CC /* Icon-72.png in Resources */, + 182A8D7911D2BE9E00E156CC /* Icon-Small-50.png in Resources */, + 182A8D7A11D2BE9E00E156CC /* Icon-Small.png in Resources */, + 182A8D7B11D2BE9E00E156CC /* Icon-Small@2x.png in Resources */, + 182A8D7C11D2BE9E00E156CC /* Icon.png in Resources */, + 182A8D7D11D2BE9E00E156CC /* Icon@2x.png in Resources */, + 182A8D7E11D2BE9E00E156CC /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 53095FF40D9C4D1A00F143AD /* MyViewController.m in Sources */, + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53EACC050DDA319F00908D73 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53EACC060DDA319F00908D73 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = Scrolling; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = DefaultProfileUuid; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = Scrolling; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = DefaultProfileUuid; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Scrolling" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Scrolling" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Scrolling/en.lproj/MainWindow.xib b/Scrolling/en.lproj/MainWindow.xib new file mode 100644 index 0000000..fb6a840 --- /dev/null +++ b/Scrolling/en.lproj/MainWindow.xib @@ -0,0 +1,315 @@ + + + + 512 + 9E17 + 672 + 949.33 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + + 274 + + YES + + + 274 + {{20, 20}, {280, 199}} + + + 3 + MQA + + 2 + + + NO + + + + 274 + {{20, 241}, {280, 199}} + + + 3 + MQA + + + NO + + + {320, 460} + + + 1 + MC4wMTA4Njk1NjMgMC4wMTA4Njk1NjMgMC4wMTA4Njk1NjMAA + + NO + + + 2 + + + + + + YES + + + myViewController + + + + 51 + + + + window + + + + 52 + + + + delegate + + + + 53 + + + + scrollView1 + + + + 59 + + + + scrollView2 + + + + 60 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 50 + + + YES + + + + + + 54 + + + YES + + + + + + + 55 + + + + + 56 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 50.CustomClassName + 50.IBEditorWindowLastContentRect + 50.IBPluginDependency + 54.IBPluginDependency + 55.CustomClassName + 55.IBPluginDependency + 56.CustomClassName + 56.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyViewController + {{23, 514}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIScrollView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIScrollView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 60 + + + + YES + + AppDelegate + NSObject + + YES + + YES + myViewController + window + + + YES + MyViewController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + MyViewController + UIViewController + + YES + + YES + scrollView1 + scrollView2 + + + YES + UIScrollView + UIScrollView + + + + IBProjectSource + MyViewController.h + + + + + 0 + ../Scrolling.xcodeproj + 3 + + diff --git a/Scrolling/images/Icon-72.png b/Scrolling/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/Scrolling/images/Icon-72.png differ diff --git a/Scrolling/images/Icon-Small-50.png b/Scrolling/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/Scrolling/images/Icon-Small-50.png differ diff --git a/Scrolling/images/Icon-Small.png b/Scrolling/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/Scrolling/images/Icon-Small.png differ diff --git a/Scrolling/images/Icon-Small@2x.png b/Scrolling/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/Scrolling/images/Icon-Small@2x.png differ diff --git a/Scrolling/images/Icon.png b/Scrolling/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/Scrolling/images/Icon.png differ diff --git a/Scrolling/images/Icon@2x.png b/Scrolling/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/Scrolling/images/Icon@2x.png differ diff --git a/Scrolling/images/iTunesArtwork b/Scrolling/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/Scrolling/images/iTunesArtwork differ diff --git a/Scrolling/images/image0.jpg b/Scrolling/images/image0.jpg new file mode 100755 index 0000000..b1386d5 Binary files /dev/null and b/Scrolling/images/image0.jpg differ diff --git a/Scrolling/images/image1.jpg b/Scrolling/images/image1.jpg new file mode 100755 index 0000000..3a5650f Binary files /dev/null and b/Scrolling/images/image1.jpg differ diff --git a/Scrolling/images/image2.jpg b/Scrolling/images/image2.jpg new file mode 100755 index 0000000..24ae57d Binary files /dev/null and b/Scrolling/images/image2.jpg differ diff --git a/Scrolling/images/image3.jpg b/Scrolling/images/image3.jpg new file mode 100755 index 0000000..1012f9c Binary files /dev/null and b/Scrolling/images/image3.jpg differ diff --git a/Scrolling/images/image4.jpg b/Scrolling/images/image4.jpg new file mode 100755 index 0000000..c6a8bbb Binary files /dev/null and b/Scrolling/images/image4.jpg differ diff --git a/Scrolling/images/image5.jpg b/Scrolling/images/image5.jpg new file mode 100755 index 0000000..e39b3a0 Binary files /dev/null and b/Scrolling/images/image5.jpg differ diff --git a/Scrolling/main.m b/Scrolling/main.m new file mode 100755 index 0000000..3c99771 --- /dev/null +++ b/Scrolling/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/SeismicXML.zip b/SeismicXML.zip new file mode 100644 index 0000000..e573d3a Binary files /dev/null and b/SeismicXML.zip differ diff --git a/SeismicXML/Classes/Earthquake.h b/SeismicXML/Classes/Earthquake.h new file mode 100644 index 0000000..953b4e0 --- /dev/null +++ b/SeismicXML/Classes/Earthquake.h @@ -0,0 +1,74 @@ +/* + File: Earthquake.h + Abstract: The model class that stores the information about an earthquake. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface Earthquake : NSObject { +@private + // Magnitude of the earthquake on the Richter scale. + CGFloat magnitude; + // Name of the location of the earthquake. + NSString *location; + // Date and time at which the earthquake occurred. + NSDate *date; + // Holds the URL to the USGS web page of the earthquake. The application uses this URL to open that page in Safari. + NSURL *USGSWebLink; + // Latitude and longitude of the earthquake. These properties are not displayed by the application, but are used to + // create a URL for opening the Maps application. They could alternatively be used in conjuction with MapKit + // to be shown in a map view. + double latitude; + double longitude; +} + +@property (nonatomic, assign) CGFloat magnitude; +@property (nonatomic, retain) NSString *location; +@property (nonatomic, retain) NSDate *date; +@property (nonatomic, retain) NSURL *USGSWebLink; +@property (nonatomic, assign) double latitude; +@property (nonatomic, assign) double longitude; + +@end diff --git a/SeismicXML/Classes/Earthquake.m b/SeismicXML/Classes/Earthquake.m new file mode 100644 index 0000000..61ed5c4 --- /dev/null +++ b/SeismicXML/Classes/Earthquake.m @@ -0,0 +1,66 @@ +/* + File: Earthquake.m + Abstract: The model class that stores the information about an earthquake. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Earthquake.h" + +@implementation Earthquake + +@synthesize magnitude; +@synthesize location; +@synthesize date; +@synthesize USGSWebLink; +@synthesize latitude; +@synthesize longitude; + +- (void)dealloc { + [location release]; + [date release]; + [USGSWebLink release]; + [super dealloc]; +} + +@end diff --git a/SeismicXML/Classes/ParseOperation.h b/SeismicXML/Classes/ParseOperation.h new file mode 100644 index 0000000..02b4dc2 --- /dev/null +++ b/SeismicXML/Classes/ParseOperation.h @@ -0,0 +1,74 @@ +/* + File: ParseOperation.h + Abstract: The NSOperation class used to perform the XML parsing of earthquake data. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +extern NSString *kAddEarthquakesNotif; +extern NSString *kEarthquakeResultsKey; + +extern NSString *kEarthquakesErrorNotif; +extern NSString *kEarthquakesMsgErrorKey; + +@class Earthquake; + +@interface ParseOperation : NSOperation { + NSData *earthquakeData; + +@private + NSDateFormatter *dateFormatter; + + // these variables are used during parsing + Earthquake *currentEarthquakeObject; + NSMutableArray *currentParseBatch; + NSMutableString *currentParsedCharacterData; + + BOOL accumulatingParsedCharacterData; + BOOL didAbortParsing; + NSUInteger parsedEarthquakesCounter; +} + +@property (copy, readonly) NSData *earthquakeData; + +@end diff --git a/SeismicXML/Classes/ParseOperation.m b/SeismicXML/Classes/ParseOperation.m new file mode 100644 index 0000000..99d4797 --- /dev/null +++ b/SeismicXML/Classes/ParseOperation.m @@ -0,0 +1,296 @@ +/* + File: ParseOperation.m + Abstract: The NSOperation class used to perform the XML parsing of earthquake data. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ParseOperation.h" +#import "Earthquake.h" + +// NSNotification name for sending earthquake data back to the app delegate +NSString *kAddEarthquakesNotif = @"AddEarthquakesNotif"; + +// NSNotification userInfo key for obtaining the earthquake data +NSString *kEarthquakeResultsKey = @"EarthquakeResultsKey"; + +// NSNotification name for reporting errors +NSString *kEarthquakesErrorNotif = @"EarthquakeErrorNotif"; + +// NSNotification userInfo key for obtaining the error message +NSString *kEarthquakesMsgErrorKey = @"EarthquakesMsgErrorKey"; + + +@interface ParseOperation () + @property (nonatomic, retain) Earthquake *currentEarthquakeObject; + @property (nonatomic, retain) NSMutableArray *currentParseBatch; + @property (nonatomic, retain) NSMutableString *currentParsedCharacterData; +@end + +@implementation ParseOperation + +@synthesize earthquakeData, currentEarthquakeObject, currentParsedCharacterData, currentParseBatch; + +- (id)initWithData:(NSData *)parseData +{ + if (self = [super init]) { + earthquakeData = [parseData copy]; + + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; + [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"]; + } + return self; +} + +- (void)addEarthquakesToList:(NSArray *)earthquakes { + assert([NSThread isMainThread]); + + [[NSNotificationCenter defaultCenter] postNotificationName:kAddEarthquakesNotif + object:self + userInfo:[NSDictionary dictionaryWithObject:earthquakes + forKey:kEarthquakeResultsKey]]; +} + +// the main function for this NSOperation, to start the parsing +- (void)main { + self.currentParseBatch = [NSMutableArray array]; + self.currentParsedCharacterData = [NSMutableString string]; + + // It's also possible to have NSXMLParser download the data, by passing it a URL, but this is + // not desirable because it gives less control over the network, particularly in responding to + // connection errors. + // + NSXMLParser *parser = [[NSXMLParser alloc] initWithData:self.earthquakeData]; + [parser setDelegate:self]; + [parser parse]; + + // depending on the total number of earthquakes parsed, the last batch might not have been a + // "full" batch, and thus not been part of the regular batch transfer. So, we check the count of + // the array and, if necessary, send it to the main thread. + // + if ([self.currentParseBatch count] > 0) { + [self performSelectorOnMainThread:@selector(addEarthquakesToList:) + withObject:self.currentParseBatch + waitUntilDone:NO]; + } + + self.currentParseBatch = nil; + self.currentEarthquakeObject = nil; + self.currentParsedCharacterData = nil; + + [parser release]; +} + +- (void)dealloc { + [earthquakeData release]; + + [currentEarthquakeObject release]; + [currentParsedCharacterData release]; + [currentParseBatch release]; + [dateFormatter release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark Parser constants + +// Limit the number of parsed earthquakes to 50 +// (a given day may have more than 50 earthquakes around the world, so we only take the first 50) +// +static const const NSUInteger kMaximumNumberOfEarthquakesToParse = 50; + +// When an Earthquake object has been fully constructed, it must be passed to the main thread and +// the table view in RootViewController must be reloaded to display it. It is not efficient to do +// this for every Earthquake object - the overhead in communicating between the threads and reloading +// the table exceed the benefit to the user. Instead, we pass the objects in batches, sized by the +// constant below. In your application, the optimal batch size will vary +// depending on the amount of data in the object and other factors, as appropriate. +// +static NSUInteger const kSizeOfEarthquakeBatch = 10; + +// Reduce potential parsing errors by using string constants declared in a single place. +static NSString * const kEntryElementName = @"entry"; +static NSString * const kLinkElementName = @"link"; +static NSString * const kTitleElementName = @"title"; +static NSString * const kUpdatedElementName = @"updated"; +static NSString * const kGeoRSSPointElementName = @"georss:point"; + + +#pragma mark - +#pragma mark NSXMLParser delegate methods + +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName + namespaceURI:(NSString *)namespaceURI + qualifiedName:(NSString *)qName + attributes:(NSDictionary *)attributeDict { + // If the number of parsed earthquakes is greater than + // kMaximumNumberOfEarthquakesToParse, abort the parse. + // + if (parsedEarthquakesCounter >= kMaximumNumberOfEarthquakesToParse) { + // Use the flag didAbortParsing to distinguish between this deliberate stop + // and other parser errors. + // + didAbortParsing = YES; + [parser abortParsing]; + } + if ([elementName isEqualToString:kEntryElementName]) { + Earthquake *earthquake = [[Earthquake alloc] init]; + self.currentEarthquakeObject = earthquake; + [earthquake release]; + } else if ([elementName isEqualToString:kLinkElementName]) { + NSString *relAttribute = [attributeDict valueForKey:@"rel"]; + if ([relAttribute isEqualToString:@"alternate"]) { + NSString *USGSWebLink = [attributeDict valueForKey:@"href"]; + self.currentEarthquakeObject.USGSWebLink = [NSURL URLWithString:USGSWebLink]; + } + } else if ([elementName isEqualToString:kTitleElementName] || + [elementName isEqualToString:kUpdatedElementName] || + [elementName isEqualToString:kGeoRSSPointElementName]) { + // For the 'title', 'updated', or 'georss:point' element begin accumulating parsed character data. + // The contents are collected in parser:foundCharacters:. + accumulatingParsedCharacterData = YES; + // The mutable string needs to be reset to empty. + [currentParsedCharacterData setString:@""]; + } +} + +- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName + namespaceURI:(NSString *)namespaceURI + qualifiedName:(NSString *)qName { + if ([elementName isEqualToString:kEntryElementName]) { + [self.currentParseBatch addObject:self.currentEarthquakeObject]; + parsedEarthquakesCounter++; + if ([self.currentParseBatch count] >= kMaximumNumberOfEarthquakesToParse) { + [self performSelectorOnMainThread:@selector(addEarthquakesToList:) + withObject:self.currentParseBatch + waitUntilDone:NO]; + self.currentParseBatch = [NSMutableArray array]; + } + } else if ([elementName isEqualToString:kTitleElementName]) { + // The title element contains the magnitude and location in the following format: + // M 3.6, Virgin Islands region<title/> + // Extract the magnitude and the location using a scanner: + NSScanner *scanner = [NSScanner scannerWithString:self.currentParsedCharacterData]; + // Scan past the "M " before the magnitude. + if ([scanner scanString:@"M " intoString:NULL]) { + CGFloat magnitude; + if ([scanner scanFloat:&magnitude]) { + self.currentEarthquakeObject.magnitude = magnitude; + // Scan past the ", " before the title. + if ([scanner scanString:@", " intoString:NULL]) { + NSString *location = nil; + // Scan the remainer of the string. + if ([scanner scanUpToCharactersFromSet: + [NSCharacterSet illegalCharacterSet] intoString:&location]) { + self.currentEarthquakeObject.location = location; + } + } + } + } + } else if ([elementName isEqualToString:kUpdatedElementName]) { + if (self.currentEarthquakeObject != nil) { + self.currentEarthquakeObject.date = + [dateFormatter dateFromString:self.currentParsedCharacterData]; + } + else { + // kUpdatedElementName can be found outside an entry element (i.e. in the XML header) + // so don't process it here. + } + } else if ([elementName isEqualToString:kGeoRSSPointElementName]) { + // The georss:point element contains the latitude and longitude of the earthquake epicenter. + // 18.6477 -66.7452 + // + NSScanner *scanner = [NSScanner scannerWithString:self.currentParsedCharacterData]; + double latitude, longitude; + if ([scanner scanDouble:&latitude]) { + if ([scanner scanDouble:&longitude]) { + self.currentEarthquakeObject.latitude = latitude; + self.currentEarthquakeObject.longitude = longitude; + } + } + } + // Stop accumulating parsed character data. We won't start again until specific elements begin. + accumulatingParsedCharacterData = NO; +} + +// This method is called by the parser when it find parsed character data ("PCDATA") in an element. +// The parser is not guaranteed to deliver all of the parsed character data for an element in a single +// invocation, so it is necessary to accumulate character data until the end of the element is reached. +// +- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { + if (accumulatingParsedCharacterData) { + // If the current element is one whose content we care about, append 'string' + // to the property that holds the content of the current element. + // + [self.currentParsedCharacterData appendString:string]; + } +} + +// an error occurred while parsing the earthquake data, +// post the error as an NSNotification to our app delegate. +// +- (void)handleEarthquakesError:(NSError *)parseError { + [[NSNotificationCenter defaultCenter] postNotificationName:kEarthquakesErrorNotif + object:self + userInfo:[NSDictionary dictionaryWithObject:parseError + forKey:kEarthquakesMsgErrorKey]]; +} + +// an error occurred while parsing the earthquake data, +// pass the error to the main thread for handling. +// (note: don't report an error if we aborted the parse due to a max limit of earthquakes) +// +- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { + if ([parseError code] != NSXMLParserDelegateAbortedParseError && !didAbortParsing) + { + [self performSelectorOnMainThread:@selector(handleEarthquakesError:) + withObject:parseError + waitUntilDone:NO]; + } +} + +@end diff --git a/SeismicXML/Classes/RootViewController.h b/SeismicXML/Classes/RootViewController.h new file mode 100644 index 0000000..17cb146 --- /dev/null +++ b/SeismicXML/Classes/RootViewController.h @@ -0,0 +1,62 @@ +/* + File: RootViewController.h + Abstract: View controller for displaying the earthquake list. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import <UIKit/UIKit.h> + +@interface RootViewController : UITableViewController <UIActionSheetDelegate> { + NSMutableArray *earthquakeList; + + // This date formatter is used to convert NSDate objects to NSString objects, using the user's preferred formats. + NSDateFormatter *dateFormatter; +} + +@property (nonatomic, retain) NSMutableArray *earthquakeList; +@property (nonatomic, retain, readonly) NSDateFormatter *dateFormatter; + +- (void)insertEarthquakes:(NSArray *)earthquakes; // addition method of earthquakes (for KVO purposes) + +@end diff --git a/SeismicXML/Classes/RootViewController.m b/SeismicXML/Classes/RootViewController.m new file mode 100644 index 0000000..dcb9969 --- /dev/null +++ b/SeismicXML/Classes/RootViewController.m @@ -0,0 +1,256 @@ +/* + File: RootViewController.m + Abstract: View controller for displaying the earthquake list. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "Earthquake.h" + +@implementation RootViewController + +@synthesize earthquakeList; + +#pragma mark - + +- (void)dealloc { + [earthquakeList release]; + [dateFormatter release]; + + [super dealloc]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.earthquakeList = [NSMutableArray array]; + + // The table row height is not the standard value. Since all the rows have the same height, + // it is more efficient to set this property on the table, rather than using the delegate + // method -tableView:heightForRowAtIndexPath: + // + self.tableView.rowHeight = 48.0; + + // KVO: listen for changes to our earthquake data source for table view updates + [self addObserver:self forKeyPath:@"earthquakeList" options:0 context:NULL]; +} + +- (void)viewDidUnload { + [super viewDidUnload]; + + self.earthquakeList = nil; + + [self removeObserver:self forKeyPath:@"earthquakeList"]; +} + +// On-demand initializer for read-only property. +- (NSDateFormatter *)dateFormatter { + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; + } + return dateFormatter; +} + +// Based on the magnitude of the earthquake, return an image indicating its seismic strength. +- (UIImage *)imageForMagnitude:(CGFloat)magnitude { + if (magnitude >= 5.0) { + return [UIImage imageNamed:@"5.0.png"]; + } + if (magnitude >= 4.0) { + return [UIImage imageNamed:@"4.0.png"]; + } + if (magnitude >= 3.0) { + return [UIImage imageNamed:@"3.0.png"]; + } + if (magnitude >= 2.0) { + return [UIImage imageNamed:@"2.0.png"]; + } + return nil; +} + + +#pragma mark - +#pragma mark KVO support + +- (void)insertEarthquakes:(NSArray *)earthquakes +{ + // this will allow us as an observer to notified (see observeValueForKeyPath) + // so we can update our UITableView + // + [self willChangeValueForKey:@"earthquakeList"]; + [self.earthquakeList addObjectsFromArray:earthquakes]; + [self didChangeValueForKey:@"earthquakeList"]; +} + +// listen for changes to the earthquake list coming from our app delegate. +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context +{ + [self.tableView reloadData]; +} + + +#pragma mark - +#pragma mark UITableViewDelegate + +// The number of rows is equal to the number of earthquakes in the array. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [earthquakeList count]; +} + +// The cell uses a custom layout, but otherwise has standard behavior for UITableViewCell. +// In these cases, it's preferable to modify the view hierarchy of the cell's content view, rather +// than subclassing. Instead, view "tags" are used to identify specific controls, such as labels, +// image views, etc. +// +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + // Each subview in the cell will be identified by a unique tag. + static NSUInteger const kLocationLabelTag = 2; + static NSUInteger const kDateLabelTag = 3; + static NSUInteger const kMagnitudeLabelTag = 4; + static NSUInteger const kMagnitudeImageTag = 5; + + // Declare references to the subviews which will display the earthquake data. + UILabel *locationLabel = nil; + UILabel *dateLabel = nil; + UILabel *magnitudeLabel = nil; + UIImageView *magnitudeImage = nil; + + static NSString *kEarthquakeCellID = @"EarthquakeCellID"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kEarthquakeCellID]; + if (cell == nil) { + // No reusable cell was available, so we create a new cell and configure its subviews. + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:kEarthquakeCellID] autorelease]; + + locationLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 3, 190, 20)] autorelease]; + locationLabel.tag = kLocationLabelTag; + locationLabel.font = [UIFont boldSystemFontOfSize:14]; + [cell.contentView addSubview:locationLabel]; + + dateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 28, 170, 14)] autorelease]; + dateLabel.tag = kDateLabelTag; + dateLabel.font = [UIFont systemFontOfSize:10]; + [cell.contentView addSubview:dateLabel]; + + magnitudeLabel = [[[UILabel alloc] initWithFrame:CGRectMake(277, 9, 170, 29)] autorelease]; + magnitudeLabel.tag = kMagnitudeLabelTag; + magnitudeLabel.font = [UIFont boldSystemFontOfSize:24]; + magnitudeLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + [cell.contentView addSubview:magnitudeLabel]; + + magnitudeImage = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"5.0.png"]] autorelease]; + CGRect imageFrame = magnitudeImage.frame; + imageFrame.origin = CGPointMake(180, 2); + magnitudeImage.frame = imageFrame; + magnitudeImage.tag = kMagnitudeImageTag; + magnitudeImage.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + [cell.contentView addSubview:magnitudeImage]; + } else { + // A reusable cell was available, so we just need to get a reference to the subviews + // using their tags. + // + locationLabel = (UILabel *)[cell.contentView viewWithTag:kLocationLabelTag]; + dateLabel = (UILabel *)[cell.contentView viewWithTag:kDateLabelTag]; + magnitudeLabel = (UILabel *)[cell.contentView viewWithTag:kMagnitudeLabelTag]; + magnitudeImage = (UIImageView *)[cell.contentView viewWithTag:kMagnitudeImageTag]; + } + + // Get the specific earthquake for this row. + Earthquake *earthquake = [earthquakeList objectAtIndex:indexPath.row]; + + // Set the relevant data for each subview in the cell. + locationLabel.text = earthquake.location; + dateLabel.text = [NSString stringWithFormat:@"%@", [self.dateFormatter stringFromDate:earthquake.date]]; + magnitudeLabel.text = [NSString stringWithFormat:@"%.1f", earthquake.magnitude]; + magnitudeImage.image = [self imageForMagnitude:earthquake.magnitude]; + + return cell; +} + +// When the user taps a row in the table, display the USGS web page that displays details of the +// earthquake they selected. +// +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + UIActionSheet *sheet = + [[UIActionSheet alloc] initWithTitle: + NSLocalizedString(@"External App Sheet Title", + @"Title for sheet displayed with options for displaying Earthquake data in other applications") + delegate:self + cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel") + destructiveButtonTitle:nil + otherButtonTitles:NSLocalizedString(@"Show USGS Site in Safari", @"Show USGS Site in Safari"), + NSLocalizedString(@"Show Location in Maps", @"Show Location in Maps"), + nil]; + [sheet showInView:self.view]; + [sheet release]; +} + +// Called when the user selects an option in the sheet. The sheet will automatically be dismissed. +- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex { + NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; + Earthquake *earthquake = (Earthquake *)[earthquakeList objectAtIndex:selectedIndexPath.row]; + switch (buttonIndex) { + case 0: { + NSURL *webLink = [earthquake USGSWebLink]; + [[UIApplication sharedApplication] openURL:webLink]; + } break; + case 1: { + NSString *mapsQuery = + [NSString stringWithFormat:@"http://maps.google.com/maps?z=6&t=h&ll=%f,%f", + earthquake.latitude, earthquake.longitude]; + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mapsQuery]]; + } break; + default: + break; + } + [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:YES]; +} + +@end \ No newline at end of file diff --git a/SeismicXML/Classes/SeismicXMLAppDelegate.h b/SeismicXML/Classes/SeismicXMLAppDelegate.h new file mode 100644 index 0000000..f72c855 --- /dev/null +++ b/SeismicXML/Classes/SeismicXMLAppDelegate.h @@ -0,0 +1,69 @@ +/* + File: SeismicXMLAppDelegate.h + Abstract: Delegate for the application, initiates the download of the XML data and parses the Earthquake objects at launch time. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import <UIKit/UIKit.h> + +@class Earthquake, RootViewController; + +@interface SeismicXMLAppDelegate : NSObject <UIApplicationDelegate, NSXMLParserDelegate> { + UIWindow *window; + UINavigationController *navigationController; + RootViewController *rootViewController; + +@private + // for downloading the xml data + NSURLConnection *earthquakeFeedConnection; + NSMutableData *earthquakeData; + + NSOperationQueue *parseQueue; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet RootViewController *rootViewController; + +@end diff --git a/SeismicXML/Classes/SeismicXMLAppDelegate.m b/SeismicXML/Classes/SeismicXMLAppDelegate.m new file mode 100644 index 0000000..b7b5a45 --- /dev/null +++ b/SeismicXML/Classes/SeismicXMLAppDelegate.m @@ -0,0 +1,253 @@ +/* + File: SeismicXMLAppDelegate.m + Abstract: Delegate for the application, initiates the download of the XML data and parses the Earthquake objects at launch time. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SeismicXMLAppDelegate.h" +#import "RootViewController.h" +#import "Earthquake.h" +#import "ParseOperation.h" + +// this framework was imported so we could use the kCFURLErrorNotConnectedToInternet error code +#import <CFNetwork/CFNetwork.h> + + +#pragma mark SeismicXMLAppDelegate () + +// forward declarations +@interface SeismicXMLAppDelegate () + +@property (nonatomic, retain) NSURLConnection *earthquakeFeedConnection; +@property (nonatomic, retain) NSMutableData *earthquakeData; // the data returned from the NSURLConnection +@property (nonatomic, retain) NSOperationQueue *parseQueue; // the queue that manages our NSOperation for parsing earthquake data + +- (void)addEarthquakesToList:(NSArray *)earthquakes; +- (void)handleError:(NSError *)error; +@end + + +#pragma mark - +#pragma mark SeismicXMLAppDelegate + +@implementation SeismicXMLAppDelegate + +@synthesize window; +@synthesize navigationController; +@synthesize rootViewController; +@synthesize earthquakeFeedConnection; +@synthesize earthquakeData; +@synthesize parseQueue; + + +- (void)dealloc { + [earthquakeFeedConnection cancel]; + [earthquakeFeedConnection release]; + + [earthquakeData release]; + [navigationController release]; + [rootViewController release]; + [window release]; + + [parseQueue release]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:kAddEarthquakesNotif object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kEarthquakesErrorNotif object:nil]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + // Add the navigation view controller to the window. + [window addSubview:navigationController.view]; + + // Use NSURLConnection to asynchronously download the data. This means the main thread will not + // be blocked - the application will remain responsive to the user. + // + // IMPORTANT! The main thread of the application should never be blocked! + // Also, avoid synchronous network access on any thread. + // + static NSString *feedURLString = @"http://earthquake.usgs.gov/eqcenter/catalogs/7day-M2.5.xml"; + NSURLRequest *earthquakeURLRequest = + [NSURLRequest requestWithURL:[NSURL URLWithString:feedURLString]]; + self.earthquakeFeedConnection = + [[[NSURLConnection alloc] initWithRequest:earthquakeURLRequest delegate:self] autorelease]; + + // Test the validity of the connection object. The most likely reason for the connection object + // to be nil is a malformed URL, which is a programmatic error easily detected during development. + // If the URL is more dynamic, then you should implement a more flexible validation technique, + // and be able to both recover from errors and communicate problems to the user in an + // unobtrusive manner. + NSAssert(self.earthquakeFeedConnection != nil, @"Failure to create URL connection."); + + // Start the status bar network activity indicator. We'll turn it off when the connection + // finishes or experiences an error. + [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; + + parseQueue = [NSOperationQueue new]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(addEarthquakes:) + name:kAddEarthquakesNotif + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(earthquakesError:) + name:kEarthquakesErrorNotif + object:nil]; +} + + +#pragma mark - +#pragma mark NSURLConnection delegate methods + +// The following are delegate methods for NSURLConnection. Similar to callback functions, this is +// how the connection object, which is working in the background, can asynchronously communicate back +// to its delegate on the thread from which it was started - in this case, the main thread. +// +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + // check for HTTP status code for proxy authentication failures + // anything in the 200 to 299 range is considered successful, + // also make sure the MIMEType is correct: + // + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if ((([httpResponse statusCode]/100) == 2) && [[response MIMEType] isEqual:@"application/atom+xml"]) { + self.earthquakeData = [NSMutableData data]; + } else { + NSDictionary *userInfo = [NSDictionary dictionaryWithObject: + NSLocalizedString(@"HTTP Error", + @"Error message displayed when receving a connection error.") + forKey:NSLocalizedDescriptionKey]; + NSError *error = [NSError errorWithDomain:@"HTTP" code:[httpResponse statusCode] userInfo:userInfo]; + [self handleError:error]; + } +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + [earthquakeData appendData:data]; +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; + if ([error code] == kCFURLErrorNotConnectedToInternet) { + // if we can identify the error, we can present a more precise message to the user. + NSDictionary *userInfo = + [NSDictionary dictionaryWithObject: + NSLocalizedString(@"No Connection Error", + @"Error message displayed when not connected to the Internet.") + forKey:NSLocalizedDescriptionKey]; + NSError *noConnectionError = [NSError errorWithDomain:NSCocoaErrorDomain + code:kCFURLErrorNotConnectedToInternet + userInfo:userInfo]; + [self handleError:noConnectionError]; + } else { + // otherwise handle the error generically + [self handleError:error]; + } + self.earthquakeFeedConnection = nil; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + self.earthquakeFeedConnection = nil; + [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; + + // Spawn an NSOperation to parse the earthquake data so that the UI is not blocked while the + // application parses the XML data. + // + // IMPORTANT! - Don't access or affect UIKit objects on secondary threads. + // + ParseOperation *parseOperation = [[ParseOperation alloc] initWithData:self.earthquakeData]; + [self.parseQueue addOperation:parseOperation]; + [parseOperation release]; // once added to the NSOperationQueue it's retained, we don't need it anymore + + // earthquakeData will be retained by the NSOperation until it has finished executing, + // so we no longer need a reference to it in the main thread. + self.earthquakeData = nil; +} + +// Handle errors in the download by showing an alert to the user. This is a very +// simple way of handling the error, partly because this application does not have any offline +// functionality for the user. Most real applications should handle the error in a less obtrusive +// way and provide offline functionality to the user. +// +- (void)handleError:(NSError *)error { + NSString *errorMessage = [error localizedDescription]; + UIAlertView *alertView = + [[UIAlertView alloc] initWithTitle: + NSLocalizedString(@"Error Title", + @"Title for alert displayed when download or parse error occurs.") + message:errorMessage + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alertView show]; + [alertView release]; +} + +// Our NSNotification callback from the running NSOperation to add the earthquakes +// +- (void)addEarthquakes:(NSNotification *)notif { + assert([NSThread isMainThread]); + + [self addEarthquakesToList:[[notif userInfo] valueForKey:kEarthquakeResultsKey]]; +} + +// Our NSNotification callback from the running NSOperation when a parsing error has occurred +// +- (void)earthquakesError:(NSNotification *)notif { + assert([NSThread isMainThread]); + + [self handleError:[[notif userInfo] valueForKey:kEarthquakesMsgErrorKey]]; +} + +// The NSOperation "ParseOperation" calls addEarthquakes: via NSNotification, on the main thread +// which in turn calls this method, with batches of parsed objects. +// The batch size is set via the kSizeOfEarthquakeBatch constant. +// +- (void)addEarthquakesToList:(NSArray *)earthquakes { + + // insert the earthquakes into our rootViewController's data source (for KVO purposes) + [self.rootViewController insertEarthquakes:earthquakes]; +} + +@end \ No newline at end of file diff --git a/SeismicXML/Info.plist b/SeismicXML/Info.plist new file mode 100755 index 0000000..9134498 --- /dev/null +++ b/SeismicXML/Info.plist @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleDisplayName</key> + <string>${PRODUCT_NAME}</string> + <key>LSRequiresIPhoneOS</key> + <string>true</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIconFiles</key> + <array> + <string>Icon.png</string> + <string>Icon-72.png</string> + <string>Icon@2x.png</string> + <string>Icon-Small.png</string> + <string>Icon-Small-50.png</string> + <string>Icon-Small@2x.png</string> + </array> + <key>CFBundleIdentifier</key> + <string>com.apple.samplecode.${PRODUCT_NAME:identifier}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>2.1</string> + <key>NSMainNibFile</key> + <string>MainWindow</string> + <key>UIRequiresPersistentWiFi</key> + <string>true</string> +</dict> +</plist> diff --git a/SeismicXML/ReadMe.txt b/SeismicXML/ReadMe.txt new file mode 100644 index 0000000..20b1869 --- /dev/null +++ b/SeismicXML/ReadMe.txt @@ -0,0 +1,106 @@ +SeismicXML + +=========================================================================== +DESCRIPTION: + +The SeismicXML sample application demonstrates how to use NSXMLParser to parse XML data. +When you launch the application it downloads and parses an RSS feed from the United States Geological Survey (USGS) that provides data on recent earthquakes around the world. It displays the location, date, and magnitude of each earthquake, along with a color-coded graphic that indicates the severity of the earthquake. The XML parsing occurs on a background thread and updates the earthquakes table view with batches of parsed objects. + +The USGS feed is at http://earthquake.usgs.gov/eqcenter/catalogs/7day-M2.5.xml and includes all recent magnitude 2.5 and greater earthquakes world-wide, representing each earthquake with an <entry> element, in the following form: + +<entry> + <id>urn:earthquake-usgs-gov:us:2008rkbc</id> + <title>M 5.8, Banda Sea + 2008-04-29T19:10:01Z + + + + 6.102°S 127.502°E

Tuesday, April 29, 2008 19:10:01 UTC
Wednesday, April 30, 2008 04:10:01 AM at epicenter

Depth: 395.20 km (245.57 mi)

+
+ -6.1020 127.5017 + -395200 + + + +NSXMLParser is an "event-driven" parser. This means that it makes a single pass over the XML data and calls back to its delegate with "events". These events include the beginning and end of elements, parsed character data, errors, and more. In this sample, the application delegate, an instance of the "SeismicXMLAppDelegate" class, also implements the delegate methods for the parser object. In these methods, Earthquake objects are instantiated and their properties are set, according to the data provided by the parser. For some data, additional work is required - numbers extracted from strings, or date objects created from strings. + + +=========================================================================== +BUILD REQUIREMENTS + +iOS SDK 4.0 + +=========================================================================== +RUNTIME REQUIREMENTS + +iOS OS 3.2 or later + +=========================================================================== +PACKAGING LIST + +SeismicXMLAppDelegate +Delegate for the application, initiates the download of the XML data and parses the Earthquake objects at launch time. + +Earthquake +The model class that stores the information about an earthquake. + +RootViewController +A UITableViewController subclass that manages the table view. + +ParseOperation +The NSOperation class used to perform the XML parsing of earthquake data. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS + +Version 2.3 +- Now using NSOperation to perform the XML parsing, silencing any parse aborting errors. + +Version 2.1 +- Update artwork and added NSXMLParserDelegate protocol. + +Version 2.0 +- Updated for and tested with iOS 4.0 SDK. + +Version 1.9 +- Proper formatting of dates, fixed earthquake reporting URLs due to changes in USGS page, removed unused frameworks, improved error reporting, now using KVO for table view updates. + +Version 1.8 +- Added separate use of NSURLConnection to asynchronously download data instead of using NSXMLParser -initWithContentsOfURL. Upgraded for 3.0 SDK due to deprecated APIs. + +Version 1.7 +- Updated for and tested with iPhone OS 2.0. First public release. + +Version 1.6 +- Updated for GM release. +- Fixed a memory leak in SeismicXMLAppDelegate.m. + +Version 1.5 +- Updated for Beta 7. +- Fixed memory leaks in XMLReader.m. +- Now uses the SystemConfiguration framework to determine if the RSS feed provider is available and displays a message in the table view if it's not. + +Version 1.4 +- Updated for Beta 6. +- Added LSRequiresIPhoneOS key to Info.plist +- The custom table view cell add subviews to its content view rather than drawing them directly. + +Version 1.3 +- Updated for Beta 5. +- Removed the XML-to-Objective-C object mapping to simplify the sample. +- Moved the XML parsing to a background thread. + +Version 1.2 +- Updated for Beta 4. +- Now uses NSXMLParser to parse XML. +- Removed unused XML parsing classes. + +Version 1.1 +- Updated for Beta 3. +- Updated table view API. +- Add icon and replaced Default.png file. +- Removed unit tests. +- Removed unused framework. + +=========================================================================== +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/SeismicXML/SeismicXML.xcodeproj/project.pbxproj b/SeismicXML/SeismicXML.xcodeproj/project.pbxproj new file mode 100755 index 0000000..ea657f9 --- /dev/null +++ b/SeismicXML/SeismicXML.xcodeproj/project.pbxproj @@ -0,0 +1,343 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* SeismicXMLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SeismicXMLAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + 302EC8A80F9940BA00C3EF5A /* RootView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302EC8A70F9940BA00C3EF5A /* RootView.xib */; }; + 30AE758F0FAB9CA2000B9BFA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30AE758D0FAB9CA2000B9BFA /* Localizable.strings */; }; + 5374FB411202207200E10248 /* ParseOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5374FB401202207200E10248 /* ParseOperation.m */; }; + 5374FB58120221F200E10248 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 5374FB57120221F200E10248 /* iTunesArtwork */; }; + 84EF889E0DB9369300448949 /* Earthquake.m in Sources */ = {isa = PBXBuildFile; fileRef = 84EF889D0DB9369300448949 /* Earthquake.m */; }; + CB6C7BC411D4070A00AC7FA8 /* 2.0.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BB911D4070A00AC7FA8 /* 2.0.png */; }; + CB6C7BC511D4070A00AC7FA8 /* 3.0.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BBA11D4070A00AC7FA8 /* 3.0.png */; }; + CB6C7BC611D4070A00AC7FA8 /* 4.0.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BBB11D4070A00AC7FA8 /* 4.0.png */; }; + CB6C7BC711D4070A00AC7FA8 /* 5.0.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BBC11D4070A00AC7FA8 /* 5.0.png */; }; + CB6C7BC811D4070A00AC7FA8 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BBD11D4070A00AC7FA8 /* Default.png */; }; + CB6C7BC911D4070A00AC7FA8 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BBE11D4070A00AC7FA8 /* Icon-72.png */; }; + CB6C7BCA11D4070A00AC7FA8 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BBF11D4070A00AC7FA8 /* Icon-Small-50.png */; }; + CB6C7BCB11D4070A00AC7FA8 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BC011D4070A00AC7FA8 /* Icon-Small.png */; }; + CB6C7BCC11D4070A00AC7FA8 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BC111D4070A00AC7FA8 /* Icon-Small@2x.png */; }; + CB6C7BCD11D4070A00AC7FA8 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BC211D4070A00AC7FA8 /* Icon.png */; }; + CB6C7BCE11D4070A00AC7FA8 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7BC311D4070A00AC7FA8 /* Icon@2x.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* SeismicXMLAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SeismicXMLAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* SeismicXMLAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SeismicXMLAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* SeismicXML.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SeismicXML.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* SeismicXML_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SeismicXML_Prefix.pch; sourceTree = ""; }; + 28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainWindow.xib; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 302EC8A70F9940BA00C3EF5A /* RootView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = RootView.xib; path = en.lproj/RootView.xib; sourceTree = ""; }; + 30AE758E0FAB9CA2000B9BFA /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 5374FB3F1202207200E10248 /* ParseOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseOperation.h; sourceTree = ""; }; + 5374FB401202207200E10248 /* ParseOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ParseOperation.m; sourceTree = ""; }; + 5374FB57120221F200E10248 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 8480A9C70DB947D700CD87F1 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 84EF889C0DB9369300448949 /* Earthquake.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Earthquake.h; sourceTree = ""; }; + 84EF889D0DB9369300448949 /* Earthquake.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Earthquake.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CB6C7BB911D4070A00AC7FA8 /* 2.0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 2.0.png; sourceTree = ""; }; + CB6C7BBA11D4070A00AC7FA8 /* 3.0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 3.0.png; sourceTree = ""; }; + CB6C7BBB11D4070A00AC7FA8 /* 4.0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 4.0.png; sourceTree = ""; }; + CB6C7BBC11D4070A00AC7FA8 /* 5.0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 5.0.png; sourceTree = ""; }; + CB6C7BBD11D4070A00AC7FA8 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + CB6C7BBE11D4070A00AC7FA8 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + CB6C7BBF11D4070A00AC7FA8 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + CB6C7BC011D4070A00AC7FA8 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + CB6C7BC111D4070A00AC7FA8 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + CB6C7BC211D4070A00AC7FA8 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + CB6C7BC311D4070A00AC7FA8 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* SeismicXMLAppDelegate.h */, + 1D3623250D0F684500981E51 /* SeismicXMLAppDelegate.m */, + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + 84EF889C0DB9369300448949 /* Earthquake.h */, + 84EF889D0DB9369300448949 /* Earthquake.m */, + 5374FB3F1202207200E10248 /* ParseOperation.h */, + 5374FB401202207200E10248 /* ParseOperation.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SeismicXML.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 8480A9C70DB947D700CD87F1 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* SeismicXML_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + CB6C7BB811D4070A00AC7FA8 /* images */, + 28AD735F0D9D9599002E5188 /* MainWindow.xib */, + 302EC8A70F9940BA00C3EF5A /* RootView.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 30AE758D0FAB9CA2000B9BFA /* Localizable.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CB6C7BB811D4070A00AC7FA8 /* images */ = { + isa = PBXGroup; + children = ( + CB6C7BB911D4070A00AC7FA8 /* 2.0.png */, + CB6C7BBA11D4070A00AC7FA8 /* 3.0.png */, + CB6C7BBB11D4070A00AC7FA8 /* 4.0.png */, + CB6C7BBC11D4070A00AC7FA8 /* 5.0.png */, + CB6C7BBD11D4070A00AC7FA8 /* Default.png */, + CB6C7BBE11D4070A00AC7FA8 /* Icon-72.png */, + CB6C7BBF11D4070A00AC7FA8 /* Icon-Small-50.png */, + CB6C7BC011D4070A00AC7FA8 /* Icon-Small.png */, + CB6C7BC111D4070A00AC7FA8 /* Icon-Small@2x.png */, + CB6C7BC211D4070A00AC7FA8 /* Icon.png */, + CB6C7BC311D4070A00AC7FA8 /* Icon@2x.png */, + 5374FB57120221F200E10248 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SeismicXML */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SeismicXML" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SeismicXML; + productName = SeismicXML; + productReference = 1D6058910D05DD3D006BFB54 /* SeismicXML.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SeismicXML" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SeismicXML */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */, + 302EC8A80F9940BA00C3EF5A /* RootView.xib in Resources */, + 30AE758F0FAB9CA2000B9BFA /* Localizable.strings in Resources */, + CB6C7BC411D4070A00AC7FA8 /* 2.0.png in Resources */, + CB6C7BC511D4070A00AC7FA8 /* 3.0.png in Resources */, + CB6C7BC611D4070A00AC7FA8 /* 4.0.png in Resources */, + CB6C7BC711D4070A00AC7FA8 /* 5.0.png in Resources */, + CB6C7BC811D4070A00AC7FA8 /* Default.png in Resources */, + CB6C7BC911D4070A00AC7FA8 /* Icon-72.png in Resources */, + CB6C7BCA11D4070A00AC7FA8 /* Icon-Small-50.png in Resources */, + CB6C7BCB11D4070A00AC7FA8 /* Icon-Small.png in Resources */, + CB6C7BCC11D4070A00AC7FA8 /* Icon-Small@2x.png in Resources */, + CB6C7BCD11D4070A00AC7FA8 /* Icon.png in Resources */, + CB6C7BCE11D4070A00AC7FA8 /* Icon@2x.png in Resources */, + 5374FB58120221F200E10248 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* SeismicXMLAppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + 84EF889E0DB9369300448949 /* Earthquake.m in Sources */, + 5374FB411202207200E10248 /* ParseOperation.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 30AE758D0FAB9CA2000B9BFA /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 30AE758E0FAB9CA2000B9BFA /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SeismicXML_Prefix.pch; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = SeismicXML; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SeismicXML_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = SeismicXML; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + STRIP_INSTALLED_PRODUCT = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SeismicXML" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SeismicXML" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/SeismicXML/SeismicXML_Prefix.pch b/SeismicXML/SeismicXML_Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/SeismicXML/SeismicXML_Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/SeismicXML/en.lproj/Localizable.strings b/SeismicXML/en.lproj/Localizable.strings new file mode 100644 index 0000000..43baf62 Binary files /dev/null and b/SeismicXML/en.lproj/Localizable.strings differ diff --git a/SeismicXML/en.lproj/MainWindow.xib b/SeismicXML/en.lproj/MainWindow.xib new file mode 100644 index 0000000..9aeee7b --- /dev/null +++ b/SeismicXML/en.lproj/MainWindow.xib @@ -0,0 +1,280 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + Earthquakes + + + RootView + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 13 + + + + rootViewController + + + + 14 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 10 + + + YES + + + + + + 11 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{571, 426}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SeismicXMLAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{416, 665}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 14 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + SeismicXMLAppDelegate + NSObject + + YES + + YES + navigationController + rootViewController + window + + + YES + UINavigationController + RootViewController + UIWindow + + + + IBProjectSource + Classes/SeismicXMLAppDelegate.h + + + + + 0 + ../SeismicXML.xcodeproj + 3 + + diff --git a/SeismicXML/en.lproj/RootView.xib b/SeismicXML/en.lproj/RootView.xib new file mode 100644 index 0000000..c33a8ba --- /dev/null +++ b/SeismicXML/en.lproj/RootView.xib @@ -0,0 +1,164 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + {{554, 98}, {320, 247}} + + 3 + MQA + + NO + YES + NO + NO + 1 + 0 + YES + 4.400000e+01 + 2.200000e+01 + 2.200000e+01 + + + + + YES + + + view + + + + 4 + + + + dataSource + + + + 5 + + + + delegate + + + + 6 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 3 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 3.IBPluginDependency + + + YES + RootViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 6 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + + 0 + SeismicXML.xcodeproj + 3 + + diff --git a/SeismicXML/images/2.0.png b/SeismicXML/images/2.0.png new file mode 100644 index 0000000..d9e15ab Binary files /dev/null and b/SeismicXML/images/2.0.png differ diff --git a/SeismicXML/images/3.0.png b/SeismicXML/images/3.0.png new file mode 100644 index 0000000..62b08ec Binary files /dev/null and b/SeismicXML/images/3.0.png differ diff --git a/SeismicXML/images/4.0.png b/SeismicXML/images/4.0.png new file mode 100644 index 0000000..e891fc1 Binary files /dev/null and b/SeismicXML/images/4.0.png differ diff --git a/SeismicXML/images/5.0.png b/SeismicXML/images/5.0.png new file mode 100644 index 0000000..3626297 Binary files /dev/null and b/SeismicXML/images/5.0.png differ diff --git a/SeismicXML/images/Default.png b/SeismicXML/images/Default.png new file mode 100644 index 0000000..614f229 Binary files /dev/null and b/SeismicXML/images/Default.png differ diff --git a/SeismicXML/images/Icon-72.png b/SeismicXML/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/SeismicXML/images/Icon-72.png differ diff --git a/SeismicXML/images/Icon-Small-50.png b/SeismicXML/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/SeismicXML/images/Icon-Small-50.png differ diff --git a/SeismicXML/images/Icon-Small.png b/SeismicXML/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/SeismicXML/images/Icon-Small.png differ diff --git a/SeismicXML/images/Icon-Small@2x.png b/SeismicXML/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/SeismicXML/images/Icon-Small@2x.png differ diff --git a/SeismicXML/images/Icon.png b/SeismicXML/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/SeismicXML/images/Icon.png differ diff --git a/SeismicXML/images/Icon@2x.png b/SeismicXML/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/SeismicXML/images/Icon@2x.png differ diff --git a/SeismicXML/images/iTunesArtwork b/SeismicXML/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/SeismicXML/images/iTunesArtwork differ diff --git a/SeismicXML/main.m b/SeismicXML/main.m new file mode 100755 index 0000000..218779b --- /dev/null +++ b/SeismicXML/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Template main function. + Version: 2.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/SimpleEKDemo.zip b/SimpleEKDemo.zip new file mode 100644 index 0000000..43e7516 Binary files /dev/null and b/SimpleEKDemo.zip differ diff --git a/SimpleEKDemo/Classes/RootViewController.h b/SimpleEKDemo/Classes/RootViewController.h new file mode 100644 index 0000000..095a81b --- /dev/null +++ b/SimpleEKDemo/Classes/RootViewController.h @@ -0,0 +1,71 @@ +/* + File: RootViewController.h + Abstract: Table view controller used to display the events associated with the default calendar. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +#import +#import +#import + +@interface RootViewController : UITableViewController { + + EKEventViewController *detailViewController; + EKEventStore *eventStore; + EKCalendar *defaultCalendar; + NSMutableArray *eventsList; +} + +@property (nonatomic, retain) EKEventStore *eventStore; +@property (nonatomic, retain) EKCalendar *defaultCalendar; +@property (nonatomic, retain) NSMutableArray *eventsList; +@property (nonatomic, retain) EKEventViewController *detailViewController; + +- (NSArray *) fetchEventsForToday; +- (IBAction) addEvent:(id)sender; + +@end diff --git a/SimpleEKDemo/Classes/RootViewController.m b/SimpleEKDemo/Classes/RootViewController.m new file mode 100644 index 0000000..039bfeb --- /dev/null +++ b/SimpleEKDemo/Classes/RootViewController.m @@ -0,0 +1,281 @@ +/* + File: RootViewController.m + Abstract: Table view controller used to display the events associated with the default calendar. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +#import "RootViewController.h" + +@implementation RootViewController + +@synthesize eventsList, eventStore, defaultCalendar, detailViewController; + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [eventStore release]; + [eventsList release]; + [defaultCalendar release]; + [detailViewController release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewDidLoad { + self.title = @"Events List"; + + // Initialize an event store object with the init method. Initilize the array for events. + self.eventStore = [[EKEventStore alloc] init]; + + self.eventsList = [[NSMutableArray alloc] initWithArray:0]; + + // Get the default calendar from store. + self.defaultCalendar = [self.eventStore defaultCalendarForNewEvents]; + + // Create an Add button + UIBarButtonItem *addButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: + UIBarButtonSystemItemAdd target:self action:@selector(addEvent:)]; + self.navigationItem.rightBarButtonItem = addButtonItem; + [addButtonItem release]; + + + self.navigationController.delegate = self; + + // Fetch today's event on selected calendar and put them into the eventsList array + [self.eventsList addObjectsFromArray:[self fetchEventsForToday]]; + + [self.tableView reloadData]; + +} + + +- (void)viewDidUnload { + self.eventsList = nil; +} + + +- (void)viewWillAppear:(BOOL)animated { + [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:NO]; +} + + +// Support all orientations except for Portrait Upside-down. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); +} + + +#pragma mark - +#pragma mark Table view data source + +// Fetching events happening in the next 24 hours with a predicate, limiting to the default calendar +- (NSArray *)fetchEventsForToday { + + NSDate *startDate = [NSDate date]; + + // endDate is 1 day = 60*60*24 seconds = 86400 seconds from startDate + NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:86400]; + + // Create the predicate. Pass it the default calendar. + NSArray *calendarArray = [NSArray arrayWithObject:defaultCalendar]; + NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate + calendars:calendarArray]; + + // Fetch all events that match the predicate. + NSArray *events = [self.eventStore eventsMatchingPredicate:predicate]; + + return events; +} + + +#pragma mark - +#pragma mark Table View + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return eventsList.count; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + // Add disclosure triangle to cell + UITableViewCellAccessoryType editableCellAccessoryType =UITableViewCellAccessoryDisclosureIndicator; + + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:CellIdentifier] autorelease]; + } + + cell.accessoryType = editableCellAccessoryType; + + // Get the event at the row selected and display it's title + cell.textLabel.text = [[self.eventsList objectAtIndex:indexPath.row] title]; + + return cell; +} + + +#pragma mark - +#pragma mark Table view delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // Upon selecting an event, create an EKEventViewController to display the event. + self.detailViewController = [[EKEventViewController alloc] initWithNibName:nil bundle:nil]; + detailViewController.event = [self.eventsList objectAtIndex:indexPath.row]; + + // Allow event editing. + detailViewController.allowsEditing = YES; + + // Push detailViewController onto the navigation controller stack + // If the underlying event gets deleted, detailViewController will remove itself from + // the stack and clear its event property. + [self.navigationController pushViewController:detailViewController animated:YES]; + +} + + +#pragma mark - +#pragma mark Navigation Controller delegate + +- (void)navigationController:(UINavigationController *)navigationController + willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { + // if we are navigating back to the rootViewController, and the detailViewController's event + // has been deleted - will title being NULL, then remove the events from the eventsList + // and reload the table view. This takes care of reloading the table view after adding an event too. + if (viewController == self && self.detailViewController.event.title == NULL) { + [self.eventsList removeObject:self.detailViewController.event]; + [self.tableView reloadData]; + } +} + + +#pragma mark - +#pragma mark Add a new event + +// If event is nil, a new event is created and added to the specified event store. New events are +// added to the default calendar. An exception is raised if set to an event that is not in the +// specified event store. +- (void)addEvent:(id)sender { + // When add button is pushed, create an EKEventEditViewController to display the event. + EKEventEditViewController *addController = [[EKEventEditViewController alloc] initWithNibName:nil bundle:nil]; + + // set the addController's event store to the current event store. + addController.eventStore = self.eventStore; + + // present EventsAddViewController as a modal view controller + [self presentModalViewController:addController animated:YES]; + + addController.editViewDelegate = self; + [addController release]; +} + + +#pragma mark - +#pragma mark EKEventEditViewDelegate + +// Overriding EKEventEditViewDelegate method to update event store according to user actions. +- (void)eventEditViewController:(EKEventEditViewController *)controller + didCompleteWithAction:(EKEventEditViewAction)action { + + NSError *error = nil; + EKEvent *thisEvent = controller.event; + + switch (action) { + case EKEventEditViewActionCanceled: + // Edit action canceled, do nothing. + break; + + case EKEventEditViewActionSaved: + // When user hit "Done" button, save the newly created event to the event store, + // and reload table view. + // If the new event is being added to the default calendar, then update its + // eventsList. + if (self.defaultCalendar == thisEvent.calendar) { + [self.eventsList addObject:thisEvent]; + } + [controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error]; + [self.tableView reloadData]; + break; + + case EKEventEditViewActionDeleted: + // When deleting an event, remove the event from the event store, + // and reload table view. + // If deleting an event from the currenly default calendar, then update its + // eventsList. + if (self.defaultCalendar == thisEvent.calendar) { + [self.eventsList removeObject:thisEvent]; + } + [controller.eventStore removeEvent:thisEvent span:EKSpanThisEvent error:&error]; + [self.tableView reloadData]; + break; + + default: + break; + } + // Dismiss the modal view controller + [controller dismissModalViewControllerAnimated:YES]; + +} + + +// Set the calendar edited by EKEventEditViewController to our chosen calendar - the default calendar. +- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller { + EKCalendar *calendarForEdit = self.defaultCalendar; + return calendarForEdit; +} + + +@end \ No newline at end of file diff --git a/SimpleEKDemo/Classes/SimpleEKDemoAppDelegate.h b/SimpleEKDemo/Classes/SimpleEKDemoAppDelegate.h new file mode 100644 index 0000000..c3e643d --- /dev/null +++ b/SimpleEKDemo/Classes/SimpleEKDemoAppDelegate.h @@ -0,0 +1,62 @@ +/* + File: SimpleEKDemoAppDelegate.h + Abstract: Application delegate that sets up a tab bar controller with a root view controller -- a navigation controller that in turn loads a table view controller to manage a list of calendars. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface SimpleEKDemoAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +@end + diff --git a/SimpleEKDemo/Classes/SimpleEKDemoAppDelegate.m b/SimpleEKDemo/Classes/SimpleEKDemoAppDelegate.m new file mode 100644 index 0000000..748aff5 --- /dev/null +++ b/SimpleEKDemo/Classes/SimpleEKDemoAppDelegate.m @@ -0,0 +1,79 @@ +/* + File: SimpleEKDemoAppDelegate.m + Abstract: Application delegate that sets up a tab bar controller with a root view controller -- a navigation controller that in turn loads a table view controller to manage a list of calendars. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SimpleEKDemoAppDelegate.h" +#import "RootViewController.h" + + +@implementation SimpleEKDemoAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)applicationlaunchOptions { + [window addSubview:navigationController.view]; + [window makeKeyAndVisible]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/SimpleEKDemo/Default.png b/SimpleEKDemo/Default.png new file mode 100644 index 0000000..134d04a Binary files /dev/null and b/SimpleEKDemo/Default.png differ diff --git a/SimpleEKDemo/Images/Icon-72.png b/SimpleEKDemo/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/SimpleEKDemo/Images/Icon-72.png differ diff --git a/SimpleEKDemo/Images/Icon-Small-50.png b/SimpleEKDemo/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/SimpleEKDemo/Images/Icon-Small-50.png differ diff --git a/SimpleEKDemo/Images/Icon-Small.png b/SimpleEKDemo/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/SimpleEKDemo/Images/Icon-Small.png differ diff --git a/SimpleEKDemo/Images/Icon-Small@2x.png b/SimpleEKDemo/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/SimpleEKDemo/Images/Icon-Small@2x.png differ diff --git a/SimpleEKDemo/Images/Icon.png b/SimpleEKDemo/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/SimpleEKDemo/Images/Icon.png differ diff --git a/SimpleEKDemo/Images/Icon@2x.png b/SimpleEKDemo/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/SimpleEKDemo/Images/Icon@2x.png differ diff --git a/SimpleEKDemo/Images/iTunesArtwork b/SimpleEKDemo/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/SimpleEKDemo/Images/iTunesArtwork differ diff --git a/SimpleEKDemo/ReadMe.txt b/SimpleEKDemo/ReadMe.txt new file mode 100644 index 0000000..56a5b88 --- /dev/null +++ b/SimpleEKDemo/ReadMe.txt @@ -0,0 +1,51 @@ +### SimpleEKDemo ### + +================================================================================ +DESCRIPTION: + +This sample shows how to use EventKit and EventKitUI frameworks to access and edit calendar data in the Calendar database. + +The application uses table views to display EKEvent objects retrieved from an EKEventStore object. It implements EKEventViewController for viewing and editing existing EKEvents, and uses EKEventEditViewController for creating new EKEvents. + +Amongst the techniques shown are how to: +* Create and initialize an event store object. +* Create a predicate, or a search query for the Calendar database. +* Override EKEventEditViewDelegate method to respond to editing events. +* Access event store, calendar and event properties. + +================================================================================ +BUILD REQUIREMENTS: + +Mac OS X v10.6 or later; Xcode 3.1.3 or later; iPhone OS 4.0. + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 4.0. + +================================================================================ +PACKAGING LIST: + +Application Configuration +------------------------- + +SimpleEKDemoAppDelegate.{h,m} +MainWindow.xib +Application delegate that sets up a tab bar controller with a root view controller -- a navigation controller that in turn loads a table view controller to manage a list of calendars. + + +View Controllers +------------------------ + +RootViewController.{h,m} +RootViewController.xib +Table view controller that manages a table view displaying a list of events fetched from the default calendar. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.0 +- First version. + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/SimpleEKDemo/SimpleEKDemo-Info.plist b/SimpleEKDemo/SimpleEKDemo-Info.plist new file mode 100644 index 0000000..5c65286 --- /dev/null +++ b/SimpleEKDemo/SimpleEKDemo-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/SimpleEKDemo/SimpleEKDemo.xcodeproj/llei.mode1v3 b/SimpleEKDemo/SimpleEKDemo.xcodeproj/llei.mode1v3 new file mode 100644 index 0000000..8bb48bf --- /dev/null +++ b/SimpleEKDemo/SimpleEKDemo.xcodeproj/llei.mode1v3 @@ -0,0 +1,1397 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Applications/Xcode 3.2.4/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 7E8EDD661191D4B10073914C + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 169 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 8 + 4 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {169, 730}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {186, 748}} + GroupTreeTableConfiguration + + MainColumn + 169 + + RubberWindowFrame + 227 89 974 789 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 186pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + SimpleEKDemo-Info.plist + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + SimpleEKDemo-Info.plist + _historyCapacity + 0 + bookmark + 7E19D40D11D189CE000002E9 + history + + 7E8EEA7A1195EEE90073914C + 7E8EEA7C1195EEE90073914C + 7E8EEA7E1195EEE90073914C + 7EF4D87411B707B500CB9276 + 7EF4D87511B707B500CB9276 + 7EABE48611D150440050EA1D + 7EABE48711D150440050EA1D + 7EABE48811D150440050EA1D + 7EABE4C111D1541B0050EA1D + 7EABE4C211D1541B0050EA1D + 7E19D40B11D189CE000002E9 + 7E19D40C11D189CE000002E9 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {783, 478}} + RubberWindowFrame + 227 89 974 789 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 478pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 483}, {783, 265}} + RubberWindowFrame + 227 89 974 789 0 0 1440 878 + + Module + XCDetailModule + Proportion + 265pt + + + Proportion + 783pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 7E19D40E11D189CE000002E9 + 1CE0B1FE06471DED0097A5F4 + 7E19D40F11D189CE000002E9 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Applications/Xcode 3.2.4/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 7E8EDD671191D4B10073914C + /Users/llei/Desktop/Samples/SimpleEKDemoS/SimpleEKDemo/SimpleEKDemo/SimpleEKDemo.xcodeproj + + WindowString + 227 89 974 789 0 0 1440 878 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {697, 509}} + RubberWindowFrame + 32 134 697 703 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 509pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 514}, {697, 148}} + RubberWindowFrame + 32 134 697 703 0 0 1440 878 + + Module + PBXBuildResultsModule + Proportion + 148pt + + + Proportion + 662pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 7E8EDD671191D4B10073914C + 7E19D41011D189CE000002E9 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 32 134 697 703 0 0 1440 878 + WindowToolGUID + 7E8EDD671191D4B10073914C + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {402, 292}} + {{402, 0}, {483, 292}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {885, 292}} + {{0, 292}, {885, 255}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {885, 547}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 179 + Value + 85 + Summary + 194 + + Frame + {{402, 0}, {483, 292}} + RubberWindowFrame + 68 290 885 588 0 0 1440 878 + + RubberWindowFrame + 68 290 885 588 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 547pt + + + Proportion + 547pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 7EABE48C11D150440050EA1D + 1C162984064C10D400B95A72 + 7EABE48D11D150440050EA1D + 7EABE48E11D150440050EA1D + 7EABE48F11D150440050EA1D + 7EABE49011D150440050EA1D + 7EABE49111D150440050EA1D + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 68 290 885 588 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {781, 212}} + RubberWindowFrame + 388 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 212pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 217}, {781, 212}} + RubberWindowFrame + 388 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 429pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 7EF46E4411B6E8D100DAECEE + 7EF46E4511B6E8D100DAECEE + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 388 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {597, 565}} + RubberWindowFrame + 594 193 597 606 0 0 1440 878 + + Module + PBXDebugCLIModule + Proportion + 565pt + + + Proportion + 565pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 7EABE49211D150440050EA1D + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 594 193 597 606 0 0 1440 878 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/SimpleEKDemo/SimpleEKDemo.xcodeproj/project.pbxproj b/SimpleEKDemo/SimpleEKDemo.xcodeproj/project.pbxproj new file mode 100755 index 0000000..1098ee9 --- /dev/null +++ b/SimpleEKDemo/SimpleEKDemo.xcodeproj/project.pbxproj @@ -0,0 +1,329 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + 7E19D41311D189F4000002E9 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 7E19D41211D189F4000002E9 /* iTunesArtwork */; }; + 7E4A142A11ADA0AA004BA0B1 /* EventKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E4A142911ADA0AA004BA0B1 /* EventKit.framework */; }; + 7E4A142C11ADA0B1004BA0B1 /* EventKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E4A142B11ADA0B1004BA0B1 /* EventKitUI.framework */; }; + 7E8EE7E41194B0D70073914C /* SimpleEKDemoAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8EE7E21194B0D70073914C /* SimpleEKDemoAppDelegate.m */; }; + 7E8EEA9B1195EFF40073914C /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7E8EEA9A1195EFF40073914C /* ReadMe.txt */; }; + 7E8EEAC41195F67A0073914C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8EEAC31195F67A0073914C /* Default.png */; }; + 7E8EEB0E119750B70073914C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7E8EEB09119750B70073914C /* MainWindow.xib */; }; + 7E8EEB0F119750B70073914C /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7E8EEB0B119750B70073914C /* RootViewController.xib */; }; + 7EABE47C11D14FF80050EA1D /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EABE47711D14FF80050EA1D /* Icon-Small.png */; }; + 7EABE47D11D14FF80050EA1D /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EABE47811D14FF80050EA1D /* Icon-Small@2x.png */; }; + 7EABE47E11D14FF80050EA1D /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EABE47911D14FF80050EA1D /* Icon.png */; }; + 7EABE47F11D14FF80050EA1D /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EABE47A11D14FF80050EA1D /* Icon@2x.png */; }; + 7EABE4CB11D154BD0050EA1D /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EABE4CA11D154BD0050EA1D /* Icon-72.png */; }; + 7EABE4D611D1553D0050EA1D /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EABE4D511D1553D0050EA1D /* Icon-Small-50.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* SimpleEKDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleEKDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* SimpleEKDemo_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleEKDemo_Prefix.pch; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 7E19D41211D189F4000002E9 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; + 7E4A142911ADA0AA004BA0B1 /* EventKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKit.framework; path = System/Library/Frameworks/EventKit.framework; sourceTree = SDKROOT; }; + 7E4A142B11ADA0B1004BA0B1 /* EventKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKitUI.framework; path = System/Library/Frameworks/EventKitUI.framework; sourceTree = SDKROOT; }; + 7E8EE7E21194B0D70073914C /* SimpleEKDemoAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SimpleEKDemoAppDelegate.m; path = Classes/SimpleEKDemoAppDelegate.m; sourceTree = SOURCE_ROOT; }; + 7E8EE7E31194B0D70073914C /* SimpleEKDemoAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SimpleEKDemoAppDelegate.h; path = Classes/SimpleEKDemoAppDelegate.h; sourceTree = SOURCE_ROOT; }; + 7E8EEA9A1195EFF40073914C /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = SOURCE_ROOT; }; + 7E8EEAC31195F67A0073914C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = SOURCE_ROOT; }; + 7E8EEB0A119750B70073914C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 7E8EEB0C119750B70073914C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; + 7EABE47711D14FF80050EA1D /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + 7EABE47811D14FF80050EA1D /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + 7EABE47911D14FF80050EA1D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + 7EABE47A11D14FF80050EA1D /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + 7EABE4CA11D154BD0050EA1D /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + 7EABE4D511D1553D0050EA1D /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* SimpleEKDemo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SimpleEKDemo-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + 7E4A142A11ADA0AA004BA0B1 /* EventKit.framework in Frameworks */, + 7E4A142C11ADA0B1004BA0B1 /* EventKitUI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 7E8EE7E31194B0D70073914C /* SimpleEKDemoAppDelegate.h */, + 7E8EE7E21194B0D70073914C /* SimpleEKDemoAppDelegate.m */, + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SimpleEKDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 7E8EEA9A1195EFF40073914C /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* SimpleEKDemo_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 7E8EEB09119750B70073914C /* MainWindow.xib */, + 7E8EEB0B119750B70073914C /* RootViewController.xib */, + 7E8EEABD1195F60F0073914C /* Images */, + 8D1107310486CEB800E47090 /* SimpleEKDemo-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7E4A142B11ADA0B1004BA0B1 /* EventKitUI.framework */, + 7E4A142911ADA0AA004BA0B1 /* EventKit.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7E8EEABD1195F60F0073914C /* Images */ = { + isa = PBXGroup; + children = ( + 7E19D41211D189F4000002E9 /* iTunesArtwork */, + 7EABE4D511D1553D0050EA1D /* Icon-Small-50.png */, + 7EABE4CA11D154BD0050EA1D /* Icon-72.png */, + 7EABE47711D14FF80050EA1D /* Icon-Small.png */, + 7EABE47811D14FF80050EA1D /* Icon-Small@2x.png */, + 7EABE47911D14FF80050EA1D /* Icon.png */, + 7EABE47A11D14FF80050EA1D /* Icon@2x.png */, + 7E8EEAC31195F67A0073914C /* Default.png */, + ); + name = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SimpleEKDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleEKDemo" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SimpleEKDemo; + productName = SimpleEKDemo; + productReference = 1D6058910D05DD3D006BFB54 /* SimpleEKDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleEKDemo" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SimpleEKDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7E8EEA9B1195EFF40073914C /* ReadMe.txt in Resources */, + 7E8EEAC41195F67A0073914C /* Default.png in Resources */, + 7E8EEB0E119750B70073914C /* MainWindow.xib in Resources */, + 7E8EEB0F119750B70073914C /* RootViewController.xib in Resources */, + 7EABE47C11D14FF80050EA1D /* Icon-Small.png in Resources */, + 7EABE47D11D14FF80050EA1D /* Icon-Small@2x.png in Resources */, + 7EABE47E11D14FF80050EA1D /* Icon.png in Resources */, + 7EABE47F11D14FF80050EA1D /* Icon@2x.png in Resources */, + 7EABE4CB11D154BD0050EA1D /* Icon-72.png in Resources */, + 7EABE4D611D1553D0050EA1D /* Icon-Small-50.png in Resources */, + 7E19D41311D189F4000002E9 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + 7E8EE7E41194B0D70073914C /* SimpleEKDemoAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 7E8EEB09119750B70073914C /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 7E8EEB0A119750B70073914C /* en */, + ); + name = MainWindow.xib; + sourceTree = SOURCE_ROOT; + }; + 7E8EEB0B119750B70073914C /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 7E8EEB0C119750B70073914C /* en */, + ); + name = RootViewController.xib; + sourceTree = SOURCE_ROOT; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleEKDemo_Prefix.pch; + INFOPLIST_FILE = "SimpleEKDemo-Info.plist"; + PRODUCT_NAME = SimpleEKDemo; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleEKDemo_Prefix.pch; + INFOPLIST_FILE = "SimpleEKDemo-Info.plist"; + PRODUCT_NAME = SimpleEKDemo; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleEKDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleEKDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/SimpleEKDemo/SimpleEKDemo_Prefix.pch b/SimpleEKDemo/SimpleEKDemo_Prefix.pch new file mode 100644 index 0000000..c4f20f7 --- /dev/null +++ b/SimpleEKDemo/SimpleEKDemo_Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'SimpleEKDemo' target in the 'SimpleEKDemo' project +// +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/SimpleEKDemo/en.lproj/MainWindow.xib b/SimpleEKDemo/en.lproj/MainWindow.xib new file mode 100644 index 0000000..6ae3e86 --- /dev/null +++ b/SimpleEKDemo/en.lproj/MainWindow.xib @@ -0,0 +1,560 @@ + + + + 1024 + 10D573 + 789 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 116 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + IBCocoaTouchFramework + YES + YES + + + + + 1 + + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + NO + YES + YES + IBCocoaTouchFramework + + + YES + + + IBCocoaTouchFramework + + + RootViewController + + + 1 + + IBCocoaTouchFramework + NO + + + + + + + YES + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + rootViewController + + + + 20 + + + + delegate + + + + 21 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SimpleEKDemoAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{186, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 21 + + + + YES + + RootViewController + UITableViewController + + addEvent: + id + + + addEvent: + + addEvent: + id + + + + IBProjectSource + Classes/RootViewController.h + + + + SimpleEKDemoAppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + YES + + YES + navigationController + window + + + YES + + navigationController + UINavigationController + + + window + UIWindow + + + + + IBProjectSource + Classes/SimpleEKDemoAppDelegate.h + + + + UIWindow + UIView + + IBUserSource + + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../SimpleEKDemo.xcodeproj + 3 + 116 + + diff --git a/SimpleEKDemo/en.lproj/RootViewController.xib b/SimpleEKDemo/en.lproj/RootViewController.xib new file mode 100644 index 0000000..45bb63e --- /dev/null +++ b/SimpleEKDemo/en.lproj/RootViewController.xib @@ -0,0 +1,390 @@ + + + + 1024 + 10D573 + 786 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 112 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {320, 460} + + 3 + MQA + + NO + YES + NO + IBCocoaTouchFramework + NO + 1 + 0 + YES + 44 + 22 + 22 + + + + + YES + + + dataSource + + + + 22 + + + + delegate + + + + 23 + + + + view + + + + 24 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + + + YES + RootViewController + UIResponder + {{144, 396}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 24 + + + + YES + + RootViewController + UITableViewController + + addEvent: + id + + + addEvent: + + addEvent: + id + + + + eventsTableView + UITableView + + + eventsTableView + + eventsTableView + UITableView + + + + IBProjectSource + Classes/RootViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../SimpleEKDemo.xcodeproj + 3 + 112 + + diff --git a/SimpleEKDemo/main.m b/SimpleEKDemo/main.m new file mode 100644 index 0000000..7b153e5 --- /dev/null +++ b/SimpleEKDemo/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: Main file for the application. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/SimpleUndo.zip b/SimpleUndo.zip new file mode 100644 index 0000000..ff46c0f Binary files /dev/null and b/SimpleUndo.zip differ diff --git a/SimpleUndo/Classes/Book.h b/SimpleUndo/Classes/Book.h new file mode 100644 index 0000000..2850da4 --- /dev/null +++ b/SimpleUndo/Classes/Book.h @@ -0,0 +1,59 @@ + +/* + File: Book.h + Abstract: Simple class to represent a book. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface Book : NSObject { + NSString *title; + NSString *author; + NSDate *copyright; +} + +@property (nonatomic, retain) NSString * title; +@property (nonatomic, retain) NSString * author; +@property (nonatomic, retain) NSDate * copyright; + +@end diff --git a/SimpleUndo/Classes/Book.m b/SimpleUndo/Classes/Book.m new file mode 100644 index 0000000..0ac2748 --- /dev/null +++ b/SimpleUndo/Classes/Book.m @@ -0,0 +1,62 @@ + +/* + File: Book.m + Abstract: Simple class to represent a book. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Book.h" + +@implementation Book + +@synthesize title, author, copyright; + +- (void)dealloc { + [title release]; + [author release]; + [copyright release]; + [super dealloc]; +} + +@end diff --git a/SimpleUndo/Classes/EditingViewController.h b/SimpleUndo/Classes/EditingViewController.h new file mode 100755 index 0000000..6449951 --- /dev/null +++ b/SimpleUndo/Classes/EditingViewController.h @@ -0,0 +1,93 @@ + +/* + File: EditingViewController.h + Abstract: A generic table view controller responsible for editing a field of data (text or date). + The controller defines a protocol to communicate changes to the view controller that manages the object being edited. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +/* + Protocol to define communication between editing view controller and the view controller that configured it. + */ +@protocol PropertyEditing +- (void)setValue:(id)newValue forEditedProperty:(NSString *)field; +@end + + +@interface EditingViewController : UIViewController { + + UITextField *textField; + UIDatePicker *datePicker; + + id editedObject; + NSString *editedPropertyKey; + NSString *editedPropertyDisplayName; + + BOOL editingDate; + + id sourceController; +} + +@property (nonatomic, retain) IBOutlet UITextField *textField; +@property (nonatomic, retain) IBOutlet UIDatePicker *datePicker; + +/* + Aspects of the object being edited: + The object itself, the name of the property being edited, and the name to display to the user. + */ +@property (nonatomic, retain) id editedObject; +@property (nonatomic, retain) NSString *editedPropertyKey; +@property (nonatomic, retain) NSString *editedPropertyDisplayName; + +@property (nonatomic, assign, getter=isEditingDate) BOOL editingDate; + +@property (nonatomic, retain) id sourceController; + +- (IBAction)cancel; +- (IBAction)save; + +@end + diff --git a/SimpleUndo/Classes/EditingViewController.m b/SimpleUndo/Classes/EditingViewController.m new file mode 100755 index 0000000..7d391b5 --- /dev/null +++ b/SimpleUndo/Classes/EditingViewController.m @@ -0,0 +1,135 @@ + +/* + File: EditingViewController.m + Abstract: A generic table view controller responsible for editing a field of data (text or date). + The controller defines a protocol to communicate changes to the view controller that manages the object being edited. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "EditingViewController.h" +#import "RootViewController.h" + +@implementation EditingViewController + +@synthesize textField, editedObject, editedPropertyKey, editedPropertyDisplayName, editingDate, datePicker, sourceController; + + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewDidLoad { + // Set the title to the user-visible name of the field. + self.title = editedPropertyDisplayName; + + // Configure the save and cancel buttons. + UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save)]; + self.navigationItem.rightBarButtonItem = saveButton; + [saveButton release]; + + UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; + self.navigationItem.leftBarButtonItem = cancelButton; + [cancelButton release]; +} + + +- (void)viewWillAppear:(BOOL)animated { + + [super viewWillAppear:animated]; + + // Update user interface according to state. + if (editingDate) { + textField.hidden = YES; + datePicker.hidden = NO; + NSDate *date = [editedObject valueForKey:editedPropertyKey]; + if (date == nil) date = [NSDate date]; + datePicker.date = date; + } + else { + textField.hidden = NO; + datePicker.hidden = YES; + textField.text = [editedObject valueForKey:editedPropertyKey]; + textField.placeholder = self.title; + [textField becomeFirstResponder]; + } +} + + +#pragma mark - +#pragma mark Save and cancel operations + +- (IBAction)save { + + // Pass the current value to the source controller, then pop. + if (editingDate) { + [sourceController setValue:datePicker.date forEditedProperty:editedPropertyKey]; + } + else { + [sourceController setValue:textField.text forEditedProperty:editedPropertyKey]; + } + + [self.navigationController popViewControllerAnimated:YES]; +} + + +- (IBAction)cancel { + // Don't pass the current value to the edited object, just pop. + [self.navigationController popViewControllerAnimated:YES]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [datePicker release]; + [editedObject release]; + [editedPropertyKey release]; + [editedPropertyDisplayName release]; + [super dealloc]; +} + + +@end + diff --git a/SimpleUndo/Classes/RootViewController.h b/SimpleUndo/Classes/RootViewController.h new file mode 100644 index 0000000..c8998ec --- /dev/null +++ b/SimpleUndo/Classes/RootViewController.h @@ -0,0 +1,64 @@ + +/* + File: RootViewController.h + Abstract: Abstract: The table view controller responsible for displaying information about a book. The user can also edit the information. When editing starts, the root view controller creates an undo manager to record changes. The undo manager supports up to three levels of and redo. When the user taps Done, changes are considered to be committed and the undo manager is disposed of. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "EditingViewController.h" + +@class Book; + +@interface RootViewController : UITableViewController { + Book *book; + NSDateFormatter *dateFormatter; + NSUndoManager *undoManager; +} + +@property (nonatomic, retain) Book *book; +@property (nonatomic, retain) NSDateFormatter *dateFormatter; +@property (nonatomic, retain) NSUndoManager *undoManager; + +@end diff --git a/SimpleUndo/Classes/RootViewController.m b/SimpleUndo/Classes/RootViewController.m new file mode 100644 index 0000000..a012b73 --- /dev/null +++ b/SimpleUndo/Classes/RootViewController.m @@ -0,0 +1,307 @@ + +/* + File: RootViewController.m + Abstract: Abstract: The table view controller responsible for displaying information about a book. The user can also edit the information. When editing starts, the root view controller creates an undo manager to record changes. The undo manager supports up to three levels of and redo. When the user taps Done, changes are considered to be committed and the undo manager is disposed of. + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" + +#import "EditingViewController.h" +#import "Book.h" + + +@implementation RootViewController + +@synthesize book, dateFormatter, undoManager; + +#pragma mark - +#pragma mark View loading + + +- (void)viewDidLoad { + + [super viewDidLoad]; + self.title = @"Book"; + self.navigationItem.rightBarButtonItem = self.editButtonItem; + self.tableView.allowsSelectionDuringEditing = YES; +} + + +- (void)viewDidUnload { + // Release any properties that are loaded in viewDidLoad or can be recreated lazily. + self.dateFormatter = nil; +} + + +- (void)viewWillAppear:(BOOL)animated { + + [super viewWillAppear:animated]; + // Redisplay the data. + [self.tableView reloadData]; +} + + + +#pragma mark - +#pragma mark Table view data source methods + +/* + Standard table view data source and delegate methods to display a table view containing a single section with three rows showing different properties of the book. + */ + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // 1 section. + return 1; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // 3 rows. + return 3; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + /* + Dequeue or create and then configure a table cell for each attribute of the book. + */ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease]; + cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + + switch (indexPath.row) { + case 0: + cell.textLabel.text = @"Title"; + cell.detailTextLabel.text = book.title; + break; + case 1: + cell.textLabel.text = @"Author"; + cell.detailTextLabel.text = book.author; + break; + case 2: + cell.textLabel.text = @"Copyright"; + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:book.copyright]; + break; + } + return cell; +} + + +- (NSIndexPath *)tableView:(UITableView *)tv willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // Only allow selection if editing. + return (self.editing) ? indexPath : nil; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + + // Only allow selection if editing. + if (!self.editing) return; + + /* + Create, configure, and push the editing controller. + */ + EditingViewController *controller = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]; + controller.editedObject = book; + controller.sourceController = self; + + switch (indexPath.row) { + case 0: { + controller.editedPropertyKey = @"title"; + controller.editedPropertyDisplayName = NSLocalizedString(@"title", @"display name for title"); + controller.editingDate = NO; + } break; + case 1: { + controller.editedPropertyKey = @"author"; + controller.editedPropertyDisplayName = NSLocalizedString(@"author", @"display name for author"); + controller.editingDate = NO; + } break; + case 2: { + controller.editedPropertyKey = @"copyright"; + controller.editedPropertyDisplayName = NSLocalizedString(@"copyright", @"display name for copyright"); + controller.editingDate = YES; + } break; + } + + [self.navigationController pushViewController:controller animated:YES]; + [controller release]; +} + + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + // Do not allow rows to be deleted when in editing mode. + return UITableViewCellEditingStyleNone; +} + + +- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath { + // Do not indent rows when in editing mode. + return NO; +} + + +#pragma mark - +#pragma mark Editing + +/* + Method to update a value in the book, and at the same time register the undo/redo operation with the undo manager. + The implementation uses an invocation since the method requires two arguments. + + This method is invoked by the editing view controller if the user taps Save. + */ +- (void)setValue:(id)newValue forEditedProperty:(NSString *)field { + + /* + prepareWithInvocationTarget: pushes a new undo item onto the undo stack (or onto the redop stack if this method is invoked during an undo operation). + If the user chooses undo, then the undo manager sends the target (self) setValue:forEditedProperty: message with the arguments currentValueforEditedProperty and field. + */ + id currentValueforEditedProperty = [book valueForKey:field]; + [[undoManager prepareWithInvocationTarget:self] setValue:currentValueforEditedProperty forEditedProperty:field]; + + // Update the book's property to the new value. + [book setValue:newValue forKey:field]; + + // Set the action name (which appears in the undo button title) to the user-visible name of the field. + if (![undoManager isUndoing]) { + [undoManager setActionName:NSLocalizedString(field, @"string provided dynamically")]; + } +} + + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + + [super setEditing:editing animated:animated]; + + /* + Respond to change in editing state: + If editing begins, create and set an undo manager to track edits. Then register as an observer of undo manager change notifications, so that if an undo or redo operation is performed, the table view can be reloaded. + If editing ends, de-register from the notification center and remove the undo manager. + */ + NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter]; + + if (editing) { + NSUndoManager *anUndoManager = [[NSUndoManager alloc] init]; + self.undoManager = anUndoManager; + [anUndoManager release]; + + /* + 3 levels of undo is somewhat arbitrary. It happens here to coincide with the number of properties that can be edited, but in general you need to consider the memory overhead of maintaining a large number of undo actions, and the user interaction (how easy will it be for the user to backtrack through a dozen or more actions). + */ + [undoManager setLevelsOfUndo:3]; + [dnc addObserver:self selector:@selector(undoManagerDidUndo:) name:NSUndoManagerDidUndoChangeNotification object:undoManager]; + [dnc addObserver:self selector:@selector(undoManagerDidRedo:) name:NSUndoManagerDidRedoChangeNotification object:undoManager]; + } + else { + [dnc removeObserver:self]; + self.undoManager = nil; + } +} + + +#pragma mark - +#pragma mark Undo support + +/* + Methods invoked in response to undo notifications -- see setEditing:animated:. Simply redisplay the table view to reflect the changed value. + */ +- (void)undoManagerDidUndo:(NSNotification *)notification { + [self.tableView reloadData]; +} + + +- (void)undoManagerDidRedo:(NSNotification *)notification { + [self.tableView reloadData]; +} + + +/* + The view controller must be first responder in order to be able to receive shake events for undo. It should resign first responder status when it disappears. + */ +- (BOOL)canBecomeFirstResponder { + return YES; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self becomeFirstResponder]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [self resignFirstResponder]; +} + + +#pragma mark - +#pragma mark Date formatter + +- (NSDateFormatter *)dateFormatter { + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; + } + return dateFormatter; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [undoManager release]; + [dateFormatter release]; + [book release]; + [super dealloc]; +} + + +@end + diff --git a/SimpleUndo/Classes/SimpleUndoAppDelegate.h b/SimpleUndo/Classes/SimpleUndoAppDelegate.h new file mode 100644 index 0000000..61e6903 --- /dev/null +++ b/SimpleUndo/Classes/SimpleUndoAppDelegate.h @@ -0,0 +1,59 @@ + +/* + File: SimpleUndoAppDelegate.h + Abstract: Application delegate to configure the view and navigation controllers. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface SimpleUndoAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; + +@end + diff --git a/SimpleUndo/Classes/SimpleUndoAppDelegate.m b/SimpleUndo/Classes/SimpleUndoAppDelegate.m new file mode 100644 index 0000000..36f937a --- /dev/null +++ b/SimpleUndo/Classes/SimpleUndoAppDelegate.m @@ -0,0 +1,91 @@ + +/* + File: SimpleUndoAppDelegate.m + Abstract: Application delegate to configure the view and navigation controllers. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SimpleUndoAppDelegate.h" +#import "RootViewController.h" +#import "Book.h" + +@implementation SimpleUndoAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Tell the application to support shake-to-edit. + application.applicationSupportsShakeToEdit = YES; + + // Create a new book for the root controller. + RootViewController *rootViewController = (RootViewController *)[navigationController topViewController]; + + Book *newBook = [[Book alloc] init]; + rootViewController.book = newBook; + [newBook release]; + + // Configure and display the window. + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/SimpleUndo/ReadMe.txt b/SimpleUndo/ReadMe.txt new file mode 100644 index 0000000..74a4d9e --- /dev/null +++ b/SimpleUndo/ReadMe.txt @@ -0,0 +1,44 @@ +### SimpleUndo ### + +=========================================================================== +DESCRIPTION: + +Illustrates how to use undo on iPhone. +The root view controller displays information (title, author, and copyright date) about a book. The user can edit this information by tapping Edit in the navigation bar. When editing starts, the root view controller creates an undo manager to record changes. The undo manager supports up to three levels of undo and redo. When the user taps Done, changes are considered to be committed and the undo manager is disposed of. + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST: + +SimpleUndoAppDelegate.{h,m} +Configures the book and the first view controllers. + +RootViewController.{h,m} +Manages a table view that displays information about a book. + +EditingViewController.{h,m} +View for editing a field of data, text or date. + +Book.{h,m} +A simple managed object class to represent a book. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.1 +- Upgraded project to build with the iOS 4.0 SDK. + +Version 1.0 +- First version. + +=========================================================================== +Copyright (C) 2009-2010 Apple Inc. All rights reserved. diff --git a/SimpleUndo/SimpleUndo-Info.plist b/SimpleUndo/SimpleUndo-Info.plist new file mode 100644 index 0000000..e935f77 --- /dev/null +++ b/SimpleUndo/SimpleUndo-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.devpubs.SimpleUndo + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/SimpleUndo/SimpleUndo.xcodeproj/project.pbxproj b/SimpleUndo/SimpleUndo.xcodeproj/project.pbxproj new file mode 100755 index 0000000..3bbb666 --- /dev/null +++ b/SimpleUndo/SimpleUndo.xcodeproj/project.pbxproj @@ -0,0 +1,346 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 182A8D0811D2BB3B00E156CC /* EditingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0211D2BB3B00E156CC /* EditingView.xib */; }; + 182A8D0911D2BB3B00E156CC /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0411D2BB3B00E156CC /* MainWindow.xib */; }; + 182A8D0A11D2BB3B00E156CC /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0611D2BB3B00E156CC /* RootViewController.xib */; }; + 182A8D1211D2BB7300E156CC /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0B11D2BB7300E156CC /* Icon-72.png */; }; + 182A8D1311D2BB7300E156CC /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0C11D2BB7300E156CC /* Icon-Small-50.png */; }; + 182A8D1411D2BB7300E156CC /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0D11D2BB7300E156CC /* Icon-Small.png */; }; + 182A8D1511D2BB7300E156CC /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0E11D2BB7300E156CC /* Icon-Small@2x.png */; }; + 182A8D1611D2BB7300E156CC /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D0F11D2BB7300E156CC /* Icon.png */; }; + 182A8D1711D2BB7300E156CC /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D1011D2BB7300E156CC /* Icon@2x.png */; }; + 182A8D1811D2BB7300E156CC /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 182A8D1111D2BB7300E156CC /* iTunesArtwork */; }; + 1D3623260D0F684500981E51 /* SimpleUndoAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SimpleUndoAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2881317F0F60A050004132C2 /* EditingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2881317C0F60A050004132C2 /* EditingViewController.m */; }; + 288131970F60AEDD004132C2 /* Book.m in Sources */ = {isa = PBXBuildFile; fileRef = 288131960F60AEDD004132C2 /* Book.m */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + 28D2EFE30F688E6C00258F94 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 28D2EFE20F688E6C00258F94 /* ReadMe.txt */; }; + 5396CFEC11D2BEE40065BF7B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5396CFEA11D2BEE40065BF7B /* Localizable.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 182A8D0311D2BB3B00E156CC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/EditingView.xib; sourceTree = ""; }; + 182A8D0511D2BB3B00E156CC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 182A8D0711D2BB3B00E156CC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; + 182A8D0B11D2BB7300E156CC /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 182A8D0C11D2BB7300E156CC /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 182A8D0D11D2BB7300E156CC /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 182A8D0E11D2BB7300E156CC /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 182A8D0F11D2BB7300E156CC /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 182A8D1011D2BB7300E156CC /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 182A8D1111D2BB7300E156CC /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* SimpleUndoAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleUndoAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* SimpleUndoAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleUndoAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* SimpleUndo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleUndo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2881317B0F60A050004132C2 /* EditingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingViewController.h; sourceTree = ""; }; + 2881317C0F60A050004132C2 /* EditingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditingViewController.m; sourceTree = ""; }; + 288131950F60AEDD004132C2 /* Book.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Book.h; sourceTree = ""; }; + 288131960F60AEDD004132C2 /* Book.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Book.m; sourceTree = ""; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* SimpleUndo_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleUndo_Prefix.pch; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28D2EFE20F688E6C00258F94 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5396CFEB11D2BEE40065BF7B /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* SimpleUndo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SimpleUndo-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + 2881317B0F60A050004132C2 /* EditingViewController.h */, + 2881317C0F60A050004132C2 /* EditingViewController.m */, + 1D3623240D0F684500981E51 /* SimpleUndoAppDelegate.h */, + 1D3623250D0F684500981E51 /* SimpleUndoAppDelegate.m */, + 288131950F60AEDD004132C2 /* Book.h */, + 288131960F60AEDD004132C2 /* Book.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SimpleUndo.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28D2EFE20F688E6C00258F94 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* SimpleUndo_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 182A8D0B11D2BB7300E156CC /* Icon-72.png */, + 182A8D0C11D2BB7300E156CC /* Icon-Small-50.png */, + 182A8D0D11D2BB7300E156CC /* Icon-Small.png */, + 182A8D0E11D2BB7300E156CC /* Icon-Small@2x.png */, + 182A8D0F11D2BB7300E156CC /* Icon.png */, + 182A8D1011D2BB7300E156CC /* Icon@2x.png */, + 182A8D1111D2BB7300E156CC /* iTunesArtwork */, + 182A8D0211D2BB3B00E156CC /* EditingView.xib */, + 182A8D0411D2BB3B00E156CC /* MainWindow.xib */, + 182A8D0611D2BB3B00E156CC /* RootViewController.xib */, + 5396CFEA11D2BEE40065BF7B /* Localizable.strings */, + 8D1107310486CEB800E47090 /* SimpleUndo-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SimpleUndo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleUndo" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SimpleUndo; + productName = SimpleUndo; + productReference = 1D6058910D05DD3D006BFB54 /* SimpleUndo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleUndo" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SimpleUndo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28D2EFE30F688E6C00258F94 /* ReadMe.txt in Resources */, + 182A8D0811D2BB3B00E156CC /* EditingView.xib in Resources */, + 182A8D0911D2BB3B00E156CC /* MainWindow.xib in Resources */, + 182A8D0A11D2BB3B00E156CC /* RootViewController.xib in Resources */, + 182A8D1211D2BB7300E156CC /* Icon-72.png in Resources */, + 182A8D1311D2BB7300E156CC /* Icon-Small-50.png in Resources */, + 182A8D1411D2BB7300E156CC /* Icon-Small.png in Resources */, + 182A8D1511D2BB7300E156CC /* Icon-Small@2x.png in Resources */, + 182A8D1611D2BB7300E156CC /* Icon.png in Resources */, + 182A8D1711D2BB7300E156CC /* Icon@2x.png in Resources */, + 182A8D1811D2BB7300E156CC /* iTunesArtwork in Resources */, + 5396CFEC11D2BEE40065BF7B /* Localizable.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* SimpleUndoAppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + 2881317F0F60A050004132C2 /* EditingViewController.m in Sources */, + 288131970F60AEDD004132C2 /* Book.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 182A8D0211D2BB3B00E156CC /* EditingView.xib */ = { + isa = PBXVariantGroup; + children = ( + 182A8D0311D2BB3B00E156CC /* en */, + ); + name = EditingView.xib; + sourceTree = ""; + }; + 182A8D0411D2BB3B00E156CC /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 182A8D0511D2BB3B00E156CC /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 182A8D0611D2BB3B00E156CC /* RootViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 182A8D0711D2BB3B00E156CC /* en */, + ); + name = RootViewController.xib; + sourceTree = ""; + }; + 5396CFEA11D2BEE40065BF7B /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 5396CFEB11D2BEE40065BF7B /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleUndo_Prefix.pch; + INFOPLIST_FILE = "SimpleUndo-Info.plist"; + PRODUCT_NAME = SimpleUndo; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleUndo_Prefix.pch; + INFOPLIST_FILE = "SimpleUndo-Info.plist"; + PRODUCT_NAME = SimpleUndo; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleUndo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleUndo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/SimpleUndo/SimpleUndo_Prefix.pch b/SimpleUndo/SimpleUndo_Prefix.pch new file mode 100644 index 0000000..4db631d --- /dev/null +++ b/SimpleUndo/SimpleUndo_Prefix.pch @@ -0,0 +1,59 @@ + +/* + File: SimpleUndo_Prefix.pch + Abstract: Prefix header for all source files of the 'SimpleUndo' target in the 'SimpleUndo' project. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/SimpleUndo/en.lproj/EditingView.xib b/SimpleUndo/en.lproj/EditingView.xib new file mode 100755 index 0000000..6afe218 --- /dev/null +++ b/SimpleUndo/en.lproj/EditingView.xib @@ -0,0 +1,366 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 268 + + YES + + + 268 + {{0, 43}, {320, 216}} + + NO + YES + YES + 0 + 0 + 1 + + en_US + + + America/Los_Angeles + + VFppZgAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAC5AAAABAAAABCepkign7sVkKCGKqChmveQ +y4kaoNIj9HDSYSYQ1v50INiArZDa/tGg28CQENzes6DdqayQ3r6VoN+JjpDgnneg4WlwkOJ+WaDjSVKQ +5F47oOUpNJDmR1gg5xJREOgnOiDo8jMQ6gccIOrSFRDr5v4g7LH3EO3G4CDukdkQ76/8oPBxuxDxj96g +8n/BkPNvwKD0X6OQ9U+ioPY/hZD3L4Sg+CiiEPkPZqD6CIQQ+viDIPvoZhD82GUg/chIEP64RyD/qCoQ +AJgpIAGIDBACeAsgA3EokARhJ6AFUQqQBkEJoAcw7JAHjUOgCRDOkAmtvyAK8LCQC+CvoAzZzRANwJGg +DrmvEA+priAQmZEQEYmQIBJ5cxATaXIgFFlVEBVJVCAWOTcQFyk2IBgiU5AZCRggGgI1kBryNKAb4heQ +HNIWoB3B+ZAesfigH6HbkCB2KyAhgb2QIlYNICNq2hAkNe8gJUq8ECYV0SAnKp4QJ/7toCkKgBAp3s+g +KupiECu+saAs036QLZ6ToC6zYJAvfnWgMJNCkDFnkiAycySQM0d0IDRTBpA1J1YgNjLokDcHOCA4HAUQ +OOcaIDn75xA6xvwgO9vJEDywGKA9u6sQPo/6oD+bjRBAb9ygQYSpkEJPvqBDZIuQRC+goEVEbZBF89Mg +Ry2KEEfTtSBJDWwQSbOXIErtThBLnLOgTNZqkE18laBOtkyQT1x3oFCWLpBRPFmgUnYQkFMcO6BUVfKQ +VPwdoFY11JBW5TogWB7xEFjFHCBZ/tMQWqT+IFvetRBchOAgXb6XEF5kwiBfnnkQYE3eoGGHlZBiLcCg +Y2d3kGQNoqBlR1mQZe2EoGcnO5BnzWagaQcdkGmtSKBq5v+Qa5ZlIGzQHBBtdkcgbq/+EG9WKSBwj+AQ +cTYLIHJvwhBzFe0gdE+kEHT/CaB2OMCQdt7roHgYopB4vs2gefiEkHqer6B72GaQfH6RoH24SJB+XnOg +f5gqkAABAAECAwEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA +AQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA +AQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA +AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA + + + 5 + + + + 268 + {{20, 43}, {280, 31}} + + NO + NO + 0 + + 3 + + + 3 + MAA + + 2 + + + YES + 1.700000e+01 + + 1 + + + + {320, 436} + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADgEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAACBgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAYYAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAIAAAFTAAMAAAAEAAACDodzAAcAAA78AAACFgAAAAAACAAIAAgACAABAAEAAQABAAAO/GFw +cGwCAAAAbW50clJHQiBYWVogB9kAAQAeAA4AIQAYYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA +AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAYSbmRpbgAA +B+wAAAY+ZGVzYwAADiwAAABfZHNjbQAADowAAAAkbW1vZAAADrAAAAAoY3BydAAADtgAAAAkWFlaIAAA +AAAAAHkOAAA/aAAAAd1YWVogAAAAAAAAVikAAKsgAAAS91hZWiAAAAAAAAAnnwAAFZIAAL5QWFlaIAAA +AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 +cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD +AQAAAgAAAC4AoQE5AeECrQOkBLsF7wdOCLoKPAvbDYcPPhD7EsIUjRZXGCQZ4xuXHUQe2yBiIdMjMiRx +JaImxSfdKO0p/CsFLA0tEy4ZLxwwIDEhMiIzJDQhNR02GDcROAU4+jnuOt87zjy8Pak+lj+FQHdBa0Jh +Q1hETUVBRjNHI0gSSQBJ7ErXS8FMqk2STntPZlBTUUVSOVMwVCZVGlYOVv9X8FjgWc5avFupXJRdgF5s +X1xgUGFKYkpjTWRQZVRmV2dYaFdpVWpSa09sS21GbkJvQHBCcUpyVnNkdHV1hHaTd6F4rXm6esV7z3zY +fd9+5n/qgOyB64Log+SE3oXYhtCHyIi9ibOKqIubjI6NgY5yj2KQUpFCkjGTH5QMlPmV5pbSl76YqJmS +mnubZJxMnTOeG58Dn+yg16HForOjo6SSpYCmbadaqEapMqoeqwmr86zercius6+fsI6xgLJ1s2u0Y7Vb +tlK3Sbg/uTW6KbsevBK9Bb34vuq/28DMwbvCqcOXxIPFcMZcx0fIMckcygbK78vYzMHNqs6Sz3zQaNFV +0kXTN9Qp1RzWDtcA1/HY49nT2sPbs9yj3ZPegt9z4GbhW+JT403kSeVE5kDnPOg46TTqMOss7CjtJO4f +7xvwGPEV8hLzEPQO9Qz2CfcH+Ab5BvoG+wX8Bf0E/gL/Af//AAAALACYAS4B1gKiA5IEpAXYBywImgoR +C6oNRw77ELISchQzFfUXsxltGx0cvh5PH9AhOiKNI8gk9CYSJyIoLCkyKjgrOSw4LTUuMy8uMCgxJDId +MxU0CzUANfM25DfTOME5rjqZO4E8aT1QPjU/HEAEQO5B2kLHQ7VEoUWMRndHYEhISS5KFEr3S9pMu02d +Tn9PYlBIUTJSIFMPU/1U7FXaVsdXs1ieWYhacVtZXD9dJl4OXvdf5GDWYc1iyGPFZMNlwWa+Z7potWmv +aqlromyZbZFuim+EcINxh3KQc5t0p3Wzdr93yXjTedx65HvsfPJ99377f/yA+4H4gvOD7ITkhduG0YfG +iLqJroqii5WMho13jmmPWJBIkTaSJJMSk/6U6pXVlr+XqJiPmXeaXZtDnCmdDp3zntmfv6CpoZWihKNz +pGSlVKZEpzOoIakQqf2q6qvXrMOtr66br4mweLFrsmCzWLRPtUi2QLc3uC+5JroduxO8Cbz+vfO+6L/c +wNDBxMK2w6nEmsWMxn3HbchcyUzKO8spzBfNBM3yzuDPz9DC0bjSsNOr1KfVotad15fYkdmK2oPbe9xy +3WreY99d4FrhW+Je42XkbeV15n7nhuiN6ZPqmeuf7KXtqu6x77rwyPHb8vL0DPUm9kD3Wfhw+Yb6m/uw +/MT92P7s//8AAAApAJABIAG6AnsDYQRoBYoGyggiCYsLBgyaDjIP2BGIEzgU5RaTGD8Z3xt2HP0edx/c +ITAibiOZJLkl0SbiJ/Ao+ioCKwgsDC0NLgwvCzAGMQEx+TLvM+U02TXJNrk3qDiUOX46aDtPPDc9Gj3+ +PuM/yECuQZZCfkNmRE5FNUYaRv1H4UjCSaJKgkthTD1NGU31TtJPr1CPUXJSV1M9VCNVCFXtVtBXs1iV +WXZaVVs0XBFc713MXqpfi2BwYVtiS2M7ZC5lIGYSZwNn82jiadBqvWupbJRtf25rb1lwSnFAcjpzNnQz +dTF2LncreCd5Inodexd8EH0JfgB+9n/qgNyBzIK5g6aEkIV7hmSHTYg1iRuKAorni8yMsI2UjnePWpA9 +kSCSApLkk8aUqJWIlmiXR5gmmQWZ5JrCm6CcfJ1YnjWfEZ/woNChs6KXo36kZKVLpjCnFaf6qN+pw6qm +q4msa61OrjCvFK/6sOSx0bLCs7W0qbWdtpG3g7h2uWi6WrtLvDy9LL4cvwy/+8Dswd3CzsPAxLHFocaS +x4LIcclhylDLP8wuzR3ODc79z/DQ6NHj0uPT5dTo1ezW79fy2PXZ+Nr82/7dAt4G3w3gGeEs4kfjaOSO +5bXm3egG6S3qVet+7Knt2O8R8F3xu/Mz9L32VPfv+Y37KvzH/mP//wAAbmRpbgAAAAAAAAY2AACk6gAA +VzEAAEqfAACf8gAAJpsAABOCAABQDQAAVDkAAe4UAAHcKAABuuEAAwEAAAIAAAARACgAPwBVAGwAgwCZ +ALAAyADgAPgBEAEpAUIBXAF3AZIBrQHKAecCBAIjAkICYgKEAqYCygLwAxYDPwNqA5cDxwP6BDAEbASs +BPAFOQWGBdcGKgaBBtoHNgeUB/UIWAi+CSYJkAn+Cm8K4gtZC9QMUQzRDVUN3A5mDvMPghAREKARMRHD +ElgS8BOMFCsUzRVyFhsWxhd1GCgY3BmRGkYa+huuHGIdGR3THpAfUSAUINshpCJxI0EkEyTnJbomiydY +KCMo7Sm5KoYrViwpLP8t2C60L5IwcjFVMjkzHDP9NNs1uDaUN3A4TzkvOhI6+DvfPMk9tj6kP5ZAikGB +Qn1DfUSBRYhGk0egSLBJw0raS/NND04uT1BQdFGcUsZT81UjVlVXi1jDWf1bOlx6Xb5fBGBNYZli6GQ6 +ZY1m4Wg0aYVq1mwobXxu03AucYty6nRNdbF3GXiCee97XHzJfjN/moD+gmKDxoUthpWIAYluit+MUo3I +j0CQu5I5k7qVPpbGmFGZ35txnQWenKA2odOjcqUUprmoYKoJq7StXq8GsKuyTrPxtZS3Orjjuo68O73r +v53BUsMIxMHGe8gzyenLnM1LzvnQqNJX1AnVvNdw2Sba3dyW3lDgDeHL44nlSOcH6MfqiexN7hLv2PGe +82T1K/b0+L/6jPxb/iz//wAAABIAKQBAAFcAbgCFAJwAswDLAOQA/AEVAS8BSQFjAX4BmgG2AdMB8QIP +Ai8CTwJxApMCtwLcAwMDKwNWA4MDsgPlBBsEVgSWBNoFIwVxBcMGGAZvBsoHKAeJB+wIUgi7CSUJkwoD +CncK7QtnC+QMZQzoDW8N+g6IDxkPrhBEENsRdBINEqgTRhPnFIsVMhXdFosXPBfyGKoZZhokGuMbohxg +HR0d2x6cH18gJSDuIboiiSNcJDIlCyXmJsMnnyh5KVAqJSr4K80soy18LlgvNjAXMPox4DLJM7Q0oDWM +NnY3XThBOSU6CjrwO9g8wj2vPp0/j0CCQXhCcUNsRGtFbkZ1R4BIj0miSrdLz0zqTghPKFBLUXBSmVPE +VPFWIldVWItZxFsAXD9dgV7HYBBhXWKsY/9lVGasaAdpZGrBbBxtdG7KcCFxeHLSdC51jnbveFR5u3sl +fJF+AH9xgOCCToO5hSGGiYfyiVyKyYw3jaiPG5CRkgiTgpT/ln6X/5mCmwickZ4cn6qhOqLNpGOl/KeX +qTSq1ax4rh2vw7Foswm0prZAt9i5cbsMvKi+SL/qwY/DN8Thxo3IOsnny5HNN87Z0HjSFNOx1U7W7tiQ +2jTb292E3y/g2+KJ5DXl3+eC6SDquexP7ebvfvEa8rj0WvX+96T5Tfr3/KP+UP//AAAAEwAsAEQAXAB0 +AI0ApQC+ANgA8QEMASYBQQFdAXkBlgGzAdEB8AIQAjECUwJ1ApkCvwLlAw0DOANkA5IDxAP4BDAEbASt +BPMFPAWJBdoGLQaEBt0HOQeYB/oIXwjGCTEJngoPCoMK+QtzC/EMcQz1DX0OBw6WDycPvRBVEO8RjBIp +EsgTahQOFLUVYBYPFsAXdhgvGOsZrBpwGzYb/hzHHY8eVx8gH+wguyGNImIjOyQXJPcl2ibBJ6oolimB +KmorTywxLRQt9y7dL8UwsTGfMpEzhTR9NXg2dTd0OHI5bjpnO148VT1MPkU/QUA/QT9CQkNHRE9FWUZm +R3ZIikmjSsBL4k0ITjJPXlCOUcFS91QxVW1WrVfwWTZaflvJXRZeZl+4YQ1iZWPAZR9mgGfkaUpqtGwh +bZFvBXB6cfBzZHTVdkV3tHkleph8D32IfwSAg4IFg4qFEYabiCaJr4s0jLSOL4+pkSKSnpQclZ2XIJil +mi6buJ1GntagZ6H7o5ClJaa7qFOp7auKrSmuyrBushSzvLVmtxG4vrpsvBa9u79awPTCi8QhxbnHU8ju +yovMKc3Iz2rRDNKv1FDV69d92QbaiNwE3X7e9+Bx4ezjaeTn5mXn4+lg6tjsR+2m7vfwOvFu8pfzu/TZ +9fX3Efgs+Uj6ZfuC/KD9v/7f//8AAGRlc2MAAAAAAAAABWlNYWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1s +dWMAAAAAAAAAAQAAAAxlblVTAAAACAAAABwAaQBNAGEAY21tb2QAAAAAAAAGEAAAnI4AAAAAwbTFAAAA +AAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSwgSW5jLiwgMjAwOQA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + + NO + + + + + + YES + + + view + + + + 29 + + + + textField + + + + 30 + + + + datePicker + + + + 41 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 27 + + + YES + + + + + + + 28 + + + + + -2 + + + + + 39 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 27.IBEditorWindowLastContentRect + 27.IBPluginDependency + 28.IBPluginDependency + 39.IBPluginDependency + + + YES + EditingViewController + UIResponder + {{489, 502}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 45 + + + + YES + + EditingViewController + UIViewController + + YES + + YES + cancel: + save: + + + YES + id + id + + + + YES + + YES + datePicker + editedObject + sourceController + textField + + + YES + UIDatePicker + id + id + UITextField + + + + IBProjectSource + Classes/EditingViewController.h + + + + + 0 + SimpleUndo.xcodeproj + 3 + + diff --git a/SimpleUndo/en.lproj/Localizable.strings b/SimpleUndo/en.lproj/Localizable.strings new file mode 100644 index 0000000..11b1c79 Binary files /dev/null and b/SimpleUndo/en.lproj/Localizable.strings differ diff --git a/SimpleUndo/en.lproj/MainWindow.xib b/SimpleUndo/en.lproj/MainWindow.xib new file mode 100644 index 0000000..9340f88 --- /dev/null +++ b/SimpleUndo/en.lproj/MainWindow.xib @@ -0,0 +1,266 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + + + RootViewController + + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RootViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SimpleUndoAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 15 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + SimpleUndoAppDelegate + NSObject + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + Classes/SimpleUndoAppDelegate.h + + + + + 0 + SimpleUndo.xcodeproj + 3 + + diff --git a/SimpleUndo/en.lproj/RootViewController.xib b/SimpleUndo/en.lproj/RootViewController.xib new file mode 100644 index 0000000..b25c1fb --- /dev/null +++ b/SimpleUndo/en.lproj/RootViewController.xib @@ -0,0 +1,189 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + {320, 416} + + NO + YES + NO + + + NO + + NO + 1 + 1 + 0 + YES + 4.400000e+01 + 1.000000e+01 + 1.000000e+01 + + + + + YES + + + tableView + + + + 10 + + + + view + + + + 11 + + + + dataSource + + + + 12 + + + + delegate + + + + 13 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 9 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + RootViewController + UIResponder + {{805, 337}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 13 + + + + YES + + RootViewController + UITableViewController + + IBProjectSource + Classes/RootViewController.h + + + + RootViewController + UITableViewController + + tableView + UITableView + + + IBUserSource + + + + + + 0 + SimpleUndo.xcodeproj + 3 + + diff --git a/SimpleUndo/images/Icon-72.png b/SimpleUndo/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/SimpleUndo/images/Icon-72.png differ diff --git a/SimpleUndo/images/Icon-Small-50.png b/SimpleUndo/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/SimpleUndo/images/Icon-Small-50.png differ diff --git a/SimpleUndo/images/Icon-Small.png b/SimpleUndo/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/SimpleUndo/images/Icon-Small.png differ diff --git a/SimpleUndo/images/Icon-Small@2x.png b/SimpleUndo/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/SimpleUndo/images/Icon-Small@2x.png differ diff --git a/SimpleUndo/images/Icon.png b/SimpleUndo/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/SimpleUndo/images/Icon.png differ diff --git a/SimpleUndo/images/Icon@2x.png b/SimpleUndo/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/SimpleUndo/images/Icon@2x.png differ diff --git a/SimpleUndo/images/iTunesArtwork b/SimpleUndo/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/SimpleUndo/images/iTunesArtwork differ diff --git a/SimpleUndo/main.m b/SimpleUndo/main.m new file mode 100644 index 0000000..fcf21f0 --- /dev/null +++ b/SimpleUndo/main.m @@ -0,0 +1,55 @@ + +/* + File: main.m + Abstract: Standard main.m file. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/SysSound.zip b/SysSound.zip new file mode 100644 index 0000000..328746b Binary files /dev/null and b/SysSound.zip differ diff --git a/SysSound/Classes/SysSoundAppDelegate.h b/SysSound/Classes/SysSoundAppDelegate.h new file mode 100644 index 0000000..6e59ee2 --- /dev/null +++ b/SysSound/Classes/SysSoundAppDelegate.h @@ -0,0 +1,62 @@ +/* + File: SysSoundAppDelegate.h +Abstract: Application delegate class for SysSound. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class SysSoundViewController; + +@interface SysSoundAppDelegate : NSObject { + + UIWindow *window; + SysSoundViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet SysSoundViewController *viewController; + +@end + diff --git a/SysSound/Classes/SysSoundAppDelegate.m b/SysSound/Classes/SysSoundAppDelegate.m new file mode 100644 index 0000000..6bc49bf --- /dev/null +++ b/SysSound/Classes/SysSoundAppDelegate.m @@ -0,0 +1,123 @@ +/* + File: SysSoundAppDelegate.m +Abstract: Application delegate class for SysSound. + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "SysSoundAppDelegate.h" +#import "SysSoundViewController.h" + +@implementation SysSoundAppDelegate + +@synthesize window; +@synthesize viewController; + + +- (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions { + + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; + + return YES; +} + +// This app doesn't need to do anything special during these transitions. The method stubs are left here +// for your use if you extend this app. +- (void) applicationWillResignActive: (UIApplication *) application { + /* + Sent when the application is about to move from active to inactive state. This can occur for certain types + of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the + application and it begins the transition to the background state. + + Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games + should use this method to pause the game. + */ +} + + +- (void) applicationDidEnterBackground: (UIApplication *) application { + /* + Use this method to release shared resources, save user data, invalidate timers, and store enough application + state information to restore your application to its current state in case it is terminated later. + + If your application supports background execution, called instead of applicationWillTerminate: when the user + quits. + */ +} + + +- (void) applicationWillEnterForeground: (UIApplication *) application { + /* + Called as part of transition from the background to the inactive state: here you can undo many of the + changes made on entering the background. + */ +} + + +- (void) applicationDidBecomeActive: (UIApplication *) application { + /* + Restart any tasks that were paused (or not yet started) while the application was inactive. If the + application was previously in the background, optionally refresh the user interface. + */ +} + + +- (void) applicationWillTerminate: (UIApplication *) application { + /* + Called when the application is about to terminate. + + See also applicationDidEnterBackground:. + */ +} + + +- (void) dealloc { + + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/SysSound/Classes/SysSoundViewController.h b/SysSound/Classes/SysSoundViewController.h new file mode 100644 index 0000000..8909a24 --- /dev/null +++ b/SysSound/Classes/SysSoundViewController.h @@ -0,0 +1,70 @@ +/* + File: SysSoundViewController.h +Abstract: This file does the work for SysSound--defining the sound to play and then playing +it when a user taps the System Sound button. Tapping the Alert Sound button invokes an alert as +performed by the device; for example, on an iPhone, it plays the sound and also invokes +vibration. Tapping the Vibration button directly invokes vibration on devices that support it. + + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#include + +@interface SysSoundViewController : UIViewController { + + CFURLRef soundFileURLRef; + SystemSoundID soundFileObject; + +} + +@property (readwrite) CFURLRef soundFileURLRef; +@property (readonly) SystemSoundID soundFileObject; + +- (IBAction) playSystemSound: (id) sender; +- (IBAction) playAlertSound: (id) sender; +- (IBAction) vibrate: (id) sender; + +@end + diff --git a/SysSound/Classes/SysSoundViewController.m b/SysSound/Classes/SysSoundViewController.m new file mode 100644 index 0000000..4bad726 --- /dev/null +++ b/SysSound/Classes/SysSoundViewController.m @@ -0,0 +1,113 @@ +/* + File: SysSoundViewController.m +Abstract: This file does the work for SysSound--defining the sound to play and then playing +it when a user taps the System Sound button. Tapping the Alert Sound button invokes an alert as +performed by the device; for example, on an iPhone, it plays the sound and also invokes +vibration. Tapping the Vibration button directly invokes vibration on devices that support it. + + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "SysSoundViewController.h" + +@implementation SysSoundViewController + +@synthesize soundFileURLRef; +@synthesize soundFileObject; + + +- (void) viewDidLoad { + + [super viewDidLoad]; + + // Provide a nice background for the app user interface. + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; + + // Create the URL for the source audio file. The URLForResource:withExtension: method is + // new in iOS 4.0. + NSURL *tapSound = [[NSBundle mainBundle] URLForResource: @"tap" + withExtension: @"aif"]; + + // Store the URL as a CFURLRef instance + self.soundFileURLRef = (CFURLRef) [tapSound retain]; + + // Create a system sound object representing the sound file. + AudioServicesCreateSystemSoundID ( + + soundFileURLRef, + &soundFileObject + ); +} + + +// Respond to a tap on the System Sound button. +- (IBAction) playSystemSound: (id) sender { + + AudioServicesPlaySystemSound (soundFileObject); +} + + +// Respond to a tap on the Alert Sound button. +- (IBAction) playAlertSound: (id) sender { + + AudioServicesPlayAlertSound (soundFileObject); +} + + +// Respond to a tap on the Vibrate button. In the Simulator and on devices with no +// vibration element, this method does nothing. +- (IBAction) vibrate: (id) sender { + + AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); +} + + +- (void) dealloc { + + AudioServicesDisposeSystemSoundID (soundFileObject); + CFRelease (soundFileURLRef); + [super dealloc]; +} + +@end diff --git a/SysSound/Info.plist b/SysSound/Info.plist new file mode 100644 index 0000000..faa3500 --- /dev/null +++ b/SysSound/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/SysSound/ReadMe.txt b/SysSound/ReadMe.txt new file mode 100644 index 0000000..6f8f8ff --- /dev/null +++ b/SysSound/ReadMe.txt @@ -0,0 +1,91 @@ +SysSound + +=========================================================================== +DESCRIPTION: + +SysSound demonstrates basic use of System Sound Services (declared in AudioToolbox/AudioServices.h) for playing short sounds and invoking vibration. + + + NOTE: System Sound Services is intended for user-interface + sound effects and user alerts. It is not intended for sound + effects in games. For game sound playback, or for any + playback needs beyond user-interface sound effects and + alerts, use OpenAL, the AVAudioPlayer class, Audio Queue + Services, or audio units. + + NOTE: There are no built-in sounds or alerts available in + iOS 4.0. When using System Sound Services, provide your own + sound files. + + +The code in this sample project includes three playback methods. + +* The -playSystemSound: method uses the AudioServicesPlaySystemSound function to play a system sound in response to a button tap. + +* The -playAlertSound: method uses the AudioServicesPlayAlertSound function to play the same system sound, but as an alert. On devices that include a vibration element, this function simultaneously invokes vibration if the user has configured the "Ring" settings to include vibration. On other iOS devices, this function plays an alert melody in lieu of the specified sound file. + +* The -vibrate: method uses the AudioServicesPlaySystemSound function to explicitly invoke vibration on the device in response to a button tap. It does this by passing the vibration constant rather than a system sound object. + +To create a system sound object for playback, first create a CFURLRef object that points to the sound file you want to play. SysSound shows how to do this and also demonstrates where in the file system you should place sound files. + +SysSound does not demonstrate using system sound object properties or how to use the sound completion callback. + + +=========================================================================== +RELATED INFORMATION: + +To learn about System Sound Services, including important information on its lack of participation with the audio session API, refer to the following documents: + +Multimedia Programming Guide, May 2010 +System Sound Services Reference, October 2009 + +For an example of how to play sounds other than user-interface sound effects and alerts, see the following sample code project: + +avTouch + + +=========================================================================== +SPECIAL CONSIDERATIONS: + +iOS ignores the vibration constant when running on devices that do not have a vibration element. For example, calling the AudioServicesPlaySystemSound function with the vibration constant on an iPod touch does nothing. + +In the Simulator, clicking the Vibrate button in the application's user interface does nothing. + + +=========================================================================== +BUILD REQUIREMENTS: + +Mac OS X v10.6.4, Xcode 3.2, iOS 4.0 or later + + +=========================================================================== +RUNTIME REQUIREMENTS: + +Simulator: Mac OS X v10.5.4 or later +Device: iOS 4.0 or later + + +=========================================================================== +PACKAGING LIST: + +SysSoundAppDelegate.h +SysSoundAppDelegate.m + +The SysSoundAppDelegate class defines the application delegate object, responsible for instantiating the controller object (defined in the SysSoundViewController class) and adding the application's view to the application window. + +SysSoundViewController.h +SysSoundViewController.m + +The SysSoundViewController class defines the controller object for the application. The object helps set up the user interface, responds to and manages user interaction, and implements sound playback and vibration. + + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.1, Upgraded project to build with the iOS 4.0 SDK. Other minor corrections and changes. + +Version 1.0, tested with iOS 2.1. Minor changes to project files. + + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/SysSound/Resources/en.lproj/MainWindow.xib b/SysSound/Resources/en.lproj/MainWindow.xib new file mode 100644 index 0000000..a707357 --- /dev/null +++ b/SysSound/Resources/en.lproj/MainWindow.xib @@ -0,0 +1,215 @@ + + + + 512 + 9D34 + 670 + 949.33 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + SysSoundViewController + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + viewController + + + + 11 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + SysSound App Delegate + + + -2 + + + + + 10 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + SysSoundViewController + {{512, 351}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{362, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SysSoundAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 11 + + + + YES + + SysSoundAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/SysSoundAppDelegate.h + + + + SysSoundAppDelegate + NSObject + + viewController + id + + + IBUserSource + + + + + SysSoundViewController + UIViewController + + IBProjectSource + Classes/SysSoundViewController.h + + + + + 0 + SysSound.xcodeproj + 3 + + diff --git a/SysSound/Resources/en.lproj/SysSoundViewController.xib b/SysSound/Resources/en.lproj/SysSoundViewController.xib new file mode 100644 index 0000000..4db8696 --- /dev/null +++ b/SysSound/Resources/en.lproj/SysSoundViewController.xib @@ -0,0 +1,399 @@ + + + + 512 + 9F33 + 677 + 949.34 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 256 + {{0, -20}, {320, 479.94}} + + NO + YES + 4 + YES + + NSImage + Background.png + + + + + 1828 + + {{20, 167}, {280, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + System Sound + System Sound + System Sound + System Sound + + 1 + MSAxIDEAA + + + 3 + MAA + + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + + + + 1828 + + {{20, 212}, {280, 37}} + + NO + NO + 0 + 0 + + 1 + Alert Sound + Alert Sound + Alert Sound + Alert Sound + + + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + + + + 1828 + + {{20, 257}, {280, 37}} + + NO + NO + 0 + 0 + + 1 + Vibration + Vibration + Vibration + Vibration + + + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + + + + 290 + {320, 44} + + NO + NO + + YES + + + SysSound + + + + + {320, 460} + + + 3 + MQA + + 2 + + + + + + + YES + + + view + + + + 3 + + + + playSystemSound: + + + 1 + + 21 + + + + playAlertSound: + + + 1 + + 22 + + + + vibrate: + + + 1 + + 23 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 6 + + + + + 11 + + + YES + + + + + + 12 + + + + + 10 + + + + + 13 + + + + + 15 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 1.IBUserGuides + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBAttributePlaceholdersKey + 13.IBPluginDependency + 15.IBAttributePlaceholdersKey + 15.IBPluginDependency + 6.IBAttributePlaceholdersKey + 6.IBPluginDependency + + + YES + SysSoundViewController + UIResponder + {{537, 296}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 23 + + + + YES + + SysSoundViewController + UIViewController + + YES + + YES + playAlertSound: + playSystemSound: + vibrate: + + + YES + id + id + id + + + + IBProjectSource + Classes/SysSoundViewController.h + + + + + 0 + ../SysSound.xcodeproj + 3 + + diff --git a/SysSound/Resources/images/Default.png b/SysSound/Resources/images/Default.png new file mode 100644 index 0000000..303a8a3 Binary files /dev/null and b/SysSound/Resources/images/Default.png differ diff --git a/SysSound/Resources/images/Icon-72.png b/SysSound/Resources/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/SysSound/Resources/images/Icon-72.png differ diff --git a/SysSound/Resources/images/Icon-Small-50.png b/SysSound/Resources/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/SysSound/Resources/images/Icon-Small-50.png differ diff --git a/SysSound/Resources/images/Icon-Small.png b/SysSound/Resources/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/SysSound/Resources/images/Icon-Small.png differ diff --git a/SysSound/Resources/images/Icon-Small@2x.png b/SysSound/Resources/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/SysSound/Resources/images/Icon-Small@2x.png differ diff --git a/SysSound/Resources/images/Icon.png b/SysSound/Resources/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/SysSound/Resources/images/Icon.png differ diff --git a/SysSound/Resources/images/Icon@2x.png b/SysSound/Resources/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/SysSound/Resources/images/Icon@2x.png differ diff --git a/SysSound/Resources/images/iTunesArtwork b/SysSound/Resources/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/SysSound/Resources/images/iTunesArtwork differ diff --git a/SysSound/Resources/sounds/tap.aif b/SysSound/Resources/sounds/tap.aif new file mode 100644 index 0000000..818676e Binary files /dev/null and b/SysSound/Resources/sounds/tap.aif differ diff --git a/SysSound/SysSound.xcodeproj/mrj.mode1v3 b/SysSound/SysSound.xcodeproj/mrj.mode1v3 new file mode 100644 index 0000000..89e80fa --- /dev/null +++ b/SysSound/SysSound.xcodeproj/mrj.mode1v3 @@ -0,0 +1,1408 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 0A3C0EC20E40031900799984 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-go + debugger-enable-breakpoints + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 22 + 239 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + SCMStatusColumn + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + 29B97317FDCFA39411CA2CEA + 19C28FACFE9D520D11CA2CBB + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 2 + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {261, 673}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {278, 691}} + GroupTreeTableConfiguration + + SCMStatusColumn + 22 + MainColumn + 239 + + RubberWindowFrame + 49 400 1151 732 0 0 1920 1178 + + Module + PBXSmartGroupTreeModule + Proportion + 278pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + SysSoundAppDelegate.h + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + SysSoundAppDelegate.h + _historyCapacity + 0 + bookmark + 0A58095811F394C8004F0A23 + history + + 0AA394D60E96FB3A0066BFDD + 0A3D9C4F10928F1B0037E96C + 0A58092C11F392D6004F0A23 + 0A58095511F394C8004F0A23 + 0A58095611F394C8004F0A23 + 0A58095711F394C8004F0A23 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {868, 686}} + RubberWindowFrame + 49 400 1151 732 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 686pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 691}, {868, 0}} + RubberWindowFrame + 49 400 1151 732 0 0 1920 1178 + + Module + XCDetailModule + Proportion + 0pt + + + Proportion + 868pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 0A58093F11F3939E004F0A23 + 1CE0B1FE06471DED0097A5F4 + 0A58094011F3939E004F0A23 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 0A58096011F394C8004F0A23 + 0A58096111F394C8004F0A23 + 1C78EAAD065D492600B07095 + 1CD10A99069EF8BA00B06720 + 0A3C0EC30E40031900799984 + /Volumes/mrj (tallinn)/Documents/Apple/projects/Aspen/03. Sample Code Work/SysSound project/SysSound/SysSound.xcodeproj + + WindowString + 49 400 1151 732 0 0 1920 1178 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1235, 227}} + RubberWindowFrame + 231 540 1235 509 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 227pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 232}, {1235, 236}} + RubberWindowFrame + 231 540 1235 509 0 0 1920 1178 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 468pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 0A3C0EC30E40031900799984 + 0A58094111F3939E004F0A23 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowString + 231 540 1235 509 0 0 1920 1178 + WindowToolGUID + 0A3C0EC30E40031900799984 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 266 649 694 422 0 0 1920 1178 + + RubberWindowFrame + 266 649 694 422 0 0 1920 1178 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 0A58095911F394C8004F0A23 + 1C162984064C10D400B95A72 + 0A58095A11F394C8004F0A23 + 0A58095B11F394C8004F0A23 + 0A58095C11F394C8004F0A23 + 0A58095D11F394C8004F0A23 + 0A58095E11F394C8004F0A23 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 266 649 694 422 0 0 1920 1178 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {781, 212}} + RubberWindowFrame + 56 285 781 470 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 212pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 217}, {781, 212}} + RubberWindowFrame + 56 285 781 470 0 0 1280 778 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 429pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 0ACF7F3F0E54F6C4001E9276 + 0ACF7F400E54F6C4001E9276 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 56 285 781 470 0 0 1280 778 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 209}} + RubberWindowFrame + 256 844 650 250 0 0 1920 1178 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 0A58095F11F394C8004F0A23 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 256 844 650 250 0 0 1920 1178 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + FirstTimeWindowDisplayed + + Identifier + windowTool.scm + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {749, 186}} + RubberWindowFrame + 156 45 749 710 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 186pt + + + BecomeActive + + ContentConfiguration + + PBXCVSModuleFilterTypeKey + 1032 + PBXCVSModuleTreeModuleColumnData + + PBXCVSModuleTreeModuleColumnWidthsKey + + 333 + 56 + 63 + 60 + 63 + 139 + + PBXCVSModuleTreeModuleColumnsKey + + Name + Status + Update + Revision + Author + Date + + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM Results + SCMActivityViewerShowingDefaultKey + {{0, 374}, {749, 104}} + + GeometryConfiguration + + Frame + {{0, 191}, {749, 478}} + RubberWindowFrame + 156 45 749 710 0 0 1280 778 + + Module + PBXCVSModule + Proportion + 478pt + + + Proportion + 669pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + + TableOfContents + + 0AA394DB0E96FB3A0066BFDD + 0ADBBB900EC8DB9600F3F34B + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 156 45 749 710 0 0 1280 778 + WindowToolGUID + 0AA394DB0E96FB3A0066BFDD + WindowToolIsVisible + + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/SysSound/SysSound.xcodeproj/project.pbxproj b/SysSound/SysSound.xcodeproj/project.pbxproj new file mode 100755 index 0000000..4e4d304 --- /dev/null +++ b/SysSound/SysSound.xcodeproj/project.pbxproj @@ -0,0 +1,343 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 0A1104470E2C059D0000B08D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A1104460E2C059D0000B08D /* AudioToolbox.framework */; }; + 0A5808E111F38FF6004F0A23 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808D111F38FF6004F0A23 /* MainWindow.xib */; }; + 0A5808E211F38FF6004F0A23 /* SysSoundViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808D311F38FF6004F0A23 /* SysSoundViewController.xib */; }; + 0A5808E411F38FF6004F0A23 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808D711F38FF6004F0A23 /* Default.png */; }; + 0A5808E511F38FF6004F0A23 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808D811F38FF6004F0A23 /* Icon-72.png */; }; + 0A5808E611F38FF6004F0A23 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808D911F38FF6004F0A23 /* Icon-Small-50.png */; }; + 0A5808E711F38FF6004F0A23 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808DA11F38FF6004F0A23 /* Icon-Small.png */; }; + 0A5808E811F38FF6004F0A23 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808DB11F38FF6004F0A23 /* Icon-Small@2x.png */; }; + 0A5808E911F38FF6004F0A23 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808DC11F38FF6004F0A23 /* Icon.png */; }; + 0A5808EA11F38FF6004F0A23 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808DD11F38FF6004F0A23 /* Icon@2x.png */; }; + 0A5808EB11F38FF6004F0A23 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808DE11F38FF6004F0A23 /* iTunesArtwork */; }; + 0A5808EC11F38FF6004F0A23 /* tap.aif in Resources */ = {isa = PBXBuildFile; fileRef = 0A5808E011F38FF6004F0A23 /* tap.aif */; }; + 1D3623260D0F684500981E51 /* SysSoundAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SysSoundAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28D7ACF80DDB3853001CB0EB /* SysSoundViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* SysSoundViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0A1104460E2C059D0000B08D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 0A5808D211F38FF6004F0A23 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = MainWindow.xib; sourceTree = ""; }; + 0A5808D411F38FF6004F0A23 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = SysSoundViewController.xib; sourceTree = ""; }; + 0A5808D611F38FF6004F0A23 /* Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Background.png; sourceTree = ""; }; + 0A5808D711F38FF6004F0A23 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 0A5808D811F38FF6004F0A23 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 0A5808D911F38FF6004F0A23 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 0A5808DA11F38FF6004F0A23 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 0A5808DB11F38FF6004F0A23 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 0A5808DC11F38FF6004F0A23 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 0A5808DD11F38FF6004F0A23 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 0A5808DE11F38FF6004F0A23 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 0A5808E011F38FF6004F0A23 /* tap.aif */ = {isa = PBXFileReference; lastKnownFileType = file; path = tap.aif; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* SysSoundAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SysSoundAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* SysSoundAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SysSoundAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* SysSound.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SysSound.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28D7ACF60DDB3853001CB0EB /* SysSoundViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SysSoundViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* SysSoundViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SysSoundViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* SysSound_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SysSound_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 0A1104470E2C059D0000B08D /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* SysSoundAppDelegate.h */, + 1D3623250D0F684500981E51 /* SysSoundAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* SysSoundViewController.h */, + 28D7ACF70DDB3853001CB0EB /* SysSoundViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 0A5808D011F38FF6004F0A23 /* en.lproj */ = { + isa = PBXGroup; + children = ( + 0A5808D111F38FF6004F0A23 /* MainWindow.xib */, + 0A5808D311F38FF6004F0A23 /* SysSoundViewController.xib */, + ); + name = en.lproj; + path = Resources/en.lproj; + sourceTree = ""; + }; + 0A5808D511F38FF6004F0A23 /* images */ = { + isa = PBXGroup; + children = ( + 0A5808D611F38FF6004F0A23 /* Background.png */, + 0A5808D711F38FF6004F0A23 /* Default.png */, + 0A5808D811F38FF6004F0A23 /* Icon-72.png */, + 0A5808D911F38FF6004F0A23 /* Icon-Small-50.png */, + 0A5808DA11F38FF6004F0A23 /* Icon-Small.png */, + 0A5808DB11F38FF6004F0A23 /* Icon-Small@2x.png */, + 0A5808DC11F38FF6004F0A23 /* Icon.png */, + 0A5808DD11F38FF6004F0A23 /* Icon@2x.png */, + 0A5808DE11F38FF6004F0A23 /* iTunesArtwork */, + ); + name = images; + path = Resources/images; + sourceTree = ""; + }; + 0A5808DF11F38FF6004F0A23 /* sounds */ = { + isa = PBXGroup; + children = ( + 0A5808E011F38FF6004F0A23 /* tap.aif */, + ); + name = sounds; + path = Resources/sounds; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SysSound.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* SysSound_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* Info.plist */, + 0A5808D011F38FF6004F0A23 /* en.lproj */, + 0A5808D511F38FF6004F0A23 /* images */, + 0A5808DF11F38FF6004F0A23 /* sounds */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0A1104460E2C059D0000B08D /* AudioToolbox.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SysSound */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SysSound" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SysSound; + productName = SysSound; + productReference = 1D6058910D05DD3D006BFB54 /* SysSound.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SysSound" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SysSound */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A5808E111F38FF6004F0A23 /* MainWindow.xib in Resources */, + 0A5808E211F38FF6004F0A23 /* SysSoundViewController.xib in Resources */, + 0A5808E411F38FF6004F0A23 /* Default.png in Resources */, + 0A5808E511F38FF6004F0A23 /* Icon-72.png in Resources */, + 0A5808E611F38FF6004F0A23 /* Icon-Small-50.png in Resources */, + 0A5808E711F38FF6004F0A23 /* Icon-Small.png in Resources */, + 0A5808E811F38FF6004F0A23 /* Icon-Small@2x.png in Resources */, + 0A5808E911F38FF6004F0A23 /* Icon.png in Resources */, + 0A5808EA11F38FF6004F0A23 /* Icon@2x.png in Resources */, + 0A5808EB11F38FF6004F0A23 /* iTunesArtwork in Resources */, + 0A5808EC11F38FF6004F0A23 /* tap.aif in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* SysSoundAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* SysSoundViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 0A5808D111F38FF6004F0A23 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 0A5808D211F38FF6004F0A23 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 0A5808D311F38FF6004F0A23 /* SysSoundViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 0A5808D411F38FF6004F0A23 /* en */, + ); + name = SysSoundViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SysSound_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = SysSound; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SysSound_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = SysSound; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Murray Jason"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "C4A00DD6-671B-432A-B53F-EE0E07CDAA84"; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SysSound" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SysSound" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/SysSound/SysSound_Prefix.pch b/SysSound/SysSound_Prefix.pch new file mode 100644 index 0000000..fe1e61d --- /dev/null +++ b/SysSound/SysSound_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'SysSound' target in the 'SysSound' project +// + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/SysSound/main.m b/SysSound/main.m new file mode 100644 index 0000000..10c697f --- /dev/null +++ b/SysSound/main.m @@ -0,0 +1,56 @@ +/* + File: main.m +Abstract: n/a + Version: 1.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableSearch.zip b/TableSearch.zip new file mode 100644 index 0000000..a628aef Binary files /dev/null and b/TableSearch.zip differ diff --git a/TableSearch/AppDelegate.h b/TableSearch/AppDelegate.h new file mode 100755 index 0000000..2c32d66 --- /dev/null +++ b/TableSearch/AppDelegate.h @@ -0,0 +1,57 @@ +/* + File: AppDelegate.h + Abstract: The application delegate used to configure the navigation controller. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navController; + +@end diff --git a/TableSearch/AppDelegate.m b/TableSearch/AppDelegate.m new file mode 100755 index 0000000..9a4e3d5 --- /dev/null +++ b/TableSearch/AppDelegate.m @@ -0,0 +1,99 @@ + +/* + File: AppDelegate.m + Abstract: The application delegate used to configure the navigation controller. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MainViewController.h" +#import "Product.h" + +@implementation AppDelegate; + +@synthesize window, navController; + +- (void)dealloc +{ + [navController release]; + [window release]; + [super dealloc]; +} + + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // Create and configure the window, navigation controller, and main view controller. + + // Create the master list for the main view controller. + NSArray *listContent = [[NSArray alloc] initWithObjects: + [Product productWithType:@"Device" name:@"iPhone"], + [Product productWithType:@"Device" name:@"iPod"], + [Product productWithType:@"Device" name:@"iPod touch"], + [Product productWithType:@"Desktop" name:@"iMac"], + [Product productWithType:@"Desktop" name:@"Mac Pro"], + [Product productWithType:@"Portable" name:@"iBook"], + [Product productWithType:@"Portable" name:@"MacBook"], + [Product productWithType:@"Portable" name:@"MacBook Pro"], + [Product productWithType:@"Portable" name:@"PowerBook"], nil]; + + + // Create and configure the main view controller. + MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil]; + mainViewController.listContent = listContent; + [listContent release]; + + // Add create and configure the navigation controller. + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController]; + self.navController = navigationController; + [mainViewController release]; + [navigationController release]; + + // Configure and display the window. + [window addSubview:navController.view]; + [window makeKeyAndVisible]; +} + + +@end diff --git a/TableSearch/Images/Icon-Small.png b/TableSearch/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TableSearch/Images/Icon-Small.png differ diff --git a/TableSearch/Images/Icon-Small@2x.png b/TableSearch/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TableSearch/Images/Icon-Small@2x.png differ diff --git a/TableSearch/Images/Icon.png b/TableSearch/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TableSearch/Images/Icon.png differ diff --git a/TableSearch/Images/Icon@2x.png b/TableSearch/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TableSearch/Images/Icon@2x.png differ diff --git a/TableSearch/Images/iTunesArtwork.png b/TableSearch/Images/iTunesArtwork.png new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TableSearch/Images/iTunesArtwork.png differ diff --git a/TableSearch/Info.plist b/TableSearch/Info.plist new file mode 100755 index 0000000..f828d59 --- /dev/null +++ b/TableSearch/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Icon.png + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.5 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TableSearch/MainViewController.h b/TableSearch/MainViewController.h new file mode 100644 index 0000000..d9bbc55 --- /dev/null +++ b/TableSearch/MainViewController.h @@ -0,0 +1,66 @@ +/* + File: MainViewController.h + Abstract: Main table view controller for the application. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface MainViewController : UITableViewController +{ + NSArray *listContent; // The master content. + NSMutableArray *filteredListContent; // The content filtered as a result of a search. + + // The saved state of the search UI if a memory warning removed the view. + NSString *savedSearchTerm; + NSInteger savedScopeButtonIndex; + BOOL searchWasActive; +} + +@property (nonatomic, retain) NSArray *listContent; +@property (nonatomic, retain) NSMutableArray *filteredListContent; + +@property (nonatomic, copy) NSString *savedSearchTerm; +@property (nonatomic) NSInteger savedScopeButtonIndex; +@property (nonatomic) BOOL searchWasActive; + +@end diff --git a/TableSearch/MainViewController.m b/TableSearch/MainViewController.m new file mode 100644 index 0000000..1388459 --- /dev/null +++ b/TableSearch/MainViewController.m @@ -0,0 +1,226 @@ +/* + File: MainViewController.m + Abstract: Main table view controller for the application. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MainViewController.h" +#import "Product.h" + +@implementation MainViewController + +@synthesize listContent, filteredListContent, savedSearchTerm, savedScopeButtonIndex, searchWasActive; + + +#pragma mark - +#pragma mark Lifecycle methods + +- (void)viewDidLoad +{ + self.title = @"Products"; + + // create a filtered list that will contain products for the search results table. + self.filteredListContent = [NSMutableArray arrayWithCapacity:[self.listContent count]]; + + // restore search settings if they were saved in didReceiveMemoryWarning. + if (self.savedSearchTerm) + { + [self.searchDisplayController setActive:self.searchWasActive]; + [self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex]; + [self.searchDisplayController.searchBar setText:savedSearchTerm]; + + self.savedSearchTerm = nil; + } + + [self.tableView reloadData]; + self.tableView.scrollEnabled = YES; +} + +- (void)viewDidUnload +{ + self.filteredListContent = nil; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + // save the state of the search UI so that it can be restored if the view is re-created + self.searchWasActive = [self.searchDisplayController isActive]; + self.savedSearchTerm = [self.searchDisplayController.searchBar text]; + self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex]; +} + +- (void)dealloc +{ + [listContent release]; + [filteredListContent release]; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark UITableView data source and delegate methods + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + /* + If the requesting table view is the search display controller's table view, return the count of + the filtered list, otherwise return the count of the main list. + */ + if (tableView == self.searchDisplayController.searchResultsTableView) + { + return [self.filteredListContent count]; + } + else + { + return [self.listContent count]; + } +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kCellID = @"cellID"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + + /* + If the requesting table view is the search display controller's table view, configure the cell using the filtered content, otherwise use the main list. + */ + Product *product = nil; + if (tableView == self.searchDisplayController.searchResultsTableView) + { + product = [self.filteredListContent objectAtIndex:indexPath.row]; + } + else + { + product = [self.listContent objectAtIndex:indexPath.row]; + } + + cell.textLabel.text = product.name; + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + UIViewController *detailsViewController = [[UIViewController alloc] init]; + + /* + If the requesting table view is the search display controller's table view, configure the next view controller using the filtered content, otherwise use the main list. + */ + Product *product = nil; + if (tableView == self.searchDisplayController.searchResultsTableView) + { + product = [self.filteredListContent objectAtIndex:indexPath.row]; + } + else + { + product = [self.listContent objectAtIndex:indexPath.row]; + } + detailsViewController.title = product.name; + + [[self navigationController] pushViewController:detailsViewController animated:YES]; + [detailsViewController release]; +} + + +#pragma mark - +#pragma mark Content Filtering + +- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope +{ + /* + Update the filtered array based on the search text and scope. + */ + + [self.filteredListContent removeAllObjects]; // First clear the filtered array. + + /* + Search the main list for products whose type matches the scope (if selected) and whose name matches searchText; add items that match to the filtered array. + */ + for (Product *product in listContent) + { + if ([scope isEqualToString:@"All"] || [product.type isEqualToString:scope]) + { + NSComparisonResult result = [product.name compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])]; + if (result == NSOrderedSame) + { + [self.filteredListContent addObject:product]; + } + } + } +} + + +#pragma mark - +#pragma mark UISearchDisplayController Delegate Methods + +- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString +{ + [self filterContentForSearchText:searchString scope: + [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]]; + + // Return YES to cause the search result table view to be reloaded. + return YES; +} + + +- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption +{ + [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope: + [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]]; + + // Return YES to cause the search result table view to be reloaded. + return YES; +} + + +@end + diff --git a/TableSearch/Prefix.pch b/TableSearch/Prefix.pch new file mode 100755 index 0000000..4572cf6 --- /dev/null +++ b/TableSearch/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif \ No newline at end of file diff --git a/TableSearch/Product.h b/TableSearch/Product.h new file mode 100644 index 0000000..b9e36e3 --- /dev/null +++ b/TableSearch/Product.h @@ -0,0 +1,57 @@ +/* + File: Product.h + Abstract: Simple class to represent a product, with a product type and name. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface Product : NSObject { + NSString *type; + NSString *name; +} + +@property (nonatomic, copy) NSString *type, *name; + ++ (id)productWithType:(NSString *)type name:(NSString *)name; + +@end diff --git a/TableSearch/Product.m b/TableSearch/Product.m new file mode 100644 index 0000000..2792d99 --- /dev/null +++ b/TableSearch/Product.m @@ -0,0 +1,72 @@ + +/* + File: Product.m + Abstract: Simple class to represent a product, with a product type and name. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Product.h" + +@implementation Product + +@synthesize type, name; + + ++ (id)productWithType:(NSString *)type name:(NSString *)name +{ + Product *newProduct = [[[self alloc] init] autorelease]; + newProduct.type = type; + newProduct.name = name; + return newProduct; +} + + +- (void)dealloc +{ + [type release]; + [name release]; + [super dealloc]; +} + +@end diff --git a/TableSearch/ReadMe.txt b/TableSearch/ReadMe.txt new file mode 100644 index 0000000..b9a7908 --- /dev/null +++ b/TableSearch/ReadMe.txt @@ -0,0 +1,42 @@ +TableSearch + +This sample demonstrates how to use the UISearchDisplayController object in conjunction with a UISearchBar, effectively filtering in and out the contents of that table. If an iPhone/iPod Touch application has large amounts of table data, this sample shows how to filter it down to a manageable amount if memory usage is a concern or you just want users to scroll through less content in a table. + +It shows how you can: +- Create a UISearchDisplayController. +- Use the new scopes on UISearchBar with a search display controller. +- Manage the interaction between the search display controller and a containing UINavigationController + (there is no code for this -- the navigation bar is moved around as necessary). +- Return different results for the main table view and the search display controller's table view. +- Handle the destruction and re-creation of a search display controller when receiving a memory warning. + + +Build Requirements +iOS SDK 4.0. + + +Runtime Requirements +iOS 4.0. + + +Using the Sample +Build and run TableSearch using Xcode. To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. When launched tap the search field and as you enter case insensitive text the list shinks/expands based on the filter text. An empty string will show the entire contents. To get back the entire contents once you have filtered the content, touch the search bar again, click the clear ('x') button and hit cancel. + + +Packaging List +AppDelegate.{h,m} - The application's delegate to setup its window and content. +MainViewController.{h,m} - Manages a table view to display a list of products, and manages a search bar to filter the product list. +Product.{h,m} - A simple model file to represent a product with a name and type. +main.m - Main source file for this sample. + + +Changes from Previous Versions +1.5 - Upgraded project to build with the iOS 4 SDK. +1.4 - Fixed problem with saving state during low memory warnings. +1.3 - Updated UISearchBar and UISearchDisplayController as nib objects. +1.2 - Upgraded to use UISearchDisplayController and iPhone OS 3.0. +1.1 - Minor user interface upgrades, no longer using UINavigationController; UISearchBar takes it's place. +1.0 - Updated for and tested with iPhone OS 2.0. First public release. + + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/TableSearch/TableSearch.xcodeproj/project.pbxproj b/TableSearch/TableSearch.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9f35f21 --- /dev/null +++ b/TableSearch/TableSearch.xcodeproj/project.pbxproj @@ -0,0 +1,324 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 531F16A90D6367A3003D33FB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 531F16990D6367A3003D33FB /* AppDelegate.m */; }; + 533407750E06E7DD009822AC /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 533407740E06E7DD009822AC /* MainViewController.m */; }; + 5391030D0F8BDD5C00ED14FA /* Product.m in Sources */ = {isa = PBXBuildFile; fileRef = 5391030C0F8BDD5C00ED14FA /* Product.m */; }; + 539103140F8BDD8500ED14FA /* MainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 539103120F8BDD8500ED14FA /* MainView.xib */; }; + 539168B00DCFA64400D8C6CB /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 539168AE0DCFA64400D8C6CB /* MainWindow.xib */; }; + 53A66D3F0E0842EF009C8489 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53A66D3E0E0842EF009C8489 /* CoreGraphics.framework */; }; + 7E3705A711CAC39100F5DB11 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E3705A211CAC39100F5DB11 /* Icon-Small.png */; }; + 7E3705A811CAC39100F5DB11 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E3705A311CAC39100F5DB11 /* Icon-Small@2x.png */; }; + 7E3705A911CAC39100F5DB11 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E3705A411CAC39100F5DB11 /* Icon.png */; }; + 7E3705AA11CAC39100F5DB11 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E3705A511CAC39100F5DB11 /* Icon@2x.png */; }; + 7E3705AB11CAC39100F5DB11 /* iTunesArtwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E3705A611CAC39100F5DB11 /* iTunesArtwork.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* TableSearch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TableSearch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 531F16910D63677B003D33FB /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 531F16990D6367A3003D33FB /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 531F16A40D6367A3003D33FB /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 533407730E06E7DD009822AC /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 533407740E06E7DD009822AC /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 5391030B0F8BDD5C00ED14FA /* Product.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Product.h; sourceTree = ""; }; + 5391030C0F8BDD5C00ED14FA /* Product.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Product.m; sourceTree = ""; }; + 539103130F8BDD8500ED14FA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainView.xib; sourceTree = ""; }; + 539168AF0DCFA64400D8C6CB /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 53A66D3E0E0842EF009C8489 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 53FEEEAE0DCFAC0A004B8231 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 7E3705A211CAC39100F5DB11 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + 7E3705A311CAC39100F5DB11 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + 7E3705A411CAC39100F5DB11 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + 7E3705A511CAC39100F5DB11 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + 7E3705A611CAC39100F5DB11 /* iTunesArtwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iTunesArtwork.png; path = Images/iTunesArtwork.png; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 53A66D3F0E0842EF009C8489 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 53A66D3E0E0842EF009C8489 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* TableSearch.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Toolbar */ = { + isa = PBXGroup; + children = ( + 53FEEEAE0DCFAC0A004B8231 /* ReadMe.txt */, + 29B97315FDCFA39411CA2CEA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = Toolbar; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Sources */ = { + isa = PBXGroup; + children = ( + 531F16910D63677B003D33FB /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 531F16A40D6367A3003D33FB /* AppDelegate.h */, + 531F16990D6367A3003D33FB /* AppDelegate.m */, + 533407730E06E7DD009822AC /* MainViewController.h */, + 533407740E06E7DD009822AC /* MainViewController.m */, + 5391030B0F8BDD5C00ED14FA /* Product.h */, + 5391030C0F8BDD5C00ED14FA /* Product.m */, + ); + name = Sources; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 7E3704FC11CAA35A00F5DB11 /* Images */, + 539168AE0DCFA64400D8C6CB /* MainWindow.xib */, + 539103120F8BDD8500ED14FA /* MainView.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7E3704FC11CAA35A00F5DB11 /* Images */ = { + isa = PBXGroup; + children = ( + 7E3705A211CAC39100F5DB11 /* Icon-Small.png */, + 7E3705A311CAC39100F5DB11 /* Icon-Small@2x.png */, + 7E3705A411CAC39100F5DB11 /* Icon.png */, + 7E3705A511CAC39100F5DB11 /* Icon@2x.png */, + 7E3705A611CAC39100F5DB11 /* iTunesArtwork.png */, + ); + name = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* TableSearch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TableSearch" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TableSearch; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* TableSearch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TableSearch" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* Toolbar */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* TableSearch */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 539168B00DCFA64400D8C6CB /* MainWindow.xib in Resources */, + 539103140F8BDD8500ED14FA /* MainView.xib in Resources */, + 7E3705A711CAC39100F5DB11 /* Icon-Small.png in Resources */, + 7E3705A811CAC39100F5DB11 /* Icon-Small@2x.png in Resources */, + 7E3705A911CAC39100F5DB11 /* Icon.png in Resources */, + 7E3705AA11CAC39100F5DB11 /* Icon@2x.png in Resources */, + 7E3705AB11CAC39100F5DB11 /* iTunesArtwork.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 531F16A90D6367A3003D33FB /* AppDelegate.m in Sources */, + 533407750E06E7DD009822AC /* MainViewController.m in Sources */, + 5391030D0F8BDD5C00ED14FA /* Product.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 539103120F8BDD8500ED14FA /* MainView.xib */ = { + isa = PBXVariantGroup; + children = ( + 539103130F8BDD8500ED14FA /* en */, + ); + name = MainView.xib; + sourceTree = ""; + }; + 539168AE0DCFA64400D8C6CB /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 539168AF0DCFA64400D8C6CB /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Applications; + PREBINDING = NO; + PRODUCT_NAME = TableSearch; + SDKROOT = iphoneos4.0; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Applications; + PREBINDING = NO; + PRODUCT_NAME = TableSearch; + SDKROOT = iphoneos4.0; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TableSearch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TableSearch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TableSearch/en.lproj/MainView.xib b/TableSearch/en.lproj/MainView.xib new file mode 100644 index 0000000..fb0f5b2 --- /dev/null +++ b/TableSearch/en.lproj/MainView.xib @@ -0,0 +1,249 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 290 + {320, 44} + + NO + 3 + YES + + 1 + + + YES + All + Device + Desktop + Portable + + + + {320, 460} + + + 1 + MSAxIDEAA + + NO + YES + NO + + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + + + + + YES + + + view + + + + 5 + + + + searchBar + + + + 9 + + + + searchDisplayController + + + + 10 + + + + searchContentsController + + + + 11 + + + + searchResultsDataSource + + + + 12 + + + + searchResultsDelegate + + + + 13 + + + + delegate + + + + 14 + + + + delegate + + + + 15 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 3 + + + YES + + + + + + 7 + + + + + 8 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 3.IBEditorWindowLastContentRect + 3.IBPluginDependency + 7.IBPluginDependency + + + YES + MainViewController + UIResponder + {{184, 349}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 16 + + + + YES + + MainViewController + UITableViewController + + IBProjectSource + MainViewController.h + + + + + 0 + ../TableSearch.xcodeproj + 3 + 3.0 + + diff --git a/TableSearch/en.lproj/MainWindow.xib b/TableSearch/en.lproj/MainWindow.xib new file mode 100644 index 0000000..ea3d340 --- /dev/null +++ b/TableSearch/en.lproj/MainWindow.xib @@ -0,0 +1,188 @@ + + + + 768 + 9J44 + 677 + 949.46 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 75 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + + 0 + ../TableSearch.xcodeproj + 3 + + diff --git a/TableSearch/main.m b/TableSearch/main.m new file mode 100755 index 0000000..1129bf7 --- /dev/null +++ b/TableSearch/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file for this sample. + Version: 1.5 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableViewSuite.zip b/TableViewSuite.zip new file mode 100644 index 0000000..46c32af Binary files /dev/null and b/TableViewSuite.zip differ diff --git a/TableViewSuite/1_SimpleTableView/Classes/RootViewController.h b/TableViewSuite/1_SimpleTableView/Classes/RootViewController.h new file mode 100644 index 0000000..e62060a --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/Classes/RootViewController.h @@ -0,0 +1,56 @@ + +/* + File: RootViewController.h + Abstract: View controller that sets up the table view and serves as the table view's data source and delegate. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface RootViewController : UITableViewController { + NSArray *timeZoneNames; +} + +@property (nonatomic, retain) NSArray *timeZoneNames; + +@end diff --git a/TableViewSuite/1_SimpleTableView/Classes/RootViewController.m b/TableViewSuite/1_SimpleTableView/Classes/RootViewController.m new file mode 100644 index 0000000..89f57b5 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/Classes/RootViewController.m @@ -0,0 +1,110 @@ + +/* + File: RootViewController.m + Abstract: View controller that sets up the table view and serves as the table view's data source and delegate. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "SimpleTableViewAppDelegate.h" + + +@implementation RootViewController + +@synthesize timeZoneNames; + + +- (void)viewDidLoad { + self.title = NSLocalizedString(@"Time Zones", @"Time Zones title"); +} + + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // There is only one section. + return 1; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // Return the number of time zone names. + return [timeZoneNames count]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *MyIdentifier = @"MyIdentifier"; + + // Try to retrieve from the table view a now-unused cell with the given identifier. + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; + + // If no cell is available, create a new one using the given identifier. + if (cell == nil) { + // Use the default cell style. + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; + } + + // Set up the cell. + NSString *timeZoneName = [timeZoneNames objectAtIndex:indexPath.row]; + cell.textLabel.text = timeZoneName; + + return cell; +} + +/* + To conform to Human Interface Guildelines, since selecting a row would have no effect (such as navigation), make sure that rows cannot be selected. + */ +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + return nil; +} + + +- (void)dealloc { + [timeZoneNames release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/1_SimpleTableView/Classes/SimpleTableViewAppDelegate.h b/TableViewSuite/1_SimpleTableView/Classes/SimpleTableViewAppDelegate.h new file mode 100755 index 0000000..19c32a6 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/Classes/SimpleTableViewAppDelegate.h @@ -0,0 +1,59 @@ + +/* + File: SimpleTableViewAppDelegate.h + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface SimpleTableViewAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +@end diff --git a/TableViewSuite/1_SimpleTableView/Classes/SimpleTableViewAppDelegate.m b/TableViewSuite/1_SimpleTableView/Classes/SimpleTableViewAppDelegate.m new file mode 100755 index 0000000..b66dac7 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/Classes/SimpleTableViewAppDelegate.m @@ -0,0 +1,91 @@ + + /* + File: SimpleTableViewAppDelegate.m + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SimpleTableViewAppDelegate.h" +#import "RootViewController.h" + + +@implementation SimpleTableViewAppDelegate + +@synthesize window; +@synthesize navigationController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + /* + Create and configure the navigation and view controllers. + */ + + RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; + + // Retrieve the array of known time zone names, then sort the array and pass it to the root view controller. + NSArray *timeZones = [NSTimeZone knownTimeZoneNames]; + rootViewController.timeZoneNames = [timeZones sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + + UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + self.navigationController = aNavigationController; + [aNavigationController release]; + [rootViewController release]; + + // Configure and display the window. + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/1_SimpleTableView/Info.plist b/TableViewSuite/1_SimpleTableView/Info.plist new file mode 100755 index 0000000..ed44605 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + SimpleTableView + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TableViewSuite/1_SimpleTableView/SimpleTableView.xcodeproj/project.pbxproj b/TableViewSuite/1_SimpleTableView/SimpleTableView.xcodeproj/project.pbxproj new file mode 100755 index 0000000..5cb3adc --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/SimpleTableView.xcodeproj/project.pbxproj @@ -0,0 +1,328 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28589E0B0D62784500B31E57 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28589E0A0D62784500B31E57 /* RootViewController.m */; }; + 28D9174C0DCB8E6600DA1262 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 28D9174A0DCB8E6600DA1262 /* Localizable.strings */; }; + 28F1A8410DC9357000332FD8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28F1A8400DC9357000332FD8 /* CoreGraphics.framework */; }; + 2DED9DE00D59266800890EDD /* SimpleTableViewAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DED9DDE0D59266800890EDD /* SimpleTableViewAppDelegate.m */; }; + 533088EC11D3DAE200FAABF5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088E411D3DAE200FAABF5 /* Default.png */; }; + 533088ED11D3DAE200FAABF5 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088E511D3DAE200FAABF5 /* Icon-72.png */; }; + 533088EE11D3DAE200FAABF5 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088E611D3DAE200FAABF5 /* Icon-Small-50.png */; }; + 533088EF11D3DAE200FAABF5 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088E711D3DAE200FAABF5 /* Icon-Small.png */; }; + 533088F011D3DAE200FAABF5 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088E811D3DAE200FAABF5 /* Icon-Small@2x.png */; }; + 533088F111D3DAE200FAABF5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088E911D3DAE200FAABF5 /* Icon.png */; }; + 533088F211D3DAE200FAABF5 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088EA11D3DAE200FAABF5 /* Icon@2x.png */; }; + 533088F311D3DAE200FAABF5 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 533088EB11D3DAE200FAABF5 /* iTunesArtwork */; }; + 537EA91A11C82EE30019DB41 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537EA91811C82EE20019DB41 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* SimpleTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleTableView.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28589E090D62784500B31E57 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28589E0A0D62784500B31E57 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28D9174B0DCB8E6600DA1262 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A7860DC934EC00332FD8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ReadMe.txt; path = ../ReadMe.txt; sourceTree = SOURCE_ROOT; }; + 28F1A8400DC9357000332FD8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2DED9DDE0D59266800890EDD /* SimpleTableViewAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleTableViewAppDelegate.m; sourceTree = ""; }; + 2DED9DDF0D59266800890EDD /* SimpleTableViewAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleTableViewAppDelegate.h; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* SimpleTableView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleTableView_Prefix.pch; sourceTree = ""; }; + 533088E411D3DAE200FAABF5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 533088E511D3DAE200FAABF5 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 533088E611D3DAE200FAABF5 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 533088E711D3DAE200FAABF5 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 533088E811D3DAE200FAABF5 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 533088E911D3DAE200FAABF5 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 533088EA11D3DAE200FAABF5 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 533088EB11D3DAE200FAABF5 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 537EA91911C82EE20019DB41 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 28F1A8410DC9357000332FD8 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 28589E090D62784500B31E57 /* RootViewController.h */, + 28589E0A0D62784500B31E57 /* RootViewController.m */, + 2DED9DDF0D59266800890EDD /* SimpleTableViewAppDelegate.h */, + 2DED9DDE0D59266800890EDD /* SimpleTableViewAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SimpleTableView.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28F1A7860DC934EC00332FD8 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* SimpleTableView_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 533088E311D3DAE200FAABF5 /* images */, + 537EA91811C82EE20019DB41 /* MainWindow.xib */, + 28D9174A0DCB8E6600DA1262 /* Localizable.strings */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 28F1A8400DC9357000332FD8 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 533088E311D3DAE200FAABF5 /* images */ = { + isa = PBXGroup; + children = ( + 533088E411D3DAE200FAABF5 /* Default.png */, + 533088E511D3DAE200FAABF5 /* Icon-72.png */, + 533088E611D3DAE200FAABF5 /* Icon-Small-50.png */, + 533088E711D3DAE200FAABF5 /* Icon-Small.png */, + 533088E811D3DAE200FAABF5 /* Icon-Small@2x.png */, + 533088E911D3DAE200FAABF5 /* Icon.png */, + 533088EA11D3DAE200FAABF5 /* Icon@2x.png */, + 533088EB11D3DAE200FAABF5 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SimpleTableView */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleTableView" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SimpleTableView; + productName = SimpleTableView; + productReference = 1D6058910D05DD3D006BFB54 /* SimpleTableView.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleTableView" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SimpleTableView */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28D9174C0DCB8E6600DA1262 /* Localizable.strings in Resources */, + 537EA91A11C82EE30019DB41 /* MainWindow.xib in Resources */, + 533088EC11D3DAE200FAABF5 /* Default.png in Resources */, + 533088ED11D3DAE200FAABF5 /* Icon-72.png in Resources */, + 533088EE11D3DAE200FAABF5 /* Icon-Small-50.png in Resources */, + 533088EF11D3DAE200FAABF5 /* Icon-Small.png in Resources */, + 533088F011D3DAE200FAABF5 /* Icon-Small@2x.png in Resources */, + 533088F111D3DAE200FAABF5 /* Icon.png in Resources */, + 533088F211D3DAE200FAABF5 /* Icon@2x.png in Resources */, + 533088F311D3DAE200FAABF5 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2DED9DE00D59266800890EDD /* SimpleTableViewAppDelegate.m in Sources */, + 28589E0B0D62784500B31E57 /* RootViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 28D9174A0DCB8E6600DA1262 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 28D9174B0DCB8E6600DA1262 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 537EA91811C82EE20019DB41 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 537EA91911C82EE20019DB41 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleTableView_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Applications; + PREBINDING = NO; + PRODUCT_NAME = SimpleTableView; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleTableView_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = SimpleTableView; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleTableView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleTableView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TableViewSuite/1_SimpleTableView/SimpleTableView_Prefix.pch b/TableViewSuite/1_SimpleTableView/SimpleTableView_Prefix.pch new file mode 100755 index 0000000..342b9e0 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/SimpleTableView_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'SimpleTableView' target in the 'SimpleTableView' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TableViewSuite/1_SimpleTableView/en.lproj/Localizable.strings b/TableViewSuite/1_SimpleTableView/en.lproj/Localizable.strings new file mode 100644 index 0000000..9111b51 Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/en.lproj/Localizable.strings differ diff --git a/TableViewSuite/1_SimpleTableView/en.lproj/MainWindow.xib b/TableViewSuite/1_SimpleTableView/en.lproj/MainWindow.xib new file mode 100644 index 0000000..5d64955 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/en.lproj/MainWindow.xib @@ -0,0 +1,181 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + window + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + SimpleTableViewAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{596, 373}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SimpleTableViewAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + SimpleTableViewAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/SimpleTableViewAppDelegate.h + + + + + 0 + SimpleTableView.xcodeproj + 3 + + diff --git a/TableViewSuite/1_SimpleTableView/images/Default.png b/TableViewSuite/1_SimpleTableView/images/Default.png new file mode 100644 index 0000000..2807ead Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Default.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/Icon-72.png b/TableViewSuite/1_SimpleTableView/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Icon-72.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/Icon-Small-50.png b/TableViewSuite/1_SimpleTableView/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Icon-Small-50.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/Icon-Small.png b/TableViewSuite/1_SimpleTableView/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Icon-Small.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/Icon-Small@2x.png b/TableViewSuite/1_SimpleTableView/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Icon-Small@2x.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/Icon.png b/TableViewSuite/1_SimpleTableView/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Icon.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/Icon@2x.png b/TableViewSuite/1_SimpleTableView/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/Icon@2x.png differ diff --git a/TableViewSuite/1_SimpleTableView/images/iTunesArtwork b/TableViewSuite/1_SimpleTableView/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TableViewSuite/1_SimpleTableView/images/iTunesArtwork differ diff --git a/TableViewSuite/1_SimpleTableView/main.m b/TableViewSuite/1_SimpleTableView/main.m new file mode 100755 index 0000000..5d0bad3 --- /dev/null +++ b/TableViewSuite/1_SimpleTableView/main.m @@ -0,0 +1,56 @@ + + /* + File: main.m + Abstract: Main source file for this sample. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/Region.h b/TableViewSuite/2_SimpleSectionedTableView/Classes/Region.h new file mode 100644 index 0000000..a8bb956 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/Region.h @@ -0,0 +1,61 @@ + +/* + File: Region.h + Abstract: Object to represent a region containing the corresponding time zone wrappers. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +@interface Region : NSObject { + NSString *name; + NSMutableArray *timeZoneWrappers; +} + +@property (nonatomic, copy) NSString *name; +@property (nonatomic, retain) NSMutableArray *timeZoneWrappers; + ++ (NSArray *)knownRegions; + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/Region.m b/TableViewSuite/2_SimpleSectionedTableView/Classes/Region.m new file mode 100644 index 0000000..afe6e14 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/Region.m @@ -0,0 +1,168 @@ + +/* + File: Region.m + Abstract: Object to represent a region containing the corresponding time zone wrappers. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Region.h" +#import "TimeZoneWrapper.h" + + +@interface Region (Private) +- (id)initWithName:(NSString *)regionName; ++ (void)setUpKnownRegions; +- (void)addTimeZoneWrapper:(TimeZoneWrapper *)timeZoneWrapper; +- (void)sortTimeZones; +@end + + +@implementation Region + +@synthesize name, timeZoneWrappers; + +static NSMutableArray *knownRegions = nil; + + ++ (NSArray *)knownRegions { + + if (knownRegions == nil) { + [self setUpKnownRegions]; + } + return knownRegions; + +} + + +#pragma mark - +#pragma mark Memory management. + +- (void)dealloc { + [name release]; + [timeZoneWrappers release]; + [super dealloc]; +} + + +#pragma mark - +#pragma mark Private methods for setting up the regions. + +- (id)initWithName:(NSString *)regionName { + + if (self = [super init]) { + name = [regionName copy]; + timeZoneWrappers = [[NSMutableArray alloc] init]; + } + return self; +} + + ++ (void)setUpKnownRegions { + + NSArray *knownTimeZoneNames = [NSTimeZone knownTimeZoneNames]; + + NSMutableArray *regions = [[NSMutableArray alloc] initWithCapacity:[knownTimeZoneNames count]]; + + for (NSString *timeZoneName in knownTimeZoneNames) { + + NSArray *nameComponents = [timeZoneName componentsSeparatedByString:@"/"]; + NSString *regionName = [nameComponents objectAtIndex:0]; + + // Get the region with the region name, or create it if it doesn't exist. + Region *region = nil; + + for (Region *aRegion in regions) { + if ([aRegion.name isEqualToString:regionName]) { + region = aRegion; + break; + } + } + + if (region == nil) { + region = [[Region alloc] initWithName:regionName]; + [regions addObject:region]; + [region release]; + } + + NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName]; + TimeZoneWrapper *timeZoneWrapper = [[TimeZoneWrapper alloc] initWithTimeZone:timeZone nameComponents:nameComponents]; + [region addTimeZoneWrapper:timeZoneWrapper]; + [timeZoneWrapper release]; + } + + // Now sort the time zones by name + for (Region *aRegion in regions) { + [aRegion sortTimeZones]; + } + + // Sort the regions + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1]; + [regions sortUsingDescriptors:sortDescriptors]; + [sortDescriptor release]; + [sortDescriptors release]; + + knownRegions = regions; +} + + +- (void)addTimeZoneWrapper:(TimeZoneWrapper *)timeZoneWrapper { + [timeZoneWrappers addObject:timeZoneWrapper]; +} + + +- (void)sortTimeZones { + + // Sort the time zones by name + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"localeName" ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1]; + + [timeZoneWrappers sortUsingDescriptors:sortDescriptors]; + + [sortDescriptor release]; + [sortDescriptors release]; +} + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/RootViewController.h b/TableViewSuite/2_SimpleSectionedTableView/Classes/RootViewController.h new file mode 100644 index 0000000..2def42e --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/RootViewController.h @@ -0,0 +1,57 @@ + + /* + File: RootViewController.h + Abstract: View controller that sets up the table view and serves as the table view's data source and delegate. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +@interface RootViewController : UITableViewController { + NSArray *regions; +} + +@property (nonatomic, retain) NSArray *regions; + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/RootViewController.m b/TableViewSuite/2_SimpleSectionedTableView/Classes/RootViewController.m new file mode 100644 index 0000000..9ea0b7f --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/RootViewController.m @@ -0,0 +1,135 @@ + +/* + File: RootViewController.m + Abstract: View controller that sets up the table view and serves as the table view's data source and delegate. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "SimpleSectionedTableViewAppDelegate.h" +#import "Region.h" +#import "TimeZoneWrapper.h" + +NSString *localeNameForTimeZoneNameComponents(NSArray *nameComponents); +NSMutableDictionary *regionDictionaryWithNameInArray(NSString *name, NSArray *array); + + +@implementation RootViewController + + +@synthesize regions; + + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewDidLoad { + self.title = NSLocalizedString(@"Time Zones", @"Time Zones title"); +} + + +#pragma mark - +#pragma mark Table view data source methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // Number of sections is the number of regions. + return [regions count]; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // Number of rows is the number of time zones in the region for the specified section. + Region *region = [regions objectAtIndex:section]; + return [region.timeZoneWrappers count]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + // The header for the section is the region name -- get this from the region at the section index. + Region *region = [regions objectAtIndex:section]; + return [region name]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *MyIdentifier = @"MyIdentifier"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; + } + + // Get the section index, and so the region for that section. + Region *region = [regions objectAtIndex:indexPath.section]; + TimeZoneWrapper *timeZoneWrapper = [region.timeZoneWrappers objectAtIndex:indexPath.row]; + + // Set the cell's text to the name of the time zone at the row + cell.textLabel.text = timeZoneWrapper.localeName; + return cell; +} + + +#pragma mark - +#pragma mark Table view delegate method + +/* + To conform to Human Interface Guildelines, since selecting a row would have no effect (such as navigation), make sure that rows cannot be selected. + */ +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + return nil; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [regions release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.h b/TableViewSuite/2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.h new file mode 100755 index 0000000..5c0fd69 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.h @@ -0,0 +1,63 @@ + +/* + File: SimpleSectionedTableViewAppDelegate.h + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface SimpleSectionedTableViewAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; + + NSArray *list; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +@property (nonatomic, copy) NSArray *list; + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.m b/TableViewSuite/2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.m new file mode 100644 index 0000000..c67b301 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.m @@ -0,0 +1,88 @@ + +/* + File: SimpleSectionedTableViewAppDelegate.m + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SimpleSectionedTableViewAppDelegate.h" +#import "RootViewController.h" +#import "Region.h" + + +@implementation SimpleSectionedTableViewAppDelegate + +@synthesize window; +@synthesize navigationController; +@synthesize list; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Create the navigation and view controllers + RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; + UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + self.navigationController = aNavigationController; + [aNavigationController release]; + [rootViewController release]; + + [rootViewController setRegions:[Region knownRegions]]; + + // Configure and display the window + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [navigationController release]; + [window release]; + [list release]; + [super dealloc]; +} + + +@end + diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/TimeZoneWrapper.h b/TableViewSuite/2_SimpleSectionedTableView/Classes/TimeZoneWrapper.h new file mode 100644 index 0000000..8c0234a --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/TimeZoneWrapper.h @@ -0,0 +1,60 @@ + +/* + File: TimeZoneWrapper.h + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TimeZoneWrapper : NSObject { + NSString *localeName; + NSTimeZone *timeZone; +} + +@property (nonatomic, copy) NSString *localeName; +@property (nonatomic, retain) NSTimeZone *timeZone; + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents; + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Classes/TimeZoneWrapper.m b/TableViewSuite/2_SimpleSectionedTableView/Classes/TimeZoneWrapper.m new file mode 100644 index 0000000..eb7c21b --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Classes/TimeZoneWrapper.m @@ -0,0 +1,85 @@ + +/* + File: TimeZoneWrapper.m + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TimeZoneWrapper.h" + + +@implementation TimeZoneWrapper + +@synthesize localeName, timeZone; + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents { + + if (self = [super init]) { + + timeZone = [aTimeZone retain]; + + NSString *name = nil; + if ([nameComponents count] == 2) { + name = [nameComponents objectAtIndex:1]; + } + if ([nameComponents count] == 3) { + name = [NSString stringWithFormat:@"%@ (%@)", [nameComponents objectAtIndex:2], [nameComponents objectAtIndex:1]]; + } + + localeName = [[name stringByReplacingOccurrencesOfString:@"_" withString:@" "] retain]; + } + return self; +} + + +- (void)dealloc { + [localeName release]; + [timeZone release]; + + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/2_SimpleSectionedTableView/Info.plist b/TableViewSuite/2_SimpleSectionedTableView/Info.plist new file mode 100755 index 0000000..5f0ee9c --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + SimpleIndexedTableView + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TableViewSuite/2_SimpleSectionedTableView/SimpleSectionedTableView.xcodeproj/project.pbxproj b/TableViewSuite/2_SimpleSectionedTableView/SimpleSectionedTableView.xcodeproj/project.pbxproj new file mode 100755 index 0000000..ccb2668 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/SimpleSectionedTableView.xcodeproj/project.pbxproj @@ -0,0 +1,348 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 280173F80F7D316E0082ABE2 /* Region.m in Sources */ = {isa = PBXBuildFile; fileRef = 280173F70F7D316E0082ABE2 /* Region.m */; }; + 280174280F7D4AF30082ABE2 /* TimeZoneWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 280174270F7D4AF30082ABE2 /* TimeZoneWrapper.m */; }; + 28D9178A0DCB8FB200DA1262 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 28D917880DCB8FB200DA1262 /* Localizable.strings */; }; + 3B9137DF0D713F4000C0E354 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B9137DE0D713F4000C0E354 /* RootViewController.m */; }; + 533088CE11D3DAB800FAABF5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088C611D3DAB800FAABF5 /* Default.png */; }; + 533088CF11D3DAB800FAABF5 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088C711D3DAB800FAABF5 /* Icon-72.png */; }; + 533088D011D3DAB800FAABF5 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088C811D3DAB800FAABF5 /* Icon-Small-50.png */; }; + 533088D111D3DAB800FAABF5 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088C911D3DAB800FAABF5 /* Icon-Small.png */; }; + 533088D211D3DAB800FAABF5 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088CA11D3DAB800FAABF5 /* Icon-Small@2x.png */; }; + 533088D311D3DAB800FAABF5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088CB11D3DAB800FAABF5 /* Icon.png */; }; + 533088D411D3DAB800FAABF5 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088CC11D3DAB800FAABF5 /* Icon@2x.png */; }; + 533088D511D3DAB800FAABF5 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 533088CD11D3DAB800FAABF5 /* iTunesArtwork */; }; + 53E4CA3111C82F1C00FCFED2 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53E4CA2F11C82F1C00FCFED2 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleSectionedTableViewAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleSectionedTableViewAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* SimpleSectionedTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleSectionedTableView.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 280173F60F7D316E0082ABE2 /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Region.h; path = Classes/Region.h; sourceTree = ""; }; + 280173F70F7D316E0082ABE2 /* Region.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Region.m; path = Classes/Region.m; sourceTree = ""; }; + 280174260F7D4AF30082ABE2 /* TimeZoneWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimeZoneWrapper.h; path = Classes/TimeZoneWrapper.h; sourceTree = ""; }; + 280174270F7D4AF30082ABE2 /* TimeZoneWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TimeZoneWrapper.m; path = Classes/TimeZoneWrapper.m; sourceTree = ""; }; + 28D917890DCB8FB200DA1262 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A8600DC935EE00332FD8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ReadMe.txt; path = ../ReadMe.txt; sourceTree = SOURCE_ROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* SimpleSectionedTableView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleSectionedTableView_Prefix.pch; sourceTree = ""; }; + 3B9137DE0D713F4000C0E354 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 3B9137E10D713F5700C0E354 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 533088C611D3DAB800FAABF5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 533088C711D3DAB800FAABF5 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 533088C811D3DAB800FAABF5 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 533088C911D3DAB800FAABF5 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 533088CA11D3DAB800FAABF5 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 533088CB11D3DAB800FAABF5 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 533088CC11D3DAB800FAABF5 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 533088CD11D3DAB800FAABF5 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 53E4CA3011C82F1C00FCFED2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* View Controllers */ = { + isa = PBXGroup; + children = ( + 3B9137E10D713F5700C0E354 /* RootViewController.h */, + 3B9137DE0D713F4000C0E354 /* RootViewController.m */, + 1D3623240D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.h */, + 1D3623250D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.m */, + ); + name = "View Controllers"; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SimpleSectionedTableView.app */, + ); + name = Products; + sourceTree = ""; + }; + 280175050F7D57150082ABE2 /* Models */ = { + isa = PBXGroup; + children = ( + 280173F60F7D316E0082ABE2 /* Region.h */, + 280173F70F7D316E0082ABE2 /* Region.m */, + 280174260F7D4AF30082ABE2 /* TimeZoneWrapper.h */, + 280174270F7D4AF30082ABE2 /* TimeZoneWrapper.m */, + ); + name = Models; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28F1A8600DC935EE00332FD8 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* View Controllers */, + 280175050F7D57150082ABE2 /* Models */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* SimpleSectionedTableView_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 533088C511D3DAB800FAABF5 /* images */, + 53E4CA2F11C82F1C00FCFED2 /* MainWindow.xib */, + 28D917880DCB8FB200DA1262 /* Localizable.strings */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 533088C511D3DAB800FAABF5 /* images */ = { + isa = PBXGroup; + children = ( + 533088C611D3DAB800FAABF5 /* Default.png */, + 533088C711D3DAB800FAABF5 /* Icon-72.png */, + 533088C811D3DAB800FAABF5 /* Icon-Small-50.png */, + 533088C911D3DAB800FAABF5 /* Icon-Small.png */, + 533088CA11D3DAB800FAABF5 /* Icon-Small@2x.png */, + 533088CB11D3DAB800FAABF5 /* Icon.png */, + 533088CC11D3DAB800FAABF5 /* Icon@2x.png */, + 533088CD11D3DAB800FAABF5 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SimpleSectionedTableView */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleSectionedTableView" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SimpleSectionedTableView; + productName = SimpleSectionedTableView; + productReference = 1D6058910D05DD3D006BFB54 /* SimpleSectionedTableView.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleSectionedTableView" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SimpleSectionedTableView */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28D9178A0DCB8FB200DA1262 /* Localizable.strings in Resources */, + 53E4CA3111C82F1C00FCFED2 /* MainWindow.xib in Resources */, + 533088CE11D3DAB800FAABF5 /* Default.png in Resources */, + 533088CF11D3DAB800FAABF5 /* Icon-72.png in Resources */, + 533088D011D3DAB800FAABF5 /* Icon-Small-50.png in Resources */, + 533088D111D3DAB800FAABF5 /* Icon-Small.png in Resources */, + 533088D211D3DAB800FAABF5 /* Icon-Small@2x.png in Resources */, + 533088D311D3DAB800FAABF5 /* Icon.png in Resources */, + 533088D411D3DAB800FAABF5 /* Icon@2x.png in Resources */, + 533088D511D3DAB800FAABF5 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* SimpleSectionedTableViewAppDelegate.m in Sources */, + 3B9137DF0D713F4000C0E354 /* RootViewController.m in Sources */, + 280173F80F7D316E0082ABE2 /* Region.m in Sources */, + 280174280F7D4AF30082ABE2 /* TimeZoneWrapper.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 28D917880DCB8FB200DA1262 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 28D917890DCB8FB200DA1262 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 53E4CA2F11C82F1C00FCFED2 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53E4CA3011C82F1C00FCFED2 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleSectionedTableView_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = SimpleSectionedTableView; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleSectionedTableView_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = SimpleSectionedTableView; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleSectionedTableView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleSectionedTableView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TableViewSuite/2_SimpleSectionedTableView/SimpleSectionedTableView_Prefix.pch b/TableViewSuite/2_SimpleSectionedTableView/SimpleSectionedTableView_Prefix.pch new file mode 100755 index 0000000..db1cead --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/SimpleSectionedTableView_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'SimpleSectionTableView' target in the 'SimpleSectionTableView' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TableViewSuite/2_SimpleSectionedTableView/en.lproj/Localizable.strings b/TableViewSuite/2_SimpleSectionedTableView/en.lproj/Localizable.strings new file mode 100644 index 0000000..9111b51 Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/en.lproj/Localizable.strings differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/en.lproj/MainWindow.xib b/TableViewSuite/2_SimpleSectionedTableView/en.lproj/MainWindow.xib new file mode 100644 index 0000000..d7525b2 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/en.lproj/MainWindow.xib @@ -0,0 +1,181 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + delegate + + + + 9 + + + + window + + + + 10 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + SimpleSectionedTableViewAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{513, 356}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SimpleSectionedTableViewAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 10 + + + + YES + + SimpleSectionedTableViewAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/SimpleSectionedTableViewAppDelegate.h + + + + + 0 + SimpleSectionedTableView.xcodeproj + 3 + + diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Default.png b/TableViewSuite/2_SimpleSectionedTableView/images/Default.png new file mode 100644 index 0000000..2807ead Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Default.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Icon-72.png b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-72.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small-50.png b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small-50.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small.png b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small@2x.png b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Icon-Small@2x.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Icon.png b/TableViewSuite/2_SimpleSectionedTableView/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Icon.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/Icon@2x.png b/TableViewSuite/2_SimpleSectionedTableView/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/Icon@2x.png differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/images/iTunesArtwork b/TableViewSuite/2_SimpleSectionedTableView/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TableViewSuite/2_SimpleSectionedTableView/images/iTunesArtwork differ diff --git a/TableViewSuite/2_SimpleSectionedTableView/main.m b/TableViewSuite/2_SimpleSectionedTableView/main.m new file mode 100755 index 0000000..5d0bad3 --- /dev/null +++ b/TableViewSuite/2_SimpleSectionedTableView/main.m @@ -0,0 +1,56 @@ + + /* + File: main.m + Abstract: Main source file for this sample. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableViewSuite/3_SimpleIndexedTableView/Classes/RootViewController.h b/TableViewSuite/3_SimpleIndexedTableView/Classes/RootViewController.h new file mode 100644 index 0000000..5e379d3 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Classes/RootViewController.h @@ -0,0 +1,58 @@ + +/* + File: RootViewController.h + Abstract: View controller that serves as the table view's data source and delegate. It uses the current UILocalizedIndexedCollation object to organize the time zones into appropriate sections, and also to provide information about section titles and section index titles. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface RootViewController : UITableViewController { + NSMutableArray *timeZonesArray; + NSMutableArray *sectionsArray; + UILocalizedIndexedCollation *collation; +} + +@property (nonatomic, retain) NSMutableArray *timeZonesArray; + +@end diff --git a/TableViewSuite/3_SimpleIndexedTableView/Classes/RootViewController.m b/TableViewSuite/3_SimpleIndexedTableView/Classes/RootViewController.m new file mode 100644 index 0000000..6526632 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Classes/RootViewController.m @@ -0,0 +1,214 @@ + +/* + File: RootViewController.m + Abstract: View controller that serves as the table view's data source and delegate. It uses the current UILocalizedIndexedCollation object to organize the time zones into appropriate sections, and also to provide information about section titles and section index titles. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "SimpleIndexedTableViewAppDelegate.h" + +#import "TimeZoneWrapper.h" + +// The sections array and the collation are private. +@interface RootViewController() +@property (nonatomic, retain) NSMutableArray *sectionsArray; +@property (nonatomic, retain) UILocalizedIndexedCollation *collation; +- (void)configureSections; +@end + + +@implementation RootViewController + +@synthesize timeZonesArray, sectionsArray, collation; + + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewDidLoad { + self.title = @"Time Zones"; +} + + +#pragma mark - +#pragma mark Table view data source and delegate methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // The number of sections is the same as the number of titles in the collation. + return [[collation sectionTitles] count]; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + + // The number of time zones in the section is the count of the array associated with the section in the sections array. + NSArray *timeZonesInSection = [sectionsArray objectAtIndex:section]; + + return [timeZonesInSection count]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; + } + + // Get the time zone from the array associated with the section index in the sections array. + NSArray *timeZonesInSection = [sectionsArray objectAtIndex:indexPath.section]; + + // Configure the cell with the time zone's name. + TimeZoneWrapper *timeZone = [timeZonesInSection objectAtIndex:indexPath.row]; + cell.textLabel.text = timeZone.localeName; + + return cell; +} + + +/* + Section-related methods: Retrieve the section titles and section index titles from the collation. + */ + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + return [[collation sectionTitles] objectAtIndex:section]; +} + + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { + return [collation sectionIndexTitles]; +} + + +- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { + return [collation sectionForSectionIndexTitleAtIndex:index]; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +#pragma mark - +#pragma mark Set the data array and configure the section data + +- (void)setTimeZonesArray:(NSMutableArray *)newDataArray { + if (newDataArray != timeZonesArray) { + [timeZonesArray release]; + timeZonesArray = [newDataArray retain]; + } + if (timeZonesArray == nil) { + self.sectionsArray = nil; + } + else { + [self configureSections]; + } +} + + +- (void)configureSections { + + // Get the current collation and keep a reference to it. + self.collation = [UILocalizedIndexedCollation currentCollation]; + + NSInteger index, sectionTitlesCount = [[collation sectionTitles] count]; + + NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount]; + + // Set up the sections array: elements are mutable arrays that will contain the time zones for that section. + for (index = 0; index < sectionTitlesCount; index++) { + NSMutableArray *array = [[NSMutableArray alloc] init]; + [newSectionsArray addObject:array]; + [array release]; + } + + // Segregate the time zones into the appropriate arrays. + for (TimeZoneWrapper *timeZone in timeZonesArray) { + + // Ask the collation which section number the time zone belongs in, based on its locale name. + NSInteger sectionNumber = [collation sectionForObject:timeZone collationStringSelector:@selector(localeName)]; + + // Get the array for the section. + NSMutableArray *sectionTimeZones = [newSectionsArray objectAtIndex:sectionNumber]; + + // Add the time zone to the section. + [sectionTimeZones addObject:timeZone]; + } + + // Now that all the data's in place, each section array needs to be sorted. + for (index = 0; index < sectionTitlesCount; index++) { + + NSMutableArray *timeZonesArrayForSection = [newSectionsArray objectAtIndex:index]; + + // If the table view or its contents were editable, you would make a mutable copy here. + NSArray *sortedTimeZonesArrayForSection = [collation sortedArrayFromArray:timeZonesArrayForSection collationStringSelector:@selector(localeName)]; + + // Replace the existing array with the sorted array. + [newSectionsArray replaceObjectAtIndex:index withObject:sortedTimeZonesArrayForSection]; + } + + self.sectionsArray = newSectionsArray; + [newSectionsArray release]; +} + + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [timeZonesArray release]; + [sectionsArray release]; + [collation release]; + [super dealloc]; +} + + +@end + diff --git a/TableViewSuite/3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate.h b/TableViewSuite/3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate.h new file mode 100755 index 0000000..cf45bf5 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate.h @@ -0,0 +1,60 @@ + +/* + File: SimpleIndexedTableViewAppDelegate.h + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface SimpleIndexedTableViewAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +@end + diff --git a/TableViewSuite/3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate.m b/TableViewSuite/3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate.m new file mode 100755 index 0000000..4c9b4b0 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate.m @@ -0,0 +1,110 @@ + +/* + File: SimpleIndexedTableViewAppDelegate.m + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "SimpleIndexedTableViewAppDelegate.h" +#import "RootViewController.h" + +#import "TimeZoneWrapper.h" + + +@implementation SimpleIndexedTableViewAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Create the navigation and view controllers. + RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; + UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + self.navigationController = aNavigationController; + [rootViewController release]; + [aNavigationController release]; + + /* + Create an array of time zone wrappers and pass to the root view controller. + */ + NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames]; + NSMutableArray *timeZones = [[NSMutableArray alloc] initWithCapacity:[timeZoneNames count]]; + + for (NSString *timeZoneName in timeZoneNames) { + + NSArray *nameComponents = [timeZoneName componentsSeparatedByString:@"/"]; + // For this example, the time zone itself isn't needed. + TimeZoneWrapper *timeZoneWrapper = [[TimeZoneWrapper alloc] initWithTimeZone:nil nameComponents:nameComponents]; + + [timeZones addObject:timeZoneWrapper]; + [timeZoneWrapper release]; + } + + rootViewController.timeZonesArray = timeZones; + [timeZones release]; + + // Configure and display the window. + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/TableViewSuite/3_SimpleIndexedTableView/Classes/TimeZoneWrapper.h b/TableViewSuite/3_SimpleIndexedTableView/Classes/TimeZoneWrapper.h new file mode 100644 index 0000000..8c0234a --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Classes/TimeZoneWrapper.h @@ -0,0 +1,60 @@ + +/* + File: TimeZoneWrapper.h + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TimeZoneWrapper : NSObject { + NSString *localeName; + NSTimeZone *timeZone; +} + +@property (nonatomic, copy) NSString *localeName; +@property (nonatomic, retain) NSTimeZone *timeZone; + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents; + +@end diff --git a/TableViewSuite/3_SimpleIndexedTableView/Classes/TimeZoneWrapper.m b/TableViewSuite/3_SimpleIndexedTableView/Classes/TimeZoneWrapper.m new file mode 100644 index 0000000..77c2e01 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Classes/TimeZoneWrapper.m @@ -0,0 +1,84 @@ +/* + File: TimeZoneWrapper.m + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TimeZoneWrapper.h" + + +@implementation TimeZoneWrapper + +@synthesize localeName, timeZone; + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents { + + if (self = [super init]) { + + timeZone = [aTimeZone retain]; + + NSString *name = nil; + if ([nameComponents count] == 2) { + name = [nameComponents objectAtIndex:1]; + } + if ([nameComponents count] == 3) { + name = [NSString stringWithFormat:@"%@ (%@)", [nameComponents objectAtIndex:2], [nameComponents objectAtIndex:1]]; + } + + localeName = [[name stringByReplacingOccurrencesOfString:@"_" withString:@" "] retain]; + } + return self; +} + + +- (void)dealloc { + [localeName release]; + [timeZone release]; + + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/3_SimpleIndexedTableView/Info.plist b/TableViewSuite/3_SimpleIndexedTableView/Info.plist new file mode 100755 index 0000000..0418545 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TableViewSuite/3_SimpleIndexedTableView/SimpleIndexedTableView.xcodeproj/project.pbxproj b/TableViewSuite/3_SimpleIndexedTableView/SimpleIndexedTableView.xcodeproj/project.pbxproj new file mode 100755 index 0000000..ba62eac --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/SimpleIndexedTableView.xcodeproj/project.pbxproj @@ -0,0 +1,348 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 280176720F7D74EE0082ABE2 /* TimeZoneWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 280176710F7D74EE0082ABE2 /* TimeZoneWrapper.m */; }; + 282E81C40D78CB3C004DAD01 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 282E81C30D78CB3C004DAD01 /* RootViewController.m */; }; + 28D918080DCB968D00DA1262 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 28D918060DCB968C00DA1262 /* Localizable.strings */; }; + 533088B011D3DA9600FAABF5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088A811D3DA9600FAABF5 /* Default.png */; }; + 533088B111D3DA9600FAABF5 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088A911D3DA9600FAABF5 /* Icon-72.png */; }; + 533088B211D3DA9600FAABF5 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088AA11D3DA9600FAABF5 /* Icon-Small-50.png */; }; + 533088B311D3DA9600FAABF5 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088AB11D3DA9600FAABF5 /* Icon-Small.png */; }; + 533088B411D3DA9600FAABF5 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088AC11D3DA9600FAABF5 /* Icon-Small@2x.png */; }; + 533088B511D3DA9600FAABF5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088AD11D3DA9600FAABF5 /* Icon.png */; }; + 533088B611D3DA9600FAABF5 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 533088AE11D3DA9600FAABF5 /* Icon@2x.png */; }; + 533088B711D3DA9600FAABF5 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 533088AF11D3DA9600FAABF5 /* iTunesArtwork */; }; + 5360E82B11C82F530078A458 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5360E82911C82F530078A458 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleIndexedTableViewAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleIndexedTableViewAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* SimpleIndexedTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleIndexedTableView.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 280176700F7D74EE0082ABE2 /* TimeZoneWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeZoneWrapper.h; sourceTree = ""; }; + 280176710F7D74EE0082ABE2 /* TimeZoneWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimeZoneWrapper.m; sourceTree = ""; }; + 282E81C20D78CB3C004DAD01 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 282E81C30D78CB3C004DAD01 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28D918070DCB968C00DA1262 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A8770DC9362100332FD8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ReadMe.txt; path = ../ReadMe.txt; sourceTree = SOURCE_ROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* SimpleIndexedTableView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleIndexedTableView_Prefix.pch; sourceTree = ""; }; + 533088A811D3DA9600FAABF5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 533088A911D3DA9600FAABF5 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 533088AA11D3DA9600FAABF5 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 533088AB11D3DA9600FAABF5 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 533088AC11D3DA9600FAABF5 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 533088AD11D3DA9600FAABF5 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 533088AE11D3DA9600FAABF5 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 533088AF11D3DA9600FAABF5 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 5360E82A11C82F530078A458 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 282E81C20D78CB3C004DAD01 /* RootViewController.h */, + 282E81C30D78CB3C004DAD01 /* RootViewController.m */, + 1D3623240D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.h */, + 1D3623250D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.m */, + 280176700F7D74EE0082ABE2 /* TimeZoneWrapper.h */, + 280176710F7D74EE0082ABE2 /* TimeZoneWrapper.m */, + ); + path = Classes; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SimpleIndexedTableView.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28F1A8770DC9362100332FD8 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* SimpleIndexedTableView_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 533088A711D3DA9600FAABF5 /* images */, + 5360E82911C82F530078A458 /* MainWindow.xib */, + 28D918060DCB968C00DA1262 /* Localizable.strings */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 533088A711D3DA9600FAABF5 /* images */ = { + isa = PBXGroup; + children = ( + 533088A811D3DA9600FAABF5 /* Default.png */, + 533088A911D3DA9600FAABF5 /* Icon-72.png */, + 533088AA11D3DA9600FAABF5 /* Icon-Small-50.png */, + 533088AB11D3DA9600FAABF5 /* Icon-Small.png */, + 533088AC11D3DA9600FAABF5 /* Icon-Small@2x.png */, + 533088AD11D3DA9600FAABF5 /* Icon.png */, + 533088AE11D3DA9600FAABF5 /* Icon@2x.png */, + 533088AF11D3DA9600FAABF5 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SimpleIndexedTableView */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleIndexedTableView" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SimpleIndexedTableView; + productName = SimpleIndexedTableView; + productReference = 1D6058910D05DD3D006BFB54 /* SimpleIndexedTableView.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleIndexedTableView" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SimpleIndexedTableView */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28D918080DCB968D00DA1262 /* Localizable.strings in Resources */, + 5360E82B11C82F530078A458 /* MainWindow.xib in Resources */, + 533088B011D3DA9600FAABF5 /* Default.png in Resources */, + 533088B111D3DA9600FAABF5 /* Icon-72.png in Resources */, + 533088B211D3DA9600FAABF5 /* Icon-Small-50.png in Resources */, + 533088B311D3DA9600FAABF5 /* Icon-Small.png in Resources */, + 533088B411D3DA9600FAABF5 /* Icon-Small@2x.png in Resources */, + 533088B511D3DA9600FAABF5 /* Icon.png in Resources */, + 533088B611D3DA9600FAABF5 /* Icon@2x.png in Resources */, + 533088B711D3DA9600FAABF5 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* SimpleIndexedTableViewAppDelegate.m in Sources */, + 282E81C40D78CB3C004DAD01 /* RootViewController.m in Sources */, + 280176720F7D74EE0082ABE2 /* TimeZoneWrapper.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 28D918060DCB968C00DA1262 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 28D918070DCB968C00DA1262 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 5360E82911C82F530078A458 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 5360E82A11C82F530078A458 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleIndexedTableView_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = SimpleIndexedTableView; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SimpleIndexedTableView_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = SimpleIndexedTableView; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SimpleIndexedTableView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SimpleIndexedTableView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TableViewSuite/3_SimpleIndexedTableView/SimpleIndexedTableView_Prefix.pch b/TableViewSuite/3_SimpleIndexedTableView/SimpleIndexedTableView_Prefix.pch new file mode 100755 index 0000000..e11beb5 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/SimpleIndexedTableView_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'SimpleIndexedTableView' target in the 'SimpleIndexedTableView' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TableViewSuite/3_SimpleIndexedTableView/en.lproj/Localizable.strings b/TableViewSuite/3_SimpleIndexedTableView/en.lproj/Localizable.strings new file mode 100644 index 0000000..9111b51 Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/en.lproj/Localizable.strings differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/en.lproj/MainWindow.xib b/TableViewSuite/3_SimpleIndexedTableView/en.lproj/MainWindow.xib new file mode 100644 index 0000000..cdd9a44 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/en.lproj/MainWindow.xib @@ -0,0 +1,181 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + window + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + SimpleIndexedTableViewAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{450, 361}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SimpleIndexedTableViewAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + SimpleIndexedTableViewAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/SimpleIndexedTableViewAppDelegate.h + + + + + 0 + SimpleIndexedTableView.xcodeproj + 3 + + diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Default.png b/TableViewSuite/3_SimpleIndexedTableView/images/Default.png new file mode 100644 index 0000000..2807ead Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Default.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Icon-72.png b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-72.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small-50.png b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small-50.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small.png b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small@2x.png b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Icon-Small@2x.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Icon.png b/TableViewSuite/3_SimpleIndexedTableView/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Icon.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/Icon@2x.png b/TableViewSuite/3_SimpleIndexedTableView/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/Icon@2x.png differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/images/iTunesArtwork b/TableViewSuite/3_SimpleIndexedTableView/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TableViewSuite/3_SimpleIndexedTableView/images/iTunesArtwork differ diff --git a/TableViewSuite/3_SimpleIndexedTableView/main.m b/TableViewSuite/3_SimpleIndexedTableView/main.m new file mode 100755 index 0000000..ab0d3a5 --- /dev/null +++ b/TableViewSuite/3_SimpleIndexedTableView/main.m @@ -0,0 +1,56 @@ + +/* + File: main.m + Abstract: Main source file for this sample. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/Region.h b/TableViewSuite/4_TableViewCellSubviews/Classes/Region.h new file mode 100644 index 0000000..86be34a --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/Region.h @@ -0,0 +1,66 @@ + +/* + File: Region.h + Abstract: Object to represent a region containing the corresponding time zone wrappers. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface Region : NSObject { + NSString *name; + NSMutableArray *timeZoneWrappers; + NSCalendar *calendar; +} + +@property (nonatomic, retain) NSString *name; +@property (nonatomic, retain) NSMutableArray *timeZoneWrappers; +@property (nonatomic, retain) NSCalendar *calendar; + ++ (Region *)regionNamed:(NSString *)name; ++ (Region *)newRegionWithName:(NSString *)regionName; +- (void)addTimeZone:(NSTimeZone *)timeZone nameComponents:(NSArray *)nameComponents; +- (void)sortZones; +- (void)setDate:(NSDate *)date; + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/Region.m b/TableViewSuite/4_TableViewCellSubviews/Classes/Region.m new file mode 100644 index 0000000..fe169c6 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/Region.m @@ -0,0 +1,122 @@ + +/* + File: Region.m + Abstract: Object to represent a region containing the corresponding time zone wrappers. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Region.h" +#import "TimeZoneWrapper.h" + + +static NSMutableDictionary *regions; + +@implementation Region + +@synthesize name; +@synthesize timeZoneWrappers; +@synthesize calendar; + +/* + Class methods to manage global regions (pun intended). + */ ++ (void)initialize { + regions = [[NSMutableDictionary alloc] init]; +} + + ++ (Region *)regionNamed:(NSString *)name { + return [regions objectForKey:name]; +} + + ++ (Region *)newRegionWithName:(NSString *)regionName { + // Create a new region with a given name; add it to the regions dictionary + Region *newRegion = [[Region alloc] init]; + newRegion.name = regionName; + NSMutableArray *array = [[NSMutableArray alloc] init]; + newRegion.timeZoneWrappers = array; + [array release]; + [regions setObject:newRegion forKey:regionName]; + return newRegion; +} + + +- (void)addTimeZone:(NSTimeZone *)timeZone nameComponents:(NSArray *)nameComponents { + // Add a time zone to the region; use nameComponents since that's expensive + TimeZoneWrapper *timeZoneWrapper = [[TimeZoneWrapper alloc] initWithTimeZone:timeZone nameComponents:nameComponents]; + timeZoneWrapper.calendar = calendar; + [timeZoneWrappers addObject:timeZoneWrapper]; + [timeZoneWrapper release]; +} + + +- (void)sortZones { + // Sort the zone wrappers by locale name + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"localeName" ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1]; + [timeZoneWrappers sortUsingDescriptors:sortDescriptors]; + [sortDescriptors release]; + [sortDescriptor release]; +} + + +// Sets the date for the time zones, which has the side-effect of "faulting" the wrappers (see TimeZoneWrapper's setDate: method) +- (void)setDate:(NSDate *)date { + for (TimeZoneWrapper *wrapper in timeZoneWrappers) { + wrapper.date = date; + } +} + + +- (void)dealloc { + [name release]; + [timeZoneWrappers release]; + [calendar release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/RootViewController.h b/TableViewSuite/4_TableViewCellSubviews/Classes/RootViewController.h new file mode 100644 index 0000000..054701a --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/RootViewController.h @@ -0,0 +1,65 @@ + +/* + File: RootViewController.h + Abstract: View controller that sets up the table view and the time zone data. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface RootViewController : UITableViewController { + NSArray *displayList; + NSCalendar *calendar; + NSTimer *minuteTimer; +} + +@property (nonatomic, retain) NSArray *displayList; +@property (nonatomic, retain) NSCalendar *calendar; +@property (nonatomic, assign) NSTimer *minuteTimer; + +- (UITableViewCell *)tableViewCellWithReuseIdentifier:(NSString *)identifier; +- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath; + +- (void)update:sender; + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/RootViewController.m b/TableViewSuite/4_TableViewCellSubviews/Classes/RootViewController.m new file mode 100644 index 0000000..1c87b80 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/RootViewController.m @@ -0,0 +1,306 @@ + +/* + File: RootViewController.m + Abstract: View controller that sets up the table view and the time zone data. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "TimeZoneWrapper.h" +#import "Region.h" + +#import "TableViewCellSubviewsAppDelegate.h" + + + +#define ROW_HEIGHT 60 + +@implementation RootViewController + +@synthesize displayList; +@synthesize calendar; +@synthesize minuteTimer; + + + +#pragma mark - +#pragma mark View life-cycle + +- (void)viewDidLoad { + self.title = NSLocalizedString(@"Time Zones", @"Time Zones title"); + self.tableView.rowHeight = ROW_HEIGHT; +} + + +- (void)viewWillAppear:(BOOL)animated { + + /* + Set up a timer to update the table view every minute on the minute so that it shows the current time. + */ + NSDate *date = [NSDate date]; + NSDate *oneMinuteFromNow = [date dateByAddingTimeInterval:60]; + + NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit; + NSDateComponents *timerDateComponents = [calendar components:unitFlags fromDate:oneMinuteFromNow]; + // Add one second to ensure time has passed minute update when the timer fires. + [timerDateComponents setSecond:1]; + NSDate *minuteTimerDate = [calendar dateFromComponents:timerDateComponents]; + + NSTimer *timer = [[NSTimer alloc] initWithFireDate:minuteTimerDate interval:60 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; + self.minuteTimer = timer; + [timer release]; +} + + +- (void)viewWillDisappear:(BOOL)animated { + self.minuteTimer = nil; +} + + +#pragma mark - +#pragma mark Table view delegate and data source methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView { + // Number of sections is the number of regions + return [displayList count]; +} + + +- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { + // Number of rows is the number of time zones in the region for the specified section + Region *region = [displayList objectAtIndex:section]; + NSArray *regionTimeZones = region.timeZoneWrappers; + return [regionTimeZones count]; +} + + +- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section { + // Section title is the region name + Region *region = [displayList objectAtIndex:section]; + return region.name; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"TimeZoneCell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + + if (cell == nil) { + cell = [self tableViewCellWithReuseIdentifier:CellIdentifier]; + } + + // configureCell:cell forIndexPath: sets the text and image for the cell -- the method is factored out as it's also called during minuted-based updates. + [self configureCell:cell forIndexPath:indexPath]; + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + /* + To conform to the Human Interface Guidelines, selections should not be persistent -- + deselect the row after it has been selected. + */ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +#pragma mark - +#pragma mark Configuring table view cells + +#define NAME_TAG 1 +#define TIME_TAG 2 +#define IMAGE_TAG 3 + +#define LEFT_COLUMN_OFFSET 10.0 +#define LEFT_COLUMN_WIDTH 160.0 + +#define MIDDLE_COLUMN_OFFSET 170.0 +#define MIDDLE_COLUMN_WIDTH 90.0 + +#define RIGHT_COLUMN_OFFSET 280.0 + +#define MAIN_FONT_SIZE 18.0 +#define LABEL_HEIGHT 26.0 + +#define IMAGE_SIDE 30.0 + +- (UITableViewCell *)tableViewCellWithReuseIdentifier:(NSString *)identifier { + + /* + Create an instance of UITableViewCell and add tagged subviews for the name, local time, and quarter image of the time zone. + */ + + UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; + + /* + Create labels for the text fields; set the highlight color so that when the cell is selected it changes appropriately. + */ + UILabel *label; + CGRect rect; + + // Create a label for the time zone name. + rect = CGRectMake(LEFT_COLUMN_OFFSET, (ROW_HEIGHT - LABEL_HEIGHT) / 2.0, LEFT_COLUMN_WIDTH, LABEL_HEIGHT); + label = [[UILabel alloc] initWithFrame:rect]; + label.tag = NAME_TAG; + label.font = [UIFont boldSystemFontOfSize:MAIN_FONT_SIZE]; + label.adjustsFontSizeToFitWidth = YES; + [cell.contentView addSubview:label]; + label.highlightedTextColor = [UIColor whiteColor]; + [label release]; + + // Create a label for the time. + rect = CGRectMake(MIDDLE_COLUMN_OFFSET, (ROW_HEIGHT - LABEL_HEIGHT) / 2.0, MIDDLE_COLUMN_WIDTH, LABEL_HEIGHT); + label = [[UILabel alloc] initWithFrame:rect]; + label.tag = TIME_TAG; + label.font = [UIFont systemFontOfSize:MAIN_FONT_SIZE]; + label.textAlignment = UITextAlignmentRight; + [cell.contentView addSubview:label]; + label.highlightedTextColor = [UIColor whiteColor]; + [label release]; + + // Create an image view for the quarter image. + rect = CGRectMake(RIGHT_COLUMN_OFFSET, (ROW_HEIGHT - IMAGE_SIDE) / 2.0, IMAGE_SIDE, IMAGE_SIDE); + + UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect]; + imageView.tag = IMAGE_TAG; + [cell.contentView addSubview:imageView]; + [imageView release]; + + return cell; +} + + +- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath { + + /* + Cache the formatter. Normally you would use one of the date formatter styles (such as NSDateFormatterShortStyle), but here we want a specific format that excludes seconds. + */ + static NSDateFormatter *dateFormatter = nil; + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"h:mm a"]; + } + + // Get the time zones for the region for the section + Region *region = [displayList objectAtIndex:indexPath.section]; + NSArray *regionTimeZones = region.timeZoneWrappers; + TimeZoneWrapper *wrapper = [regionTimeZones objectAtIndex:indexPath.row]; + + UILabel *label; + + // Set the locale name. + label = (UILabel *)[cell viewWithTag:NAME_TAG]; + label.text = wrapper.localeName; + + // Set the time. + [dateFormatter setTimeZone:wrapper.timeZone]; + label = (UILabel *)[cell viewWithTag:TIME_TAG]; + label.text = [dateFormatter stringFromDate:[NSDate date]]; + + // Set the image. + UIImageView *imageView = (UIImageView *)[cell viewWithTag:IMAGE_TAG]; + imageView.image = wrapper.image; +} + + +#pragma mark - +#pragma mark Temporal updates + +- (void)setMinuteTimer:(NSTimer *)newTimer { + + if (minuteTimer != newTimer) { + [minuteTimer invalidate]; + minuteTimer = newTimer; + } +} + + +- (void)updateTime:(NSTimer *)timer { + /* + To display the current time, redisplay the time labels. + Don't reload the table view's data as this is unnecessarily expensive -- it recalculates the number of cells and the height of each item to determine the total height of the view etc. The external dimensions of the cells haven't changed, just their contents. + */ + NSArray *visibleCells = self.tableView.visibleCells; + for (UITableViewCell *cell in visibleCells) { + NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; + [self configureCell:cell forIndexPath:indexPath]; + [cell setNeedsDisplay]; + } +} + + +- (void)update:sender { + /* + The following sets the date for the regions, hence also for the time zone wrappers. This has the side-effect of "faulting" the time zone wrappers (see TimeZoneWrapper's setDate: method), so can be used to relieve memory pressure. + */ + NSDate *date = [NSDate date]; + for (Region *region in displayList) { + [region setDate:date]; + } +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + + [super didReceiveMemoryWarning]; + [self update:self]; +} + + +- (void)dealloc { + [minuteTimer invalidate]; + [displayList release]; + [calendar release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.h b/TableViewSuite/4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.h new file mode 100644 index 0000000..c2d2ae7 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.h @@ -0,0 +1,59 @@ + +/* + File: TableViewCellSubviewsAppDelegate.h + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TableViewCellSubviewsAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.m b/TableViewSuite/4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.m new file mode 100644 index 0000000..c5605e0 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.m @@ -0,0 +1,148 @@ + +/* + File: TableViewCellSubviewsAppDelegate.m + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TableViewCellSubviewsAppDelegate.h" +#import "RootViewController.h" + +#import "Region.h" + +@interface TableViewCellSubviewsAppDelegate (Private) +- (NSArray *)regionsWithCalendar:(NSCalendar *)calendar; +@end + + + +@implementation TableViewCellSubviewsAppDelegate + +@synthesize window; +@synthesize navigationController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Create the navigation and view controllers + RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; + UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + self.navigationController = aNavigationController; + [aNavigationController release]; + + NSCalendar *calendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + rootViewController.calendar = calendar; + rootViewController.displayList = [self regionsWithCalendar:calendar]; + + [calendar release]; + [rootViewController release]; + + // Configure and show the window + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + + +- (NSArray *)regionsWithCalendar:(NSCalendar *)calendar { + /* + Create an array of Region objects. + Each object represents a geographical region. Each region contains time zones. + Much of the information required to display a time zone is expensive to compute, so rather than using NSTimeZone objects directly use wrapper objects that calculate the required derived values on demand and cache the results. + */ + NSArray *knownTimeZoneNames = [NSTimeZone knownTimeZoneNames]; + + NSMutableArray *regions = [[NSMutableArray alloc] init]; + + for (NSString *timeZoneName in knownTimeZoneNames) { + + NSArray *components = [timeZoneName componentsSeparatedByString:@"/"]; + NSString *regionName = [components objectAtIndex:0]; + + Region *region = [Region regionNamed:regionName]; + if (region == nil) { + region = [Region newRegionWithName:regionName]; + region.calendar = calendar; + [regions addObject:region]; + [region release]; + } + + NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:timeZoneName]; + [region addTimeZone:timeZone nameComponents:components]; + [timeZone release]; + } + + // Now sort the time zones by name. + NSDate *date = [[NSDate alloc] init]; + for (Region *region in regions) { + [region sortZones]; + [region setDate:date]; + } + [date release]; + + // Sort the regions. + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1]; + + NSArray *sortedRegions = [regions sortedArrayUsingDescriptors:sortDescriptors]; + + [sortDescriptor release]; + [sortDescriptors release]; + + [regions release]; + + return sortedRegions; +} + + + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/TimeZoneWrapper.h b/TableViewSuite/4_TableViewCellSubviews/Classes/TimeZoneWrapper.h new file mode 100644 index 0000000..810b3b6 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/TimeZoneWrapper.h @@ -0,0 +1,76 @@ + +/* + File: TimeZoneWrapper.h + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TimeZoneWrapper : NSObject { + NSString *localeName; + NSTimeZone *timeZone; + + NSDate *date; + NSCalendar *calendar; + + NSString *whichDay; + NSString *abbreviation; + NSString *gmtOffset; + UIImage *image; +} + +@property (nonatomic, retain) NSString *localeName; +@property (nonatomic, retain) NSTimeZone *timeZone; + +@property (nonatomic, retain) NSDate *date; +@property (nonatomic, retain) NSCalendar *calendar; + +@property (nonatomic, retain) NSString *whichDay; +@property (nonatomic, retain) NSString *abbreviation; +@property (nonatomic, retain) NSString *gmtOffset; +@property (nonatomic, retain) UIImage *image; + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents; + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Classes/TimeZoneWrapper.m b/TableViewSuite/4_TableViewCellSubviews/Classes/TimeZoneWrapper.m new file mode 100644 index 0000000..976039b --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Classes/TimeZoneWrapper.m @@ -0,0 +1,231 @@ +/* + File: TimeZoneWrapper.m + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TimeZoneWrapper.h" +#import "TableViewCellSubviewsAppDelegate.h" + + +static NSString *today; +static NSString *tomorrow; +static NSString *yesterday; + +static UIImage *q1Image; +static UIImage *q2Image; +static UIImage *q3Image; +static UIImage *q4Image; + + +@implementation TimeZoneWrapper + +@synthesize timeZone; +@synthesize localeName; +@synthesize date; +@synthesize calendar; + +@synthesize whichDay; +@synthesize abbreviation; +@synthesize gmtOffset; +@synthesize image; + + ++ (void)initialize { + // Unlikely to have any subclasses, but check class nevertheless + if (self == [TimeZoneWrapper class]) { + today = [NSLocalizedString(@"Today", "Today") retain]; + tomorrow = [NSLocalizedString(@"Tomorrow", "Tomorrow") retain]; + yesterday = [NSLocalizedString(@"Yesterday", "Yesterday") retain]; + + q1Image = [[UIImage imageNamed:@"12-6AM.png"] retain]; + q2Image = [[UIImage imageNamed:@"6-12AM.png"] retain]; + q3Image = [[UIImage imageNamed:@"12-6PM.png"] retain]; + q4Image = [[UIImage imageNamed:@"6-12PM.png"] retain]; + } +} + + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents { + + if (self = [super init]) { + + timeZone = [aTimeZone retain]; + + NSString *name = nil; + if ([nameComponents count] == 2) { + name = [nameComponents objectAtIndex:1]; + } + else if ([nameComponents count] == 3) { + name = [NSString stringWithFormat:@"%@ (%@)", [nameComponents objectAtIndex:2], [nameComponents objectAtIndex:1]]; + } + + localeName = [[name stringByReplacingOccurrencesOfString:@"_" withString:@" "] retain]; + } + return self; +} + + +/* + By default, we don't actually calculate whichDay, abreviation, gmtOffset or image. + They're expensive to compute, and consume memory. Calculate them on demand, then cache them. + */ + +- (NSString *)whichDay { + // Return "today", "tomorrow", or "yesterday" as appropriate for the time zone + + if (whichDay == nil) { + NSDateComponents *dateComponents; + NSInteger myDay, tzDay; + + // Set the calendar's time zone to the default time zone. + [calendar setTimeZone:[NSTimeZone defaultTimeZone]]; + dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:date]; + myDay = [dateComponents weekday]; + + [calendar setTimeZone:timeZone]; + dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:date]; + tzDay = [dateComponents weekday]; + + NSRange dayRange = [calendar maximumRangeOfUnit:NSWeekdayCalendarUnit]; + NSInteger maxDay = NSMaxRange(dayRange) - 1; + + if (myDay == tzDay) { + self.whichDay = today; + } else { + if ((tzDay - myDay) > 0) { + self.whichDay = tomorrow; + } else { + self.whichDay = yesterday; + } + // Special cases for days at the end of the week + if ((myDay == maxDay) && (tzDay == 1)) { + self.whichDay = tomorrow; + } + if ((myDay == 1) && (tzDay == maxDay)) { + self.whichDay = yesterday; + } + } + } + return whichDay; +} + + +- (NSString *)abbreviation { + // Return the abbreviation for the time zone + if (abbreviation == nil) { + self.abbreviation = [timeZone abbreviationForDate:date]; + } + return abbreviation; +} + + +- (NSString *)gmtOffset { + // Return the offset from GMT for the time zone + if (gmtOffset == nil) { + self.gmtOffset = [timeZone localizedName:NSTimeZoneNameStyleShortStandard locale:[NSLocale currentLocale]]; + } + return gmtOffset; +} + + +- (UIImage *)image { + // Return an image that illustrates the quarter of the current day in the time zone + if (image == nil) { + [calendar setTimeZone:timeZone]; + NSDateComponents *dateComponents = [calendar components:NSHourCalendarUnit fromDate:date]; + NSInteger hour = [dateComponents hour]; + if (hour > 17) { + self.image = q4Image; + } else { + if (hour > 11) { + self.image = q3Image; + } else { + if (hour > 5) { + self.image = q2Image; + } else { + self.image = q1Image; + } + } + } + } + return image; +} + + +- (void)setDate:(NSDate *)newDate { + /* + Recalculating all the details is expensive. + Only change the date if it is not actually equal to the current date. + If the date is different, "fault" the receiver: nill out all the cached values -- if accessed, they will be recaulculated. + */ + if ([newDate isEqualToDate:date]) { + return; + } + [date release]; + date = [newDate retain]; + self.abbreviation = nil; + self.abbreviation = nil; + self.gmtOffset = nil; + self.image = nil; +} + + +- (void)dealloc { + [localeName release]; + [timeZone release]; + [date release]; + [calendar release]; + + [whichDay release]; + [abbreviation release]; + [gmtOffset release]; + [image release]; + + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/4_TableViewCellSubviews/Info.plist b/TableViewSuite/4_TableViewCellSubviews/Info.plist new file mode 100644 index 0000000..89683d0 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + TableViewCellSubviews + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TableViewSuite/4_TableViewCellSubviews/TableViewCellSubviews.xcodeproj/project.pbxproj b/TableViewSuite/4_TableViewCellSubviews/TableViewCellSubviews.xcodeproj/project.pbxproj new file mode 100755 index 0000000..e4b30bf --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/TableViewCellSubviews.xcodeproj/project.pbxproj @@ -0,0 +1,371 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28275AF10D6E02D900A8AFA4 /* TimeZoneWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 28275AF00D6E02D900A8AFA4 /* TimeZoneWrapper.m */; }; + 2867DEFD0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2867DEFB0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.m */; }; + 28BDD37E0D628913006FBFB9 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28BDD37D0D628913006FBFB9 /* RootViewController.m */; }; + 28D655C30D6E3F78005F58A3 /* Region.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D655C20D6E3F78005F58A3 /* Region.m */; }; + 28F1A71C0DC92FE900332FD8 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 28F1A71A0DC92FE900332FD8 /* Localizable.strings */; }; + 5330888E11D3DA7800FAABF5 /* 12-6AM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888211D3DA7800FAABF5 /* 12-6AM.png */; }; + 5330888F11D3DA7800FAABF5 /* 12-6PM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888311D3DA7800FAABF5 /* 12-6PM.png */; }; + 5330889011D3DA7800FAABF5 /* 6-12AM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888411D3DA7800FAABF5 /* 6-12AM.png */; }; + 5330889111D3DA7800FAABF5 /* 6-12PM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888511D3DA7800FAABF5 /* 6-12PM.png */; }; + 5330889211D3DA7800FAABF5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888611D3DA7800FAABF5 /* Default.png */; }; + 5330889311D3DA7800FAABF5 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888711D3DA7800FAABF5 /* Icon-72.png */; }; + 5330889411D3DA7800FAABF5 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888811D3DA7800FAABF5 /* Icon-Small-50.png */; }; + 5330889511D3DA7800FAABF5 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888911D3DA7800FAABF5 /* Icon-Small.png */; }; + 5330889611D3DA7800FAABF5 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888A11D3DA7800FAABF5 /* Icon-Small@2x.png */; }; + 5330889711D3DA7800FAABF5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888B11D3DA7800FAABF5 /* Icon.png */; }; + 5330889811D3DA7800FAABF5 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330888C11D3DA7800FAABF5 /* Icon@2x.png */; }; + 5330889911D3DA7800FAABF5 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 5330888D11D3DA7800FAABF5 /* iTunesArtwork */; }; + 53DE80E111C82FCA00BE34A6 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53DE80DF11C82FCA00BE34A6 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* TableViewCellSubviews.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TableViewCellSubviews.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28275AEF0D6E02D900A8AFA4 /* TimeZoneWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimeZoneWrapper.h; path = Classes/TimeZoneWrapper.h; sourceTree = ""; }; + 28275AF00D6E02D900A8AFA4 /* TimeZoneWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TimeZoneWrapper.m; path = Classes/TimeZoneWrapper.m; sourceTree = ""; }; + 2867DEFB0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewCellSubviewsAppDelegate.m; sourceTree = ""; }; + 2867DEFC0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewCellSubviewsAppDelegate.h; sourceTree = ""; }; + 28BDD37C0D628913006FBFB9 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28BDD37D0D628913006FBFB9 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28D655C10D6E3F78005F58A3 /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Region.h; path = Classes/Region.h; sourceTree = ""; }; + 28D655C20D6E3F78005F58A3 /* Region.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Region.m; path = Classes/Region.m; sourceTree = ""; }; + 28F1A71B0DC92FE900332FD8 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A7200DC9300100332FD8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A7210DC9300800332FD8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A8850DC9365F00332FD8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ReadMe.txt; path = ../ReadMe.txt; sourceTree = SOURCE_ROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* TableViewCellSubviews_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewCellSubviews_Prefix.pch; sourceTree = ""; }; + 5330888211D3DA7800FAABF5 /* 12-6AM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "12-6AM.png"; sourceTree = ""; }; + 5330888311D3DA7800FAABF5 /* 12-6PM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "12-6PM.png"; sourceTree = ""; }; + 5330888411D3DA7800FAABF5 /* 6-12AM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "6-12AM.png"; sourceTree = ""; }; + 5330888511D3DA7800FAABF5 /* 6-12PM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "6-12PM.png"; sourceTree = ""; }; + 5330888611D3DA7800FAABF5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 5330888711D3DA7800FAABF5 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 5330888811D3DA7800FAABF5 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 5330888911D3DA7800FAABF5 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 5330888A11D3DA7800FAABF5 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 5330888B11D3DA7800FAABF5 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 5330888C11D3DA7800FAABF5 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 5330888D11D3DA7800FAABF5 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 53DE80E011C82FCA00BE34A6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* View Controllers */ = { + isa = PBXGroup; + children = ( + 28BDD37C0D628913006FBFB9 /* RootViewController.h */, + 28BDD37D0D628913006FBFB9 /* RootViewController.m */, + 2867DEFC0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.h */, + 2867DEFB0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.m */, + ); + name = "View Controllers"; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* TableViewCellSubviews.app */, + ); + name = Products; + sourceTree = ""; + }; + 28275B330D6E06C500A8AFA4 /* Model Classes */ = { + isa = PBXGroup; + children = ( + 28D655C10D6E3F78005F58A3 /* Region.h */, + 28D655C20D6E3F78005F58A3 /* Region.m */, + 28275AEF0D6E02D900A8AFA4 /* TimeZoneWrapper.h */, + 28275AF00D6E02D900A8AFA4 /* TimeZoneWrapper.m */, + ); + name = "Model Classes"; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28F1A8850DC9365F00332FD8 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* View Controllers */, + 28275B330D6E06C500A8AFA4 /* Model Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* TableViewCellSubviews_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 5330888111D3DA7800FAABF5 /* images */, + 53DE80DF11C82FCA00BE34A6 /* MainWindow.xib */, + 28F1A71A0DC92FE900332FD8 /* Localizable.strings */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5330888111D3DA7800FAABF5 /* images */ = { + isa = PBXGroup; + children = ( + 5330888211D3DA7800FAABF5 /* 12-6AM.png */, + 5330888311D3DA7800FAABF5 /* 12-6PM.png */, + 5330888411D3DA7800FAABF5 /* 6-12AM.png */, + 5330888511D3DA7800FAABF5 /* 6-12PM.png */, + 5330888611D3DA7800FAABF5 /* Default.png */, + 5330888711D3DA7800FAABF5 /* Icon-72.png */, + 5330888811D3DA7800FAABF5 /* Icon-Small-50.png */, + 5330888911D3DA7800FAABF5 /* Icon-Small.png */, + 5330888A11D3DA7800FAABF5 /* Icon-Small@2x.png */, + 5330888B11D3DA7800FAABF5 /* Icon.png */, + 5330888C11D3DA7800FAABF5 /* Icon@2x.png */, + 5330888D11D3DA7800FAABF5 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* TableViewCellSubviews */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TableViewCellSubviews" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TableViewCellSubviews; + productName = CustomTableViewCell; + productReference = 1D6058910D05DD3D006BFB54 /* TableViewCellSubviews.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TableViewCellSubviews" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + french, + en, + fr, + de, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* TableViewCellSubviews */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28F1A71C0DC92FE900332FD8 /* Localizable.strings in Resources */, + 53DE80E111C82FCA00BE34A6 /* MainWindow.xib in Resources */, + 5330888E11D3DA7800FAABF5 /* 12-6AM.png in Resources */, + 5330888F11D3DA7800FAABF5 /* 12-6PM.png in Resources */, + 5330889011D3DA7800FAABF5 /* 6-12AM.png in Resources */, + 5330889111D3DA7800FAABF5 /* 6-12PM.png in Resources */, + 5330889211D3DA7800FAABF5 /* Default.png in Resources */, + 5330889311D3DA7800FAABF5 /* Icon-72.png in Resources */, + 5330889411D3DA7800FAABF5 /* Icon-Small-50.png in Resources */, + 5330889511D3DA7800FAABF5 /* Icon-Small.png in Resources */, + 5330889611D3DA7800FAABF5 /* Icon-Small@2x.png in Resources */, + 5330889711D3DA7800FAABF5 /* Icon.png in Resources */, + 5330889811D3DA7800FAABF5 /* Icon@2x.png in Resources */, + 5330889911D3DA7800FAABF5 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2867DEFD0D581C2E0037AED8 /* TableViewCellSubviewsAppDelegate.m in Sources */, + 28BDD37E0D628913006FBFB9 /* RootViewController.m in Sources */, + 28275AF10D6E02D900A8AFA4 /* TimeZoneWrapper.m in Sources */, + 28D655C30D6E3F78005F58A3 /* Region.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 28F1A71A0DC92FE900332FD8 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 28F1A71B0DC92FE900332FD8 /* en */, + 28F1A7200DC9300100332FD8 /* fr */, + 28F1A7210DC9300800332FD8 /* de */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 53DE80DF11C82FCA00BE34A6 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53DE80E011C82FCA00BE34A6 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = TableViewCellSubviews_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = TableViewCellSubviews; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = TableViewCellSubviews_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = CustomTableViewCell; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TableViewCellSubviews" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TableViewCellSubviews" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TableViewSuite/4_TableViewCellSubviews/TableViewCellSubviews_Prefix.pch b/TableViewSuite/4_TableViewCellSubviews/TableViewCellSubviews_Prefix.pch new file mode 100644 index 0000000..30894d9 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/TableViewCellSubviews_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'TableViewCellSubviews' target in the 'TableViewCellSubviews' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TableViewSuite/4_TableViewCellSubviews/de.lproj/Localizable.strings b/TableViewSuite/4_TableViewCellSubviews/de.lproj/Localizable.strings new file mode 100644 index 0000000..7aa1564 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/de.lproj/Localizable.strings @@ -0,0 +1,4 @@ + +"Today" = "Heute"; +"Tomorrow" = "Morgen"; +"Yesterday" = "Gestern"; diff --git a/TableViewSuite/4_TableViewCellSubviews/de.lproj/MainWindow.xib b/TableViewSuite/4_TableViewCellSubviews/de.lproj/MainWindow.xib new file mode 100644 index 0000000..2409851 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/de.lproj/MainWindow.xib @@ -0,0 +1,179 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + delegate + + + + 9 + + + + window + + + + 10 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + CustomTableViewCellAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{371, 368}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TableViewCellSubviewsAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 10 + + + + YES + + TableViewCellSubviewsAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/TableViewCellSubviewsAppDelegate.h + + + + + 0 + TableViewCellSubviews.xcodeproj + 3 + + diff --git a/TableViewSuite/4_TableViewCellSubviews/en.lproj/Localizable.strings b/TableViewSuite/4_TableViewCellSubviews/en.lproj/Localizable.strings new file mode 100644 index 0000000..0c96980 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/en.lproj/Localizable.strings differ diff --git a/TableViewSuite/4_TableViewCellSubviews/en.lproj/MainWindow.xib b/TableViewSuite/4_TableViewCellSubviews/en.lproj/MainWindow.xib new file mode 100644 index 0000000..2409851 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/en.lproj/MainWindow.xib @@ -0,0 +1,179 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + delegate + + + + 9 + + + + window + + + + 10 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + CustomTableViewCellAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{371, 368}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TableViewCellSubviewsAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 10 + + + + YES + + TableViewCellSubviewsAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/TableViewCellSubviewsAppDelegate.h + + + + + 0 + TableViewCellSubviews.xcodeproj + 3 + + diff --git a/TableViewSuite/4_TableViewCellSubviews/fr.lproj/Localizable.strings b/TableViewSuite/4_TableViewCellSubviews/fr.lproj/Localizable.strings new file mode 100644 index 0000000..eb2e4ad --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/fr.lproj/Localizable.strings @@ -0,0 +1,4 @@ + +"Today" = "Aujourd'hui"; +"Tomorrow" = "Demain"; +"Yesterday" = "Hier"; diff --git a/TableViewSuite/4_TableViewCellSubviews/fr.lproj/MainWindow.xib b/TableViewSuite/4_TableViewCellSubviews/fr.lproj/MainWindow.xib new file mode 100644 index 0000000..2409851 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/fr.lproj/MainWindow.xib @@ -0,0 +1,179 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + delegate + + + + 9 + + + + window + + + + 10 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + CustomTableViewCellAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{371, 368}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TableViewCellSubviewsAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 10 + + + + YES + + TableViewCellSubviewsAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/TableViewCellSubviewsAppDelegate.h + + + + + 0 + TableViewCellSubviews.xcodeproj + 3 + + diff --git a/TableViewSuite/4_TableViewCellSubviews/images/12-6AM.png b/TableViewSuite/4_TableViewCellSubviews/images/12-6AM.png new file mode 100644 index 0000000..c7b411e Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/12-6AM.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/12-6PM.png b/TableViewSuite/4_TableViewCellSubviews/images/12-6PM.png new file mode 100644 index 0000000..c544340 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/12-6PM.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/6-12AM.png b/TableViewSuite/4_TableViewCellSubviews/images/6-12AM.png new file mode 100644 index 0000000..77f5a50 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/6-12AM.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/6-12PM.png b/TableViewSuite/4_TableViewCellSubviews/images/6-12PM.png new file mode 100644 index 0000000..a77859e Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/6-12PM.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Default.png b/TableViewSuite/4_TableViewCellSubviews/images/Default.png new file mode 100644 index 0000000..7cad83a Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Default.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Icon-72.png b/TableViewSuite/4_TableViewCellSubviews/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Icon-72.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small-50.png b/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small-50.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small.png b/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small@2x.png b/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Icon-Small@2x.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Icon.png b/TableViewSuite/4_TableViewCellSubviews/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Icon.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/Icon@2x.png b/TableViewSuite/4_TableViewCellSubviews/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/Icon@2x.png differ diff --git a/TableViewSuite/4_TableViewCellSubviews/images/iTunesArtwork b/TableViewSuite/4_TableViewCellSubviews/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TableViewSuite/4_TableViewCellSubviews/images/iTunesArtwork differ diff --git a/TableViewSuite/4_TableViewCellSubviews/main.m b/TableViewSuite/4_TableViewCellSubviews/main.m new file mode 100644 index 0000000..ab0d3a5 --- /dev/null +++ b/TableViewSuite/4_TableViewCellSubviews/main.m @@ -0,0 +1,56 @@ + +/* + File: main.m + Abstract: Main source file for this sample. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.h b/TableViewSuite/5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.h new file mode 100644 index 0000000..abd4486 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.h @@ -0,0 +1,66 @@ + +/* + File: CustomTableViewCellAppDelegate.h + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +extern NSTimeZone *App_defaultTimeZone; + +@interface CustomTableViewCellAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; + + NSCalendar *calendar; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +- (NSArray *)displayList; +@property (nonatomic, retain, readonly) NSCalendar *calendar; + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.m b/TableViewSuite/5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.m new file mode 100644 index 0000000..321de25 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.m @@ -0,0 +1,155 @@ + +/* + File: CustomTableViewCellAppDelegate.m + Abstract: Application delegate that sets up the navigation controller and the root view controller. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "CustomTableViewCellAppDelegate.h" +#import "RootViewController.h" + +#import "Region.h" + + +NSTimeZone *App_defaultTimeZone; + +@implementation CustomTableViewCellAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + /* + We use these images and the application's time zone a lot, they're also static, so cache them and make them available globally... + */ + App_defaultTimeZone = [[NSTimeZone defaultTimeZone] retain]; + + // Create the navigation and view controllers + RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; + + rootViewController.displayList = [self displayList]; + rootViewController.calendar = [self calendar]; + + UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + self.navigationController = aNavigationController; + [aNavigationController release]; + [rootViewController release]; + + // Configure and show the window + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; +} + + +#pragma mark - +#pragma mark Setting up the display list + +- (NSArray *)displayList { + /* + Return an array of Region objects. + Each object represents a geographical region. Each region contains time zones. + Much of the information required to display a time zone is expensive to compute, so rather than using NSTimeZone objects directly use wrapper objects that calculate the required derived values on demand and cache the results. + */ + NSArray *knownTimeZoneNames = [NSTimeZone knownTimeZoneNames]; + + NSMutableArray *regions = [NSMutableArray array]; + + for (NSString *timeZoneName in knownTimeZoneNames) { + + NSArray *components = [timeZoneName componentsSeparatedByString:@"/"]; + NSString *regionName = [components objectAtIndex:0]; + + Region *region = [Region regionNamed:regionName]; + if (region == nil) { + region = [Region newRegionWithName:regionName]; + region.calendar = [self calendar]; + [regions addObject:region]; + [region release]; + } + + NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:timeZoneName]; + [region addTimeZone:timeZone nameComponents:components]; + [timeZone release]; + } + + NSDate *date = [NSDate date]; + // Now sort the time zones by name + for (Region *region in regions) { + [region sortZones]; + [region setDate:date]; + } + // Sort the regions + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; + NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; + [regions sortUsingDescriptors:sortDescriptors]; + [sortDescriptor release]; + + return regions; +} + + +- (NSCalendar *)calendar { + if (calendar == nil) { + calendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + } + return calendar; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [navigationController release]; + [window release]; + [calendar release]; + [super dealloc]; +} + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/Region.h b/TableViewSuite/5_CustomTableViewCell/Classes/Region.h new file mode 100644 index 0000000..86be34a --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/Region.h @@ -0,0 +1,66 @@ + +/* + File: Region.h + Abstract: Object to represent a region containing the corresponding time zone wrappers. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface Region : NSObject { + NSString *name; + NSMutableArray *timeZoneWrappers; + NSCalendar *calendar; +} + +@property (nonatomic, retain) NSString *name; +@property (nonatomic, retain) NSMutableArray *timeZoneWrappers; +@property (nonatomic, retain) NSCalendar *calendar; + ++ (Region *)regionNamed:(NSString *)name; ++ (Region *)newRegionWithName:(NSString *)regionName; +- (void)addTimeZone:(NSTimeZone *)timeZone nameComponents:(NSArray *)nameComponents; +- (void)sortZones; +- (void)setDate:(NSDate *)date; + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/Region.m b/TableViewSuite/5_CustomTableViewCell/Classes/Region.m new file mode 100644 index 0000000..bd60c13 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/Region.m @@ -0,0 +1,122 @@ + +/* + File: Region.m + Abstract: Object to represent a region containing the corresponding time zone wrappers. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Region.h" +#import "TimeZoneWrapper.h" + + +static NSMutableDictionary *regions; + +@implementation Region + +@synthesize name; +@synthesize timeZoneWrappers; +@synthesize calendar; + +/* + Class methods to manage global regions. + */ ++ (void)initialize { + regions = [[NSMutableDictionary alloc] init]; +} + + ++ (Region *)regionNamed:(NSString *)name { + return [regions objectForKey:name]; +} + + ++ (Region *)newRegionWithName:(NSString *)regionName { + // Create a new region with a given name; add it to the regions dictionary. + Region *newRegion = [[Region alloc] init]; + newRegion.name = regionName; + NSMutableArray *array = [[NSMutableArray alloc] init]; + newRegion.timeZoneWrappers = array; + [array release]; + [regions setObject:newRegion forKey:regionName]; + return newRegion; +} + + +- (void)addTimeZone:(NSTimeZone *)timeZone nameComponents:(NSArray *)nameComponents { + // Add a time zone to the region; use nameComponents since that's expensive to compute. + TimeZoneWrapper *timeZoneWrapper = [[TimeZoneWrapper alloc] initWithTimeZone:timeZone nameComponents:nameComponents]; + timeZoneWrapper.calendar = calendar; + [timeZoneWrappers addObject:timeZoneWrapper]; + [timeZoneWrapper release]; +} + + +- (void)sortZones { + // Sort the zone wrappers by locale name. + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeZoneLocaleName" ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1]; + [timeZoneWrappers sortUsingDescriptors:sortDescriptors]; + [sortDescriptors release]; + [sortDescriptor release]; +} + + +// Sets the date for the time zones, which has the side-effect of "faulting" the wrappers (see TimeZoneWrapper's setDate: method). +- (void)setDate:(NSDate *)date { + for (TimeZoneWrapper *wrapper in timeZoneWrappers) { + wrapper.date = date; + } +} + + +- (void)dealloc { + [name release]; + [timeZoneWrappers release]; + [calendar release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/RootViewController.h b/TableViewSuite/5_CustomTableViewCell/Classes/RootViewController.h new file mode 100644 index 0000000..8294a96 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/RootViewController.h @@ -0,0 +1,67 @@ + + /* + File: RootViewController.h + Abstract: View controller that sets up the table view and the time zone data. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface RootViewController : UITableViewController { + NSArray *displayList; + NSCalendar *calendar; + NSTimer *minuteTimer; + NSTimer *regionsTimer; + +} + +@property (nonatomic, retain) NSArray *displayList; +@property (nonatomic, retain) NSCalendar *calendar; + +@property (nonatomic, assign) NSTimer *minuteTimer; +@property (nonatomic, assign) NSTimer *regionsTimer; + +- (void)updateTime:(NSTimer *)timer; +- (void)updateRegions:(id)sender; + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/RootViewController.m b/TableViewSuite/5_CustomTableViewCell/Classes/RootViewController.m new file mode 100644 index 0000000..3a60888 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/RootViewController.m @@ -0,0 +1,255 @@ + +/* + File: RootViewController.m + Abstract: View controller that sets up the table view and the time zone data. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "TimeZoneCell.h" +#import "TimeZoneWrapper.h" +#import "Region.h" + +#import "CustomTableViewCellAppDelegate.h" + +#define ROW_HEIGHT 60 + +@implementation RootViewController + +@synthesize displayList; +@synthesize calendar; +@synthesize minuteTimer; +@synthesize regionsTimer; + + +#pragma mark - +#pragma mark Initialization + +- (id)initWithStyle:(UITableViewStyle)style { + if (self = [super initWithStyle:style]) { + self.title = NSLocalizedString(@"Time Zones", @"Time Zones title"); + + self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; + self.tableView.rowHeight = ROW_HEIGHT; + } + return self; +} + + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewWillAppear:(BOOL)animated { + + /* + Set up two timers, one that fires every minute, the other every fifteen minutes. + + 1/ The time displayed for each time zone must be updated every minute on the minute. + 2/ Time zone data is cached. Some time zones are based on 15 minute differences from GMT, so update the cache every 15 minutes, on the "quarter". + */ + + NSTimer *timer; + NSDate *date = [NSDate date]; + + /* + Set up a timer to update the table view every minute on the minute so that it shows the current time. + */ + NSDate *oneMinuteFromNow = [date dateByAddingTimeInterval:60]; + + NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit; + NSDateComponents *timerDateComponents = [calendar components:unitFlags fromDate:oneMinuteFromNow]; + // Add 1 second to make sure the minute update has passed when the timer fires. + [timerDateComponents setSecond:1]; + NSDate *minuteTimerDate = [calendar dateFromComponents:timerDateComponents]; + + timer = [[NSTimer alloc] initWithFireDate:minuteTimerDate interval:60 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; + self.minuteTimer = timer; + [timer release]; + + /* + Set up a timer to update the region data every 15 minutes on the quarter, so that the regions show the current date. + */ + NSInteger minutesToNextQuarter = 15 - ([timerDateComponents minute] % 15); + NSDateComponents *minutesToNextQuarterComponents = [[NSDateComponents alloc] init]; + [minutesToNextQuarterComponents setMinute:minutesToNextQuarter]; + NSDate *regionTimerDate = [calendar dateByAddingComponents:minutesToNextQuarterComponents toDate:minuteTimerDate options:0]; + [minutesToNextQuarterComponents release]; + + timer = [[NSTimer alloc] initWithFireDate:regionTimerDate interval:15*60 target:self selector:@selector(updateRegions:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; + self.regionsTimer = timer; + [timer release]; +} + + +- (void)viewWillDisappear:(BOOL)animated { + self.minuteTimer = nil; + self.regionsTimer = nil; +} + + +#pragma mark - +#pragma mark Table view datasource and delegate methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView { + // Number of sections is the number of regions + return [displayList count]; +} + + +- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { + // Number of rows is the number of time zones in the region for the specified section + Region *region = [displayList objectAtIndex:section]; + NSArray *regionTimeZones = region.timeZoneWrappers; + return [regionTimeZones count]; +} + + +- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section { + // Section title is the region name + Region *region = [displayList objectAtIndex:section]; + return region.name; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"TimeZoneCell"; + + TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + + if (timeZoneCell == nil) { + timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; + timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT); + } + + // Get the time zones for the region for the section + Region *region = [displayList objectAtIndex:indexPath.section]; + NSArray *regionTimeZones = region.timeZoneWrappers; + + // Get the time zone wrapper for the row + [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]]; + return timeZoneCell; +} + + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + /* + To conform to the Human Interface Guidelines, selections should not be persistent -- + deselect the row after it has been selected. + */ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +#pragma mark - +#pragma mark Update events + +- (void)updateTime:(NSTimer *)timer { + /* + To display the current time, redisplay the time labels. + Don't reload the table view's data as this is unnecessarily expensive -- it recalculates the number of cells and the height of each item to determine the total height of the view etc. The external dimensions of the cells haven't changed, just their contents. + */ + NSArray *visibleCells = self.tableView.visibleCells; + for (TimeZoneCell *cell in visibleCells) { + [cell redisplay]; + } +} + + +- (void)updateRegions:(id)sender { + /* + The following sets the date for the regions, hence also for the time zone wrappers. This has the side-effect of "faulting" the time zone wrappers (see TimeZoneWrapper's setDate: method), so can be used to relieve memory pressure. + */ + NSDate *date = [NSDate date]; + for (Region *region in displayList) { + [region setDate:date]; + } +} + + +#pragma mark - +#pragma mark Timer set accessor methods + +- (void)setMinuteTimer:(NSTimer *)newTimer { + + if (minuteTimer != newTimer) { + [minuteTimer invalidate]; + minuteTimer = newTimer; + } +} + + +- (void)setRegionsTimer:(NSTimer *)newTimer { + + if (regionsTimer != newTimer) { + [regionsTimer invalidate]; + regionsTimer = newTimer; + } +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + + [super didReceiveMemoryWarning]; + [self updateRegions:self]; +} + + +- (void)dealloc { + [minuteTimer invalidate]; + [regionsTimer invalidate]; + [displayList release]; + [calendar release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneCell.h b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneCell.h new file mode 100644 index 0000000..00eacd3 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneCell.h @@ -0,0 +1,62 @@ + +/* + File: TimeZoneCell.h + Abstract: A table view cell to display various pieces of information about a time zone. Since the content is fairly complex and can't readily be rendered using three simple subviews, it uses a TimeZoneView to display the content. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class TimeZoneWrapper; +@class TimeZoneView; + +@interface TimeZoneCell : UITableViewCell { + TimeZoneView *timeZoneView; +} + +- (void)setTimeZoneWrapper:(TimeZoneWrapper *)newTimeZoneWrapper; +@property (nonatomic, retain) TimeZoneView *timeZoneView; + +- (void)redisplay; + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneCell.m b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneCell.m new file mode 100644 index 0000000..96f5584 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneCell.m @@ -0,0 +1,92 @@ + +/* + File: TimeZoneCell.m + Abstract: A table view cell to display various pieces of information about a time zone. Since the content is fairly complex and can't readily be rendered using three simple subviews, it uses a TimeZoneView to display the content. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TimeZoneCell.h" +#import "TimeZoneWrapper.h" +#import "TimeZoneView.h" +#import "CustomTableViewCellAppDelegate.h" + + +@implementation TimeZoneCell + +@synthesize timeZoneView; + + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + + if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]) { + + // Create a time zone view and add it as a subview of self's contentView. + CGRect tzvFrame = CGRectMake(0.0, 0.0, self.contentView.bounds.size.width, self.contentView.bounds.size.height); + timeZoneView = [[TimeZoneView alloc] initWithFrame:tzvFrame]; + timeZoneView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.contentView addSubview:timeZoneView]; + } + return self; +} + + +- (void)setTimeZoneWrapper:(TimeZoneWrapper *)newTimeZoneWrapper { + // Pass the time zone wrapper to the view + timeZoneView.timeZoneWrapper = newTimeZoneWrapper; +} + + +- (void)redisplay { + [timeZoneView setNeedsDisplay]; +} + + +- (void)dealloc { + [timeZoneView release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneView.h b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneView.h new file mode 100644 index 0000000..b458899 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneView.h @@ -0,0 +1,66 @@ + +/* + File: TimeZoneView.h + Abstract: A view to display various pieces of information about a time zone. Since the the view's content is fairly complex, to optimize scolling performance it draws its content directly in drawRect:. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class TimeZoneWrapper; + +@interface TimeZoneView : UIView { + TimeZoneWrapper *timeZoneWrapper; + NSDateFormatter *dateFormatter; + NSString *abbreviation; + BOOL highlighted; + BOOL editing; +} + +@property (nonatomic, retain) TimeZoneWrapper *timeZoneWrapper; +@property (nonatomic, retain) NSDateFormatter *dateFormatter; +@property (nonatomic, retain) NSString *abbreviation; +@property (nonatomic, getter=isHighlighted) BOOL highlighted; +@property (nonatomic, getter=isEditing) BOOL editing; + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneView.m b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneView.m new file mode 100644 index 0000000..82f9cff --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneView.m @@ -0,0 +1,209 @@ + +/* + File: TimeZoneView.m + Abstract: A view to display various pieces of information about a time zone. Since the the view's content is fairly complex, to optimize scolling performance it draws its content directly in drawRect:. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TimeZoneView.h" +#import "TimeZoneWrapper.h" + +@implementation TimeZoneView + +@synthesize timeZoneWrapper; +@synthesize dateFormatter; +@synthesize abbreviation; +@synthesize highlighted; +@synthesize editing; + + +- (id)initWithFrame:(CGRect)frame { + + if (self = [super initWithFrame:frame]) { + + /* + Cache the formatter. Normally you would use one of the date formatter styles (such as NSDateFormatterShortStyle), but here we want a specific format that excludes seconds. + */ + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"h:mm a"]; + self.opaque = YES; + self.backgroundColor = [UIColor whiteColor]; + } + return self; +} + + +- (void)setTimeZoneWrapper:(TimeZoneWrapper *)newTimeZoneWrapper { + + // If the time zone wrapper changes, update the date formatter and abbreviation string. + if (timeZoneWrapper != newTimeZoneWrapper) { + [timeZoneWrapper release]; + timeZoneWrapper = [newTimeZoneWrapper retain]; + + [dateFormatter setTimeZone:timeZoneWrapper.timeZone]; + + NSString *string = [[NSString alloc] initWithFormat:@"%@ (%@)", timeZoneWrapper.abbreviation, timeZoneWrapper.gmtOffset]; + self.abbreviation = string; + [string release]; + } + // May be the same wrapper, but the date may have changed, so mark for redisplay. + [self setNeedsDisplay]; +} + + +- (void)setHighlighted:(BOOL)lit { + // If highlighted state changes, need to redisplay. + if (highlighted != lit) { + highlighted = lit; + [self setNeedsDisplay]; + } +} + + +- (void)drawRect:(CGRect)rect { + +#define LEFT_COLUMN_OFFSET 10 +#define LEFT_COLUMN_WIDTH 130 + +#define MIDDLE_COLUMN_OFFSET 140 +#define MIDDLE_COLUMN_WIDTH 110 + +#define RIGHT_COLUMN_OFFSET 270 + +#define UPPER_ROW_TOP 8 +#define LOWER_ROW_TOP 34 + +#define MAIN_FONT_SIZE 18 +#define MIN_MAIN_FONT_SIZE 16 +#define SECONDARY_FONT_SIZE 12 +#define MIN_SECONDARY_FONT_SIZE 10 + + // Color and font for the main text items (time zone name, time) + UIColor *mainTextColor = nil; + UIFont *mainFont = [UIFont systemFontOfSize:MAIN_FONT_SIZE]; + + // Color and font for the secondary text items (GMT offset, day) + UIColor *secondaryTextColor = nil; + UIFont *secondaryFont = [UIFont systemFontOfSize:SECONDARY_FONT_SIZE]; + + // Choose font color based on highlighted state. + if (self.highlighted) { + mainTextColor = [UIColor whiteColor]; + secondaryTextColor = [UIColor whiteColor]; + } + else { + mainTextColor = [UIColor blackColor]; + secondaryTextColor = [UIColor darkGrayColor]; + self.backgroundColor = [UIColor whiteColor]; + } + + CGRect contentRect = self.bounds; + + // In this example we will never be editing, but this illustrates the appropriate pattern. + if (!self.editing) { + + CGFloat boundsX = contentRect.origin.x; + CGPoint point; + + CGFloat actualFontSize; + CGSize size; + + // Set the color for the main text items. + [mainTextColor set]; + + /* + Draw the locale name top left; use the NSString UIKit method to scale the font size down if the text does not fit in the given area + */ + point = CGPointMake(boundsX + LEFT_COLUMN_OFFSET, UPPER_ROW_TOP); + [timeZoneWrapper.timeZoneLocaleName drawAtPoint:point forWidth:LEFT_COLUMN_WIDTH withFont:mainFont minFontSize:MIN_MAIN_FONT_SIZE actualFontSize:NULL lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; + + /* + Draw the current time, right-aligned in the middle column. + To ensure it is right-aligned, first find its width with the given font and minimum allowed font size. Then draw the string at the appropriate offset. + */ + NSString *timeString = [dateFormatter stringFromDate:[NSDate date]]; + size = [timeString sizeWithFont:mainFont minFontSize:MIN_MAIN_FONT_SIZE actualFontSize:&actualFontSize forWidth:MIDDLE_COLUMN_WIDTH lineBreakMode:UILineBreakModeTailTruncation]; + + point = CGPointMake(boundsX + MIDDLE_COLUMN_OFFSET + MIDDLE_COLUMN_WIDTH - size.width, UPPER_ROW_TOP); + [timeString drawAtPoint:point forWidth:MIDDLE_COLUMN_WIDTH withFont:mainFont minFontSize:actualFontSize actualFontSize:&actualFontSize lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; + + + // Set the color for the secondary text items. + [secondaryTextColor set]; + + /* + Draw the abbreviation botton left; use the NSString UIKit method to scale the font size down if the text does not fit in the given area. + */ + point = CGPointMake(boundsX + LEFT_COLUMN_OFFSET, LOWER_ROW_TOP); + [abbreviation drawAtPoint:point forWidth:LEFT_COLUMN_WIDTH withFont:secondaryFont minFontSize:MIN_SECONDARY_FONT_SIZE actualFontSize:NULL lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; + + /* + Draw the whichDay string, right-aligned in the middle column. + To ensure it is right-aligned, first find its width with the given font and minimum allowed font size. Then draw the string at the appropriate offset. + */ + size = [timeZoneWrapper.whichDay sizeWithFont:secondaryFont minFontSize:MIN_SECONDARY_FONT_SIZE actualFontSize:&actualFontSize forWidth:MIDDLE_COLUMN_WIDTH lineBreakMode:UILineBreakModeTailTruncation]; + + point = CGPointMake(boundsX + MIDDLE_COLUMN_OFFSET + MIDDLE_COLUMN_WIDTH - size.width, LOWER_ROW_TOP); + [timeZoneWrapper.whichDay drawAtPoint:point forWidth:LEFT_COLUMN_WIDTH withFont:secondaryFont minFontSize:actualFontSize actualFontSize:&actualFontSize lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; + + + // Draw the quarter image. + CGFloat imageY = (contentRect.size.height - timeZoneWrapper.image.size.height) / 2; + + point = CGPointMake(boundsX + RIGHT_COLUMN_OFFSET, imageY); + [timeZoneWrapper.image drawAtPoint:point]; + } +} + + +- (void)dealloc { + [timeZoneWrapper release]; + [dateFormatter release]; + [abbreviation release]; + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneWrapper.h b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneWrapper.h new file mode 100644 index 0000000..e425055 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneWrapper.h @@ -0,0 +1,75 @@ + +/* + File: TimeZoneWrapper.h + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TimeZoneWrapper : NSObject { + NSTimeZone *timeZone; + NSString *timeZoneLocaleName; + + NSDate *date; + NSCalendar *calendar; + + NSString *whichDay; + NSString *abbreviation; + NSString *gmtOffset; + UIImage *image; +} + +@property (nonatomic, retain) NSTimeZone *timeZone; +@property (nonatomic, retain) NSString *timeZoneLocaleName; +@property (nonatomic, retain) NSDate *date; +@property (nonatomic, retain) NSCalendar *calendar; + +@property (nonatomic, retain) NSString *whichDay; +@property (nonatomic, retain) NSString *abbreviation; +@property (nonatomic, retain) NSString *gmtOffset; +@property (nonatomic, retain) UIImage *image; + +- initWithTimeZone:(NSTimeZone *)tz nameComponents:(NSArray *)nameComponents; + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneWrapper.m b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneWrapper.m new file mode 100644 index 0000000..0ff70e9 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Classes/TimeZoneWrapper.m @@ -0,0 +1,227 @@ +/* + File: TimeZoneWrapper.m + Abstract: Object to represent a time zone, caching various derived properties that are expensive to compute. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TimeZoneWrapper.h" +#import "CustomTableViewCellAppDelegate.h" + + +static NSString *today; +static NSString *tomorrow; +static NSString *yesterday; + +static UIImage *q1Image; +static UIImage *q2Image; +static UIImage *q3Image; +static UIImage *q4Image; + + +@implementation TimeZoneWrapper + +@synthesize timeZone; +@synthesize timeZoneLocaleName; +@synthesize date; +@synthesize calendar; + +@synthesize whichDay; +@synthesize abbreviation; +@synthesize gmtOffset; +@synthesize image; + + ++ (void)initialize { + // Unlikely to have any subclasses, but check class nevertheless. + if (self == [TimeZoneWrapper class]) { + today = [NSLocalizedString(@"Today", "Today") retain]; + tomorrow = [NSLocalizedString(@"Tomorrow", "Tomorrow") retain]; + yesterday = [NSLocalizedString(@"Yesterday", "Yesterday") retain]; + + q1Image = [[UIImage imageNamed:@"12-6AM.png"] retain]; + q2Image = [[UIImage imageNamed:@"6-12AM.png"] retain]; + q3Image = [[UIImage imageNamed:@"12-6PM.png"] retain]; + q4Image = [[UIImage imageNamed:@"6-12PM.png"] retain]; + } +} + + +- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents { + + if (self = [super init]) { + timeZone = [aTimeZone retain]; + if ([nameComponents count] == 2) { + timeZoneLocaleName = [[nameComponents objectAtIndex:1] copy]; + } + else if ([nameComponents count] == 3) { + timeZoneLocaleName = [[NSString alloc] initWithFormat:@"%@ (%@)", [nameComponents objectAtIndex:2], [nameComponents objectAtIndex:1]]; + } + } + return self; +} + + +/* + By default, we don't actually calculate whichDay, abreviation, gmtOffset or image. + They're expensive to compute, and consume memory. Calculate them on demand, then cache them. + */ + +- (NSString *)whichDay { + + // Return "today", "tomorrow", or "yesterday" as appropriate for the time zone. + + if (whichDay == nil) { + NSDateComponents *dateComponents; + NSInteger myDay, tzDay; + + // Set the calendar's time zone to the default time zone. + [calendar setTimeZone:App_defaultTimeZone]; + dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:date]; + myDay = [dateComponents weekday]; + + [calendar setTimeZone:timeZone]; + dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:date]; + tzDay = [dateComponents weekday]; + + NSRange dayRange = [calendar maximumRangeOfUnit:NSWeekdayCalendarUnit]; + NSInteger maxDay = NSMaxRange(dayRange) - 1; + + if (myDay == tzDay) { + self.whichDay = today; + } else { + if ((tzDay - myDay) > 0) { + self.whichDay = tomorrow; + } else { + self.whichDay = yesterday; + } + // Special cases for days at the end of the week + if ((myDay == maxDay) && (tzDay == 1)) { + self.whichDay = tomorrow; + } + if ((myDay == 1) && (tzDay == maxDay)) { + self.whichDay = yesterday; + } + } + } + return whichDay; +} + + +- (NSString *)abbreviation { + // Return the abbreviation for the time zone. + if (abbreviation == nil) { + self.abbreviation = [timeZone abbreviationForDate:date]; + } + return abbreviation; +} + + +- (NSString *)gmtOffset { + // Return the offset from GMT for the time zone. + if (gmtOffset == nil) { + self.gmtOffset = [timeZone localizedName:NSTimeZoneNameStyleShortStandard locale:[NSLocale currentLocale]]; + } + return gmtOffset; +} + + +- (UIImage *)image { + // Return an image that illustrates the quarter of the current day in the time zone. + if (image == nil) { + [calendar setTimeZone:timeZone]; + NSDateComponents *dateComponents = [calendar components:NSHourCalendarUnit fromDate:date]; + NSInteger hour = [dateComponents hour]; + if (hour > 17) { + self.image = q4Image; + } else { + if (hour > 11) { + self.image = q3Image; + } else { + if (hour > 5) { + self.image = q2Image; + } else { + self.image = q1Image; + } + } + } + } + return image; +} + + +- (void)setDate:(NSDate *)newDate { + /* + Recalculating all the details is expensive. + Only change the date if it is not actually equal to the current date. + If the date is different, "fault" the receiver: nill out all the cached values -- if accessed, they will be recaulculated. + */ + if ([newDate isEqualToDate:date]) { + return; + } + [date release]; + date = [newDate retain]; + self.abbreviation = nil; + self.abbreviation = nil; + self.gmtOffset = nil; + self.image = nil; +} + + +- (void)dealloc { + [timeZone release]; + [timeZoneLocaleName release]; + [date release]; + [calendar release]; + + [whichDay release]; + [abbreviation release]; + [gmtOffset release]; + [image release]; + + [super dealloc]; +} + + +@end diff --git a/TableViewSuite/5_CustomTableViewCell/CustomTableViewCell.xcodeproj/project.pbxproj b/TableViewSuite/5_CustomTableViewCell/CustomTableViewCell.xcodeproj/project.pbxproj new file mode 100755 index 0000000..b042602 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/CustomTableViewCell.xcodeproj/project.pbxproj @@ -0,0 +1,383 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28275AF10D6E02D900A8AFA4 /* TimeZoneWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 28275AF00D6E02D900A8AFA4 /* TimeZoneWrapper.m */; }; + 2867DEFA0D581C1F0037AED8 /* TimeZoneCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2867DEF90D581C1F0037AED8 /* TimeZoneCell.m */; }; + 2867DEFD0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2867DEFB0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.m */; }; + 28BDD37E0D628913006FBFB9 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28BDD37D0D628913006FBFB9 /* RootViewController.m */; }; + 28CA94D90DECC7100008F9FE /* TimeZoneView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28CA94D80DECC7100008F9FE /* TimeZoneView.m */; }; + 28D655C30D6E3F78005F58A3 /* Region.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D655C20D6E3F78005F58A3 /* Region.m */; }; + 28F1A71C0DC92FE900332FD8 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 28F1A71A0DC92FE900332FD8 /* Localizable.strings */; }; + 5330886111D3DA4D00FAABF5 /* 12-6AM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885511D3DA4D00FAABF5 /* 12-6AM.png */; }; + 5330886211D3DA4D00FAABF5 /* 12-6PM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885611D3DA4D00FAABF5 /* 12-6PM.png */; }; + 5330886311D3DA4D00FAABF5 /* 6-12AM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885711D3DA4D00FAABF5 /* 6-12AM.png */; }; + 5330886411D3DA4D00FAABF5 /* 6-12PM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885811D3DA4D00FAABF5 /* 6-12PM.png */; }; + 5330886511D3DA4D00FAABF5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885911D3DA4D00FAABF5 /* Default.png */; }; + 5330886611D3DA4D00FAABF5 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885A11D3DA4D00FAABF5 /* Icon-72.png */; }; + 5330886711D3DA4D00FAABF5 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885B11D3DA4D00FAABF5 /* Icon-Small-50.png */; }; + 5330886811D3DA4D00FAABF5 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885C11D3DA4D00FAABF5 /* Icon-Small.png */; }; + 5330886911D3DA4D00FAABF5 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885D11D3DA4D00FAABF5 /* Icon-Small@2x.png */; }; + 5330886A11D3DA4D00FAABF5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885E11D3DA4D00FAABF5 /* Icon.png */; }; + 5330886B11D3DA4D00FAABF5 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5330885F11D3DA4D00FAABF5 /* Icon@2x.png */; }; + 5330886C11D3DA4D00FAABF5 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 5330886011D3DA4D00FAABF5 /* iTunesArtwork */; }; + 535E84AA11C8301A00010817 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 535E84A811C8301A00010817 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* CustomTableViewCell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomTableViewCell.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28275AEF0D6E02D900A8AFA4 /* TimeZoneWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimeZoneWrapper.h; path = Classes/TimeZoneWrapper.h; sourceTree = ""; }; + 28275AF00D6E02D900A8AFA4 /* TimeZoneWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TimeZoneWrapper.m; path = Classes/TimeZoneWrapper.m; sourceTree = ""; }; + 2867DEF80D581C1F0037AED8 /* TimeZoneCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeZoneCell.h; sourceTree = ""; }; + 2867DEF90D581C1F0037AED8 /* TimeZoneCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimeZoneCell.m; sourceTree = ""; }; + 2867DEFB0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomTableViewCellAppDelegate.m; sourceTree = ""; }; + 2867DEFC0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTableViewCellAppDelegate.h; sourceTree = ""; }; + 28BDD37C0D628913006FBFB9 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28BDD37D0D628913006FBFB9 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28CA94D70DECC7100008F9FE /* TimeZoneView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeZoneView.h; sourceTree = ""; }; + 28CA94D80DECC7100008F9FE /* TimeZoneView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimeZoneView.m; sourceTree = ""; }; + 28D655C10D6E3F78005F58A3 /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Region.h; path = Classes/Region.h; sourceTree = ""; }; + 28D655C20D6E3F78005F58A3 /* Region.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Region.m; path = Classes/Region.m; sourceTree = ""; }; + 28F1A71B0DC92FE900332FD8 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A7200DC9300100332FD8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A7210DC9300800332FD8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 28F1A8850DC9365F00332FD8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ReadMe.txt; path = ../ReadMe.txt; sourceTree = SOURCE_ROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* CustomTableViewCell_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTableViewCell_Prefix.pch; sourceTree = ""; }; + 5330885511D3DA4D00FAABF5 /* 12-6AM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "12-6AM.png"; sourceTree = ""; }; + 5330885611D3DA4D00FAABF5 /* 12-6PM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "12-6PM.png"; sourceTree = ""; }; + 5330885711D3DA4D00FAABF5 /* 6-12AM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "6-12AM.png"; sourceTree = ""; }; + 5330885811D3DA4D00FAABF5 /* 6-12PM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "6-12PM.png"; sourceTree = ""; }; + 5330885911D3DA4D00FAABF5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 5330885A11D3DA4D00FAABF5 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 5330885B11D3DA4D00FAABF5 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 5330885C11D3DA4D00FAABF5 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 5330885D11D3DA4D00FAABF5 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 5330885E11D3DA4D00FAABF5 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 5330885F11D3DA4D00FAABF5 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 5330886011D3DA4D00FAABF5 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 535E84A911C8301A00010817 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Views and Controllers */ = { + isa = PBXGroup; + children = ( + 28BDD37C0D628913006FBFB9 /* RootViewController.h */, + 28BDD37D0D628913006FBFB9 /* RootViewController.m */, + 2867DEF80D581C1F0037AED8 /* TimeZoneCell.h */, + 2867DEF90D581C1F0037AED8 /* TimeZoneCell.m */, + 28CA94D70DECC7100008F9FE /* TimeZoneView.h */, + 28CA94D80DECC7100008F9FE /* TimeZoneView.m */, + 2867DEFC0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.h */, + 2867DEFB0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.m */, + ); + name = "Views and Controllers"; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* CustomTableViewCell.app */, + ); + name = Products; + sourceTree = ""; + }; + 28275B330D6E06C500A8AFA4 /* Model Classes */ = { + isa = PBXGroup; + children = ( + 28D655C10D6E3F78005F58A3 /* Region.h */, + 28D655C20D6E3F78005F58A3 /* Region.m */, + 28275AEF0D6E02D900A8AFA4 /* TimeZoneWrapper.h */, + 28275AF00D6E02D900A8AFA4 /* TimeZoneWrapper.m */, + ); + name = "Model Classes"; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 28F1A8850DC9365F00332FD8 /* ReadMe.txt */, + 28275B330D6E06C500A8AFA4 /* Model Classes */, + 080E96DDFE201D6D7F000001 /* Views and Controllers */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* CustomTableViewCell_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 5330885411D3DA4D00FAABF5 /* images */, + 535E84A811C8301A00010817 /* MainWindow.xib */, + 28F1A71A0DC92FE900332FD8 /* Localizable.strings */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5330885411D3DA4D00FAABF5 /* images */ = { + isa = PBXGroup; + children = ( + 5330885511D3DA4D00FAABF5 /* 12-6AM.png */, + 5330885611D3DA4D00FAABF5 /* 12-6PM.png */, + 5330885711D3DA4D00FAABF5 /* 6-12AM.png */, + 5330885811D3DA4D00FAABF5 /* 6-12PM.png */, + 5330885911D3DA4D00FAABF5 /* Default.png */, + 5330885A11D3DA4D00FAABF5 /* Icon-72.png */, + 5330885B11D3DA4D00FAABF5 /* Icon-Small-50.png */, + 5330885C11D3DA4D00FAABF5 /* Icon-Small.png */, + 5330885D11D3DA4D00FAABF5 /* Icon-Small@2x.png */, + 5330885E11D3DA4D00FAABF5 /* Icon.png */, + 5330885F11D3DA4D00FAABF5 /* Icon@2x.png */, + 5330886011D3DA4D00FAABF5 /* iTunesArtwork */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* CustomTableViewCell */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "CustomTableViewCell" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CustomTableViewCell; + productName = CustomTableViewCell; + productReference = 1D6058910D05DD3D006BFB54 /* CustomTableViewCell.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CustomTableViewCell" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + french, + en, + fr, + de, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* CustomTableViewCell */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28F1A71C0DC92FE900332FD8 /* Localizable.strings in Resources */, + 535E84AA11C8301A00010817 /* MainWindow.xib in Resources */, + 5330886111D3DA4D00FAABF5 /* 12-6AM.png in Resources */, + 5330886211D3DA4D00FAABF5 /* 12-6PM.png in Resources */, + 5330886311D3DA4D00FAABF5 /* 6-12AM.png in Resources */, + 5330886411D3DA4D00FAABF5 /* 6-12PM.png in Resources */, + 5330886511D3DA4D00FAABF5 /* Default.png in Resources */, + 5330886611D3DA4D00FAABF5 /* Icon-72.png in Resources */, + 5330886711D3DA4D00FAABF5 /* Icon-Small-50.png in Resources */, + 5330886811D3DA4D00FAABF5 /* Icon-Small.png in Resources */, + 5330886911D3DA4D00FAABF5 /* Icon-Small@2x.png in Resources */, + 5330886A11D3DA4D00FAABF5 /* Icon.png in Resources */, + 5330886B11D3DA4D00FAABF5 /* Icon@2x.png in Resources */, + 5330886C11D3DA4D00FAABF5 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2867DEFA0D581C1F0037AED8 /* TimeZoneCell.m in Sources */, + 2867DEFD0D581C2E0037AED8 /* CustomTableViewCellAppDelegate.m in Sources */, + 28BDD37E0D628913006FBFB9 /* RootViewController.m in Sources */, + 28275AF10D6E02D900A8AFA4 /* TimeZoneWrapper.m in Sources */, + 28D655C30D6E3F78005F58A3 /* Region.m in Sources */, + 28CA94D90DECC7100008F9FE /* TimeZoneView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 28F1A71A0DC92FE900332FD8 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 28F1A71B0DC92FE900332FD8 /* en */, + 28F1A7200DC9300100332FD8 /* fr */, + 28F1A7210DC9300800332FD8 /* de */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 535E84A811C8301A00010817 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 535E84A911C8301A00010817 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = CustomTableViewCell_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = CustomTableViewCell; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = CustomTableViewCell_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = CustomTableViewCell; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "CustomTableViewCell" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CustomTableViewCell" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TableViewSuite/5_CustomTableViewCell/CustomTableViewCell_Prefix.pch b/TableViewSuite/5_CustomTableViewCell/CustomTableViewCell_Prefix.pch new file mode 100644 index 0000000..c452461 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/CustomTableViewCell_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'CustomTableViewCell' target in the 'CustomTableViewCell' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TableViewSuite/5_CustomTableViewCell/Info.plist b/TableViewSuite/5_CustomTableViewCell/Info.plist new file mode 100644 index 0000000..45f1ff2 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + CustomTableViewCell + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Icon.png + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 2.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TableViewSuite/5_CustomTableViewCell/de.lproj/Localizable.strings b/TableViewSuite/5_CustomTableViewCell/de.lproj/Localizable.strings new file mode 100644 index 0000000..7aa1564 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/de.lproj/Localizable.strings @@ -0,0 +1,4 @@ + +"Today" = "Heute"; +"Tomorrow" = "Morgen"; +"Yesterday" = "Gestern"; diff --git a/TableViewSuite/5_CustomTableViewCell/de.lproj/MainWindow.xib b/TableViewSuite/5_CustomTableViewCell/de.lproj/MainWindow.xib new file mode 100644 index 0000000..af449f9 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/de.lproj/MainWindow.xib @@ -0,0 +1,181 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + window + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + CustomTableViewCellAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{443, 368}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + CustomTableViewCellAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + CustomTableViewCellAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/CustomTableViewCellAppDelegate.h + + + + + 0 + CustomTableViewCell.xcodeproj + 3 + + diff --git a/TableViewSuite/5_CustomTableViewCell/en.lproj/Localizable.strings b/TableViewSuite/5_CustomTableViewCell/en.lproj/Localizable.strings new file mode 100644 index 0000000..0c96980 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/en.lproj/Localizable.strings differ diff --git a/TableViewSuite/5_CustomTableViewCell/en.lproj/MainWindow.xib b/TableViewSuite/5_CustomTableViewCell/en.lproj/MainWindow.xib new file mode 100644 index 0000000..af449f9 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/en.lproj/MainWindow.xib @@ -0,0 +1,181 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + window + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + CustomTableViewCellAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{443, 368}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + CustomTableViewCellAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + CustomTableViewCellAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/CustomTableViewCellAppDelegate.h + + + + + 0 + CustomTableViewCell.xcodeproj + 3 + + diff --git a/TableViewSuite/5_CustomTableViewCell/fr.lproj/Localizable.strings b/TableViewSuite/5_CustomTableViewCell/fr.lproj/Localizable.strings new file mode 100644 index 0000000..eb2e4ad --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/fr.lproj/Localizable.strings @@ -0,0 +1,4 @@ + +"Today" = "Aujourd'hui"; +"Tomorrow" = "Demain"; +"Yesterday" = "Hier"; diff --git a/TableViewSuite/5_CustomTableViewCell/fr.lproj/MainWindow.xib b/TableViewSuite/5_CustomTableViewCell/fr.lproj/MainWindow.xib new file mode 100644 index 0000000..af449f9 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/fr.lproj/MainWindow.xib @@ -0,0 +1,181 @@ + + + + 768 + 9J50 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + YES + + + window + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + CustomTableViewCellAppDelegate + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{443, 368}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + CustomTableViewCellAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + CustomTableViewCellAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/CustomTableViewCellAppDelegate.h + + + + + 0 + CustomTableViewCell.xcodeproj + 3 + + diff --git a/TableViewSuite/5_CustomTableViewCell/images/12-6AM.png b/TableViewSuite/5_CustomTableViewCell/images/12-6AM.png new file mode 100644 index 0000000..c7b411e Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/12-6AM.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/12-6PM.png b/TableViewSuite/5_CustomTableViewCell/images/12-6PM.png new file mode 100644 index 0000000..c544340 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/12-6PM.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/6-12AM.png b/TableViewSuite/5_CustomTableViewCell/images/6-12AM.png new file mode 100644 index 0000000..77f5a50 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/6-12AM.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/6-12PM.png b/TableViewSuite/5_CustomTableViewCell/images/6-12PM.png new file mode 100644 index 0000000..a77859e Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/6-12PM.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Default.png b/TableViewSuite/5_CustomTableViewCell/images/Default.png new file mode 100644 index 0000000..7cad83a Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Default.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Icon-72.png b/TableViewSuite/5_CustomTableViewCell/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Icon-72.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Icon-Small-50.png b/TableViewSuite/5_CustomTableViewCell/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Icon-Small-50.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Icon-Small.png b/TableViewSuite/5_CustomTableViewCell/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Icon-Small.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Icon-Small@2x.png b/TableViewSuite/5_CustomTableViewCell/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Icon-Small@2x.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Icon.png b/TableViewSuite/5_CustomTableViewCell/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Icon.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/Icon@2x.png b/TableViewSuite/5_CustomTableViewCell/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/Icon@2x.png differ diff --git a/TableViewSuite/5_CustomTableViewCell/images/iTunesArtwork b/TableViewSuite/5_CustomTableViewCell/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TableViewSuite/5_CustomTableViewCell/images/iTunesArtwork differ diff --git a/TableViewSuite/5_CustomTableViewCell/main.m b/TableViewSuite/5_CustomTableViewCell/main.m new file mode 100644 index 0000000..ab0d3a5 --- /dev/null +++ b/TableViewSuite/5_CustomTableViewCell/main.m @@ -0,0 +1,56 @@ + +/* + File: main.m + Abstract: Main source file for this sample. + + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TableViewSuite/ReadMe.txt b/TableViewSuite/ReadMe.txt new file mode 100644 index 0000000..6711db2 --- /dev/null +++ b/TableViewSuite/ReadMe.txt @@ -0,0 +1,194 @@ +### TableViewSuite ### + +================================================================================ +DESCRIPTION: + +This sample shows how to use UITableView through a progression of increasingly advanced applications that display information about time zones. + +* The first example shows a simple list of the time zone names. It shows how to display a simple data set in a table view. + +* The second example shows the time zones split into sections by region, with the region name as the section heading. It shows how to create an indexed table view. + +* The third example shows how to set up a table view to display an index. The time zones are separated into sections using UILocalizedIndexedCollation. + +When implementing a table view cell, there's a tension between optimal scrolling performance and optimal edit/reordering performance. You should typically use subviews in the cell's content view. + +When you have an edit or reordering control, using subviews makes the implementation easier, and the animations perform better because UIKit doesn't have to redraw during animations. + +Subviews have two costs: +1) Initialization. This can be largely mitigated by reusing table cells. +2) Compositing. This can be largely mitigated by making the views opaque. Often, one translucent subview is fine, but more than one frequently causes frame drops while scrolling. + +If the content is complex, however (more than about three subviews), scrolling performance may suffer. If this becomes a problem, you can instead draw directly in a subview of the table view cell's content view. + +* The fourth example displays more information about each time zone, such as the time and relative day in that time zone. Its main aim is to show how you can customize a table view cell using subviews. It also introduces custom classes to represent regions and time zones to help reduce the overhead of calculating the required information -- these are also used in the fifth example. + +* The fifth example is an extension of the fourth. It displays even more information about each time zone, such as the time and relative day in that time zone. Its shows how you can create a custom table view cell that contains a custom view that draws its content in -drawRect:. + + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + + +1_SimpleTableView +----------------- +1_SimpleTableView/Classes/RootViewController.{h,m} +View controller that sets up the table view and serves as the table view's data source and delegate. + +1_SimpleTableView/Classes/SimpleTableViewAppDelegate.{h,m} +Application delegate that configures the view controller. + +1_SimpleTableView/MainWindow.xib +The xib file containing the application's main window. + +1_SimpleTableView/en.lproj/Localizable.strings +Strings file containing localization dictionary. + + + +2_SimpleSectionedTableView +-------------------------- +2_SimpleSectionedTableView/Classes/RootViewController.{h,m} +View controller that serves as the table view's data source and delegate. It also set up the data. + +2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.{h,m} +Application delegate that configures the view controller. + +2_SimpleSectionedTableView/Classes/Region.{h,m} +Object to represent a region containing the corresponding time zone wrappers. + +2_SimpleSectionedTableView/Classes/TimeZoneWrapper.{h,m} +Object to represent a time zone, caching various derived properties that are expensive to compute. + +2_SimpleSectionedTableView/MainWindow.xib +The xib file containing the application's main window. + +2_SimpleSectionedTableView/en.lproj/Localizable.strings +Strings file containing localization dictionary. + + + +3_SimpleIndexedTableView +------------------------ +3_SimpleIndexedTableView/Classes/RootViewController.{h,m} +View controller that serves as the table view's data source and delegate. It uses the current UILocalizedIndexedCollation object to organize the time zones into appropriate sections, and also to provide information about section titles and section index titles. + +3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate..{h,m} +Application delegate that configures the view controller. + +3_SimpleIndexedTableView/Classes/TimeZoneWrapper.{h,m} +Object to represent a time zone, caching various derived properties that are expensive to compute. + +3_SimpleIndexedTableView/MainWindow.xib +The xib file containing the application's main window. + +3_SimpleIndexedTableView/en.lproj/Localizable.strings +Strings file containing localization dictionary. + + + +4_TableViewCellSubviews +----------------------- +4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.{h,m} +Application delegate that sets up the navigation controller and the root view controller. + +4_TableViewCellSubviews/Classes/RootViewController.{h,m} +View controller that sets up the table view and the time zone data. + +4_TableViewCellSubviews/Classes/Region.{h,m} +Object to represent a region containing the corresponding time zone wrappers. + +4_TableViewCellSubviews/Classes/TimeZoneWrapper.{h,m} +Object to represent a time zone, caching various derived properties that are expensive to compute. + +4_TableViewCellSubviews/MainWindow.xib +The xib file containing the application's main window. + +4_TableViewCellSubviews/en.lproj/Localizable.strings +Strings file containing localization dictionary. + + + +5_CustomTableViewCell +--------------------- +5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.{h,m} +Application delegate that sets up the navigation controller and the root view controller. + +5_CustomTableViewCell/Classes/RootViewController.{h,m} +View controller that sets up the table view and the time zone data. + +5_CustomTableViewCell/Classes/Region.{h,m} +Object to represent a region containing the corresponding time zone wrappers. + +5_CustomTableViewCell/Classes/TimeZoneWrapper.{h,m} +Object to represent a time zone, caching various derived properties that are expensive to compute. + +5_CustomTableViewCell/Classes/TimeZoneCell.{h,m} +A table view cell to display various pieces of information about a time zone.. + +5_CustomTableViewCell/Classes/TimeZoneView.{h,m} +A view to display various pieces of information about a time zone. + +5_CustomTableViewCell/MainWindow.xib +The xib file containing the application's main window. + +5_CustomTableViewCell/en.lproj/Localizable.strings +Strings file containing localization dictionary. + + + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Verrsion 2.4 +- Upgraded project to build with the iOS 4 SDK, fixed NSTimeZoneWrapper parsing bug, replaced use of deprecated NSDate "addTimeInterval". + +Version 2.0 +- Corrected a memory leak in the displayMethod in CustomTableViewCellAppDelegate.m. + +Version 2.0 +- Updated for and tested with iPhone OS 3.0. +- Adopted new UITableViewCell API where appropriate. +- SimpleIndexedTableView uses UILocalizedIndexedCollation. +- Application data created by the application delegate but passed to the first view controller. + + +Version 1.8 +- Updated for and tested with iPhone OS 2.0. First public release. +- Modified fourth and fifth examples to make timer-based updates more efficient. + +Version 1.7 +- Modified fourth and added fifth example. + +Version 1.6 +- Updated the Default.png image. +- Added LSRequiresIPhoneOS flag to Info.plist files. + +Version 1.5 +- Updated for Beta 5. +- Added localized strings files. +- Made minor changes to project file -- added ReadMe, removed project-level override for ALWAYS_SEARCH_USER_PATHS, added override at target level. +- Removed Visible At Launch flag from window in MainWindow.xib; added [window makeKeyAndVisible] in application delegate. + +Version 1.4 +- Updated for Beta 4. +- Adopts the new pattern in the Cocoa Touch List project template. +- The application delegate serves as the controller for the application's data; the table view controllers retrieve data from the application delegate. +- Minor changes to artwork. + +Version 1.3 +- Updated for Beta 3. +- The samples now use nib files and UITableViewController; they also adopt the new pattern for table cell reuse. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/TaggedLocations.zip b/TaggedLocations.zip new file mode 100644 index 0000000..717b8ed Binary files /dev/null and b/TaggedLocations.zip differ diff --git a/TaggedLocations/Classes/EditableTableViewCell.h b/TaggedLocations/Classes/EditableTableViewCell.h new file mode 100644 index 0000000..e080108 --- /dev/null +++ b/TaggedLocations/Classes/EditableTableViewCell.h @@ -0,0 +1,58 @@ + +/* + File: EditableTableViewCell.h + Abstract: Table view cell to present an editable text field to display tag names. + The cell layout is defined in the accompanying nib file -- EditableTableViewCell. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +@interface EditableTableViewCell : UITableViewCell { + UITextField *textField; +} + +@property (nonatomic, retain) IBOutlet UITextField *textField; + +@end diff --git a/TaggedLocations/Classes/EditableTableViewCell.m b/TaggedLocations/Classes/EditableTableViewCell.m new file mode 100644 index 0000000..6c83719 --- /dev/null +++ b/TaggedLocations/Classes/EditableTableViewCell.m @@ -0,0 +1,71 @@ + +/* + File: EditableTableViewCell.m + Abstract: Table view cell to present an editable text field to display tag names. + The cell layout is defined in the accompanying nib file -- EditableTableViewCell. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "EditableTableViewCell.h" + +@implementation EditableTableViewCell + +@synthesize textField; + + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + // The user can only edit the text field when in editing mode. + [super setEditing:editing animated:animated]; + textField.enabled = editing; +} + + +- (void)dealloc { + [textField release]; + [super dealloc]; +} + + +@end diff --git a/TaggedLocations/Classes/Event.h b/TaggedLocations/Classes/Event.h new file mode 100644 index 0000000..4aa65cc --- /dev/null +++ b/TaggedLocations/Classes/Event.h @@ -0,0 +1,71 @@ + +/* + File: Event.h + Abstract: A Core Data managed object class to represent an event containing geographical coordinates and a time stamp. + An event has a to-many relationship to Tag which represents tags associated with the event. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class Tag; + +@interface Event : NSManagedObject { +} + +@property (nonatomic, retain) NSString *name; +@property (nonatomic, retain) NSDate *creationDate; +@property (nonatomic, retain) NSNumber *latitude; +@property (nonatomic, retain) NSNumber *longitude; + +@property (nonatomic, retain) NSSet* tags; + +@end + + +@interface Event (TagsMethods) +- (void)addTagsObject:(Tag *)value; +- (void)removeTagsObject:(Tag *)value; +- (void)addTags:(NSSet *)value; +- (void)removeTags:(NSSet *)value; +@end + diff --git a/TaggedLocations/Classes/Event.m b/TaggedLocations/Classes/Event.m new file mode 100644 index 0000000..d0fe8df --- /dev/null +++ b/TaggedLocations/Classes/Event.m @@ -0,0 +1,61 @@ + +/* + File: Event.m + Abstract: A Core Data managed object class to represent an event containing geographical coordinates and a time stamp. + An event has a to-many relationship to Tag which represents tags associated with the event. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Event.h" +#import "Tag.h" + +@implementation Event + +@dynamic name; +@dynamic creationDate; +@dynamic latitude; +@dynamic longitude; +@dynamic tags; + +@end diff --git a/TaggedLocations/Classes/EventTableViewCell.h b/TaggedLocations/Classes/EventTableViewCell.h new file mode 100644 index 0000000..4fffb7d --- /dev/null +++ b/TaggedLocations/Classes/EventTableViewCell.h @@ -0,0 +1,66 @@ + +/* + File: EventTableViewCell.h + Abstract: Table view cell to display information about an event. + The cell layout is defined in the accompanying nib file -- EventTableViewCell. + Cells are loaded by the root view controller (the File's Owner), which is the target of the tags button's action. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface EventTableViewCell : UITableViewCell { + UITextField *nameField; + UILabel *creationDateLabel; + UILabel *locationLabel; + UITextField *tagsField; + UIButton *tagsButton; +} + +@property (nonatomic, retain) IBOutlet UITextField *nameField; +@property (nonatomic, retain) IBOutlet UILabel *creationDateLabel; +@property (nonatomic, retain) IBOutlet UILabel *locationLabel; +@property (nonatomic, retain) IBOutlet UITextField *tagsField; +@property (nonatomic, retain) IBOutlet UIButton *tagsButton; + +@end diff --git a/TaggedLocations/Classes/EventTableViewCell.m b/TaggedLocations/Classes/EventTableViewCell.m new file mode 100644 index 0000000..f205c4b --- /dev/null +++ b/TaggedLocations/Classes/EventTableViewCell.m @@ -0,0 +1,101 @@ + +/* + File: EventTableViewCell.m + Abstract: Table view cell to display information about an event. + The cell layout is defined in the accompanying nib file -- EventTableViewCell. + Cells are loaded by the root view controller (the File's Owner), which is the target of the tags button's action. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "EventTableViewCell.h" + + +@implementation EventTableViewCell + +@synthesize nameField, creationDateLabel, locationLabel, tagsField, tagsButton; + +/* + When the table view becomes editable, the cell should: + * Hide the location label (so that the Delete button does not overlap it) + * Enable the name field (to make it editable) + * Display the tags button + * Set a placeholder for the tags field (so the user knows to tap to edit tags) + The inverse applies when the table view has finished editing. + */ + +- (void)willTransitionToState:(UITableViewCellStateMask)state { + [super willTransitionToState:state]; + + if (state & UITableViewCellStateEditingMask) { + locationLabel.hidden = YES; + nameField.enabled = YES; + tagsButton.hidden = NO; + tagsField.placeholder = @"Tap to edit tags"; + } +} + +- (void)didTransitionToState:(UITableViewCellStateMask)state { + [super didTransitionToState:state]; + + if (!(state & UITableViewCellStateEditingMask)) { + locationLabel.hidden = NO; + nameField.enabled = NO; + tagsButton.hidden = YES; + tagsField.placeholder = @""; + } +} + + +- (void)dealloc { + [nameField release]; + [creationDateLabel release]; + [locationLabel release]; + [tagsField release]; + [tagsButton release]; + [super dealloc]; +} + + +@end diff --git a/TaggedLocations/Classes/RootViewController.h b/TaggedLocations/Classes/RootViewController.h new file mode 100644 index 0000000..1b682a7 --- /dev/null +++ b/TaggedLocations/Classes/RootViewController.h @@ -0,0 +1,80 @@ + +/* + File: RootViewController.h + Abstract: The table view controller responsible for displaying the list of events, supporting additional functionality: + * Addition of new new events; + * Deletion of existing events using UITableView's tableView:commitEditingStyle:forRowAtIndexPath: method. + * Editing an event's name. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class EventTableViewCell; + +@interface RootViewController : UITableViewController { + + NSMutableArray *eventsArray; + NSManagedObjectContext *managedObjectContext; + + CLLocationManager *locationManager; + UIBarButtonItem *addButton; + + EventTableViewCell *eventTableViewCell; +} + +@property (nonatomic, retain) NSMutableArray *eventsArray; +@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; + +@property (nonatomic, retain) CLLocationManager *locationManager; +@property (nonatomic, retain) UIBarButtonItem *addButton; + +@property (nonatomic, assign) IBOutlet EventTableViewCell *eventTableViewCell; + +- (void)addEvent; +- (IBAction)editTags:(UIButton *)button; +- (void)updateRowTags; + +@end diff --git a/TaggedLocations/Classes/RootViewController.m b/TaggedLocations/Classes/RootViewController.m new file mode 100644 index 0000000..baab659 --- /dev/null +++ b/TaggedLocations/Classes/RootViewController.m @@ -0,0 +1,416 @@ + +/* + File: RootViewController.m + Abstract: The table view controller responsible for displaying the list of events, supporting additional functionality: + * Addition of new new events; + * Deletion of existing events using UITableView's tableView:commitEditingStyle:forRowAtIndexPath: method. + * Editing an event's name. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "RootViewController.h" +#import "TaggedLocationsAppDelegate.h" +#import "Event.h" +#import "Tag.h" + +#import "EventTableViewCell.h" +#import "TagSelectionController.h" + + +@implementation RootViewController + + +@synthesize eventsArray, managedObjectContext, addButton, locationManager, eventTableViewCell; + + +#pragma mark - +#pragma mark View lifecycle + +- (void)viewDidLoad { + + [super viewDidLoad]; + + // Set the title. + self.title = @"Locations"; + + self.tableView.rowHeight = 77; + + + // Configure the add and edit buttons. + self.navigationItem.leftBarButtonItem = self.editButtonItem; + + UIBarButtonItem *aButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addEvent)]; + self.addButton = aButton; + [aButton release]; + + addButton.enabled = NO; + self.navigationItem.rightBarButtonItem = addButton; + + // Start the location manager. + [[self locationManager] startUpdatingLocation]; + + /* + Fetch existing events. + Create a fetch request; find the Event entity and assign it to the request; add a sort descriptor; then execute the fetch. + */ + NSFetchRequest *request = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext]; + [request setEntity:entity]; + + // Order the events by creation date, most recent first. + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; + [request setSortDescriptors:sortDescriptors]; + [sortDescriptor release]; + [sortDescriptors release]; + + // Execute the fetch -- create a mutable copy of the result. + NSError *error = nil; + NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; + if (mutableFetchResults == nil) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + // Set self's events array to the mutable array, then clean up. + [self setEventsArray:mutableFetchResults]; + [mutableFetchResults release]; + [request release]; +} + + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.tableView reloadData]; +} + + +- (void)viewDidUnload { + // Release any properties that are loaded in viewDidLoad or can be recreated lazily. + self.eventsArray = nil; + self.locationManager = nil; + self.addButton = nil; +} + + +#pragma mark - +#pragma mark Table view data source methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // Only one section. + return 1; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // As many rows as there are obects in the events array. + return [eventsArray count]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + // A date formatter for the creation date. + static NSDateFormatter *dateFormatter = nil; + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setTimeStyle:NSDateFormatterShortStyle]; + [dateFormatter setDateStyle:NSDateFormatterShortStyle]; + } + + // A number formatter for the latitude and longitude. + static NSNumberFormatter *numberFormatter = nil; + if (numberFormatter == nil) { + numberFormatter = [[NSNumberFormatter alloc] init]; + [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; + [numberFormatter setMaximumFractionDigits:3]; + } + + + static NSString *CellIdentifier = @"EventTableViewCell"; + + EventTableViewCell *cell = (EventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + [[NSBundle mainBundle] loadNibNamed:@"EventTableViewCell" owner:self options:nil]; + cell = eventTableViewCell; + self.eventTableViewCell = nil; + } + + // Get the event corresponding to the current index path and configure the table view cell. + Event *event = (Event *)[eventsArray objectAtIndex:indexPath.row]; + + cell.nameField.text = event.name; + + cell.creationDateLabel.text = [dateFormatter stringFromDate:[event creationDate]]; + + NSString *string = [NSString stringWithFormat:@"%@, %@", + [numberFormatter stringFromNumber:[event latitude]], + [numberFormatter stringFromNumber:[event longitude]]]; + cell.locationLabel.text = string; + + NSMutableArray *eventTagNames = [NSMutableArray array]; + for (Tag *tag in event.tags) { + [eventTagNames addObject:tag.name]; + } + + NSString *tagsString = @""; + if ([eventTagNames count] > 0) { + tagsString = [eventTagNames componentsJoinedByString:@", "]; + } + cell.tagsField.text = tagsString; + + cell.nameField.tag = indexPath.row; + cell.tagsButton.tag = indexPath.row; + return cell; +} + + +#pragma mark - +#pragma mark Editing + +/** + Handle deletion of an event. + */ +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + + if (editingStyle == UITableViewCellEditingStyleDelete) { + + // Ensure that if the user is editing a name field then the change is committed before deleting a row -- this ensures that changes are made to the correct event object. + [tableView endEditing:YES]; + + // Delete the managed object at the given index path. + NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row]; + [managedObjectContext deleteObject:eventToDelete]; + + // Update the array and table view. + [eventsArray removeObjectAtIndex:indexPath.row]; + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + + // Commit the change. + NSError *error; + if (![managedObjectContext save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + [self performSelector:@selector(updateRowTags) withObject:nil afterDelay:0.0]; + } +} + + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + + [super setEditing:editing animated:animated]; + self.navigationItem.rightBarButtonItem.enabled = !editing; +} + + +- (IBAction)editTags:(UIButton *)button { + + NSInteger row = button.tag; + + // Ensure that if the user is editing the name field then the change is committed before pushing the new view controller. + EventTableViewCell *cell = (EventTableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]]; + [cell.nameField endEditing:YES]; + + TagSelectionController *tagSelectionController = [[TagSelectionController alloc] initWithStyle:UITableViewStyleGrouped]; + tagSelectionController.event = [eventsArray objectAtIndex:row]; + [self.navigationController pushViewController:tagSelectionController animated:YES]; + [tagSelectionController release]; +} + + +- (void)updateRowTags { + NSArray *visibleCells = [self.tableView visibleCells]; + for (EventTableViewCell *cell in visibleCells) { + NSInteger tag = [[self.tableView indexPathForCell:cell] row]; + cell.nameField.tag = tag; + cell.tagsButton.tag = tag; + } +} + + +#pragma mark - +#pragma mark Add an event + +/** + Add an event. + */ +- (void)addEvent { + + // If it's not possible to get a location, then return. + CLLocation *location = [locationManager location]; + if (!location) { + return; + } + + /* + Create a new instance of the Event entity. + */ + Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext]; + + // Configure the new event with information from the location. + CLLocationCoordinate2D coordinate = [location coordinate]; + [event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]]; + [event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]]; + + // Should be the location's timestamp, but this will be constant for simulator. + // [event setCreationDate:[location timestamp]]; + [event setCreationDate:[NSDate date]]; + + /* + Since this is a new event, and events are displayed with most recent events at the top of the list, add the new event to the beginning of the events array, then: + * Add a new row to the table view + * Scroll to make the row visible + * Start editing the name field + */ + [eventsArray insertObject:event atIndex:0]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; + + [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + + [self updateRowTags]; + + [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; + + [self setEditing:YES animated:YES]; + EventTableViewCell *cell = (EventTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; + [cell.nameField becomeFirstResponder]; + + /* + Don't save yet -- the name is not optional: + * The user should add a name before the event is saved. + * If the user doesn't add a name, it will be set to @"" when they press Done. + */ +} + + +#pragma mark - +#pragma mark Location manager + +/** + Return a location manager -- create one if necessary. + */ +- (CLLocationManager *)locationManager { + + if (locationManager != nil) { + return locationManager; + } + + locationManager = [[CLLocationManager alloc] init]; + [locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters]; + [locationManager setDelegate:self]; + + return locationManager; +} + + +/** + Conditionally enable the Add button: + If the location manager is generating updates, then enable the button; + If the location manager is failing, then disable the button. + */ +- (void)locationManager:(CLLocationManager *)manager + didUpdateToLocation:(CLLocation *)newLocation + fromLocation:(CLLocation *)oldLocation { + if (!self.editing) { + addButton.enabled = YES; + } +} + +- (void)locationManager:(CLLocationManager *)manager + didFailWithError:(NSError *)error { + addButton.enabled = NO; +} + + +#pragma mark - +#pragma mark Editing text fields + +- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { + + Event *event = [eventsArray objectAtIndex:textField.tag]; + event.name = textField.text; + + // Commit the change. + NSError *error; + if (![managedObjectContext save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + return YES; +} + + +- (void)textFieldDidEndEditing:(UITextField *)textField { + // Ensure that a text field for a row for a newly-inserted object is disabled when the user finishes editing. + textField.enabled = self.editing; +} + + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + return YES; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [managedObjectContext release]; + [eventsArray release]; + [locationManager release]; + [addButton release]; + [super dealloc]; +} + + +@end + diff --git a/TaggedLocations/Classes/Tag.h b/TaggedLocations/Classes/Tag.h new file mode 100644 index 0000000..10209c2 --- /dev/null +++ b/TaggedLocations/Classes/Tag.h @@ -0,0 +1,69 @@ + +/* + File: Tag.h + Abstract: A Core Data managed object class to represent a tag for events. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class Event; + +@interface Tag : NSManagedObject +{ +} + +@property (nonatomic, retain) NSString * name; +@property (nonatomic, retain) NSSet* events; + +@end + + +@interface Tag (CoreDataGeneratedAccessors) +- (void)addEventsObject:(Event *)value; +- (void)removeEventsObject:(Event *)value; +- (void)addEvents:(NSSet *)value; +- (void)removeEvents:(NSSet *)value; + +@end + diff --git a/TaggedLocations/Classes/Tag.m b/TaggedLocations/Classes/Tag.m new file mode 100644 index 0000000..a9cf4ce --- /dev/null +++ b/TaggedLocations/Classes/Tag.m @@ -0,0 +1,59 @@ + +/* + File: Tag.m + Abstract: A Core Data managed object class to represent a tag for events. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +#import "Tag.h" +#import "Event.h" + +@implementation Tag + +@dynamic name; +@dynamic events; + +@end diff --git a/TaggedLocations/Classes/TagSelectionController.h b/TaggedLocations/Classes/TagSelectionController.h new file mode 100644 index 0000000..f000b39 --- /dev/null +++ b/TaggedLocations/Classes/TagSelectionController.h @@ -0,0 +1,73 @@ + +/* + File: TagSelectionController.h + Abstract: The table view controller responsible for displaying all available tags. + The controller is also given an Event object. Row for tags related to the event display a checkmark. If the user taps a row, the corresponding tag is added to or removed from the event's tags relationship as appropriate. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class Event, EditableTableViewCell; + +@interface TagSelectionController : UITableViewController { + Event *event; + NSMutableArray *tagsArray; + + UIView *headerView; + UILabel *headerLabel; + + EditableTableViewCell *editableTableViewCell; +} + +@property (nonatomic, retain) Event *event; +@property (nonatomic, retain) NSMutableArray *tagsArray; + +@property (nonatomic, retain) IBOutlet UIView *headerView; +@property (nonatomic, retain) IBOutlet UILabel *headerLabel; + +@property (nonatomic, assign) IBOutlet EditableTableViewCell *editableTableViewCell; + +- (void)insertTagAnimated:(BOOL)animated; + +@end diff --git a/TaggedLocations/Classes/TagSelectionController.m b/TaggedLocations/Classes/TagSelectionController.m new file mode 100644 index 0000000..3567366 --- /dev/null +++ b/TaggedLocations/Classes/TagSelectionController.m @@ -0,0 +1,387 @@ + +/* + File: TagSelectionController.m + Abstract: The table view controller responsible for displaying all available tags. + The controller is also given an Event object. Row for tags related to the event display a checkmark. If the user taps a row, the corresponding tag is added to or removed from the event's tags relationship as appropriate. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + + +#import "TagSelectionController.h" + +#import "Event.h" +#import "Tag.h" +#import "EditableTableViewCell.h" + + +@implementation TagSelectionController + +@synthesize event, headerView, headerLabel, tagsArray, editableTableViewCell; + + +- (void)viewDidLoad { + + // Configure the table view and controller. + [super viewDidLoad]; + self.tableView.allowsSelectionDuringEditing = YES; + + // Set up the navigation bar. + self.navigationItem.rightBarButtonItem = self.editButtonItem; + self.navigationItem.title = @"Tags"; + + // Set up the header view + [[NSBundle mainBundle] loadNibNamed:@"TagsHeaderView" owner:self options:nil]; + self.tableView.tableHeaderView = headerView; + + NSString *eventName = event.name; + if (![eventName length] > 0) { + eventName = @"Unnamed event"; + } + headerLabel.text = [NSString stringWithFormat:@"Tags for \"%@\" are indicated by a check mark.", eventName]; + + // Display all the tags, so fetch then using the event's context. + // Put the fetched tags into a mutable array. + NSManagedObjectContext *context = event.managedObjectContext; + + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tag" + inManagedObjectContext:context]; + [fetchRequest setEntity:entity]; + + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" + ascending:YES]; + NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; + [fetchRequest setSortDescriptors:sortDescriptors]; + + NSError *error; + NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; + if (fetchedObjects == nil) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + NSMutableArray *mutableArray = [fetchedObjects mutableCopy]; + self.tagsArray = mutableArray; + [mutableArray release]; + + [fetchRequest release]; + [sortDescriptor release]; + [sortDescriptors release]; +} + + +- (void)viewDidAppear:(BOOL)animated { + + [super viewDidAppear:animated]; + if ([tagsArray count] == 0) { + // There are no tags, and presumably the user wants to add one. + // Create and edit one straight away. + [self setEditing:YES animated:NO]; + [self insertTagAnimated:NO]; + } +} + + +#pragma mark - +#pragma mark Table view data source + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // Return the number of tags in the array, adding one if editing (for the Add Tag row). + NSUInteger count = [tagsArray count]; + if (self.editing) { + count++; + } + return count; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + + NSUInteger row = indexPath.row; + + if (row == [tagsArray count]) { + + // This is the insertion cell. + static NSString *InsertionCellIdentifier = @"InsertionCell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:InsertionCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:InsertionCellIdentifier] autorelease]; + cell.textLabel.text = @"Add Tag"; + cell.accessoryType = UITableViewCellAccessoryNone; + } + return cell; + } + + + static NSString *TagCellIdentifier = @"EditableTableViewCell"; + + EditableTableViewCell *cell = (EditableTableViewCell *)[tableView dequeueReusableCellWithIdentifier:TagCellIdentifier]; + + if (cell == nil) { + [[NSBundle mainBundle] loadNibNamed:@"EditableTableViewCell" owner:self options:nil]; + cell = editableTableViewCell; + self.editableTableViewCell = nil; + } + + // Set the tag on the text field to the row number so it can be identified later if edited. + cell.textField.tag = row; + + Tag *tag = [tagsArray objectAtIndex:row]; + + // If the tag at this row in the tags array is related to the event, display a checkmark, otherwise remove any checkmark that might have been present. + cell.textField.text = tag.name; + if ([event.tags containsObject:tag]) { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + else { + cell.accessoryType = UITableViewCellAccessoryNone; + } + + return cell; +} + + + +#pragma mark - +#pragma mark Editing rows + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + + // The add row gets an insertion marker, the others a delete marker. + if (indexPath.row == [tagsArray count]) { + return UITableViewCellEditingStyleInsert; + } + return UITableViewCellEditingStyleDelete; +} + + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + + [super setEditing:editing animated:animated]; + + // Don't show the Back button while editing. + [self.navigationItem setHidesBackButton:editing animated:YES]; + + + [self.tableView beginUpdates]; + + NSUInteger count = [tagsArray count]; + + NSArray *tagInsertIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:0]]; + + // Add or remove the Add row as appropriate. + UITableViewRowAnimation animationStyle = UITableViewRowAnimationNone; + if (editing) { + if (animated) { + animationStyle = UITableViewRowAnimationFade; + } + [self.tableView insertRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:animationStyle]; + } + else { + [self.tableView deleteRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:UITableViewRowAnimationFade]; + } + + [self.tableView endUpdates]; + + // If editing is finished, save the managed object context. + + if (!editing) { + NSManagedObjectContext *context = event.managedObjectContext; + NSError *error = nil; + if (![context save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + } +} + + +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + + NSManagedObjectContext *context = event.managedObjectContext; + + if (editingStyle == UITableViewCellEditingStyleDelete) { + + // Delete the tag. + + // Ensure the cell is not being edited, otherwise the callback in textFieldShouldEndEditing: may look for a non-existent row. + EditableTableViewCell *cell = (EditableTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; + [cell.textField resignFirstResponder]; + + + // Find the tag to delete. + Tag *tag = [tagsArray objectAtIndex:indexPath.row]; + + // Delete the tag from the context. Because the relationship between Tag and Event is defined in both directions, and the delete rule is nullify, Core Data automatically removes the tag from any relationships in which it is present. + [context deleteObject:tag]; + + // Remove the tag from the tags array and the corresponding row from the table view. + [tagsArray removeObject:tag]; + + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + + // Save the change. + NSError *error = nil; + if (![context save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + } + + if (editingStyle == UITableViewCellEditingStyleInsert) { + [self insertTagAnimated:YES]; + // Don't save yet as the user must set a name. + } +} + + +- (void)insertTagAnimated:(BOOL)animated { + + // Create a new instance of Tag, insert it into the tags array, and add a corresponding new row to the table view. + + Tag *tag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:[event managedObjectContext]]; + + // Presumably the tag was added for the current event, so relate it to the event. + [event addTagsObject:tag]; + + // Add the new tag to the tags array and to the table view. + [tagsArray addObject:tag]; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[tagsArray count]-1 inSection:0]; + UITableViewRowAnimation animationStyle = UITableViewRowAnimationNone; + if (animated) { + animationStyle = UITableViewRowAnimationFade; + } + [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:animationStyle]; + + // Start editing the tag's name. + EditableTableViewCell *cell = (EditableTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; + [cell.textField becomeFirstResponder]; +} + + +#pragma mark - +#pragma mark Row selection + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // Disable selection of the Add row. + if (indexPath.row == [tagsArray count]) { + return nil; + } + return indexPath; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + + /* + Find the tag at the row index in the tags array, then + * If the event currently has this tag, remove the tag; + * If the event doesn't have this tag, add the tag. + + (The Add row is not selectable.) + */ + Tag *tag = [tagsArray objectAtIndex:indexPath.row]; + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + + if ([event.tags containsObject:tag]) { + cell.accessoryType = UITableViewCellAccessoryNone; + [event removeTagsObject:tag]; + } + else { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + [event addTagsObject:tag]; + } + + // Save the change. + NSError *error = nil; + if (![event.managedObjectContext save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + + +#pragma mark - +#pragma mark Editing text fields + +- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { + + Tag *tag = [tagsArray objectAtIndex:textField.tag]; + tag.name = textField.text; + + return YES; +} + + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + return YES; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [headerView release]; + [headerLabel release]; + [event release]; + [tagsArray release]; + [super dealloc]; +} + + +@end + diff --git a/TaggedLocations/Classes/TaggedLocationsAppDelegate.h b/TaggedLocations/Classes/TaggedLocationsAppDelegate.h new file mode 100644 index 0000000..6e892c8 --- /dev/null +++ b/TaggedLocations/Classes/TaggedLocationsAppDelegate.h @@ -0,0 +1,70 @@ + +/* + File: TaggedLocationsAppDelegate.h + Abstract: Application delegate to set up the Core Data stack and configure the view and navigation controllers. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TaggedLocationsAppDelegate : NSObject { + + UIWindow *window; + UINavigationController *navigationController; + + NSPersistentStoreCoordinator *persistentStoreCoordinator; + NSManagedObjectModel *managedObjectModel; + NSManagedObjectContext *managedObjectContext; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +- (IBAction)saveAction:sender; + +@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; +@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; +@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; + +@property (nonatomic, readonly) NSString *applicationDocumentsDirectory; + +@end diff --git a/TaggedLocations/Classes/TaggedLocationsAppDelegate.m b/TaggedLocations/Classes/TaggedLocationsAppDelegate.m new file mode 100644 index 0000000..2270cde --- /dev/null +++ b/TaggedLocations/Classes/TaggedLocationsAppDelegate.m @@ -0,0 +1,209 @@ + +/* + File: TaggedLocationsAppDelegate.m + Abstract: Application delegate to set up the Core Data stack and configure the view and navigation controllers. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TaggedLocationsAppDelegate.h" +#import "RootViewController.h" + + +@implementation TaggedLocationsAppDelegate + +@synthesize window; +@synthesize navigationController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Configure and show the window. + + RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; + + NSManagedObjectContext *context = [self managedObjectContext]; + if (!context) { + // Handle the error. + NSLog(@"Unresolved error (no context)"); + exit(-1); // Fail + } + rootViewController.managedObjectContext = context; + + UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + self.navigationController = aNavigationController; + + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; + + [rootViewController release]; + [aNavigationController release]; +} + +/** + applicationWillTerminate: saves changes in the application's managed object context before the application terminates. + */ +- (void)applicationWillTerminate:(UIApplication *)application { + + NSError *error; + if (managedObjectContext != nil) { + if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + } +} + + +#pragma mark - +#pragma mark Saving + +/** + Performs the save action for the application, which is to send the save: + message to the application's managed object context. + */ +- (IBAction)saveAction:(id)sender { + + NSError *error; + if (![[self managedObjectContext] save:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } +} + + +#pragma mark - +#pragma mark Core Data stack + +/** + Returns the managed object context for the application. + If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. + */ +- (NSManagedObjectContext *) managedObjectContext { + + if (managedObjectContext != nil) { + return managedObjectContext; + } + + NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; + if (coordinator != nil) { + managedObjectContext = [[NSManagedObjectContext alloc] init]; + [managedObjectContext setPersistentStoreCoordinator: coordinator]; + } + return managedObjectContext; +} + + +/** + Returns the managed object model for the application. + If the model doesn't already exist, it is created by merging all of the models found in the application bundle. + */ +- (NSManagedObjectModel *)managedObjectModel { + + if (managedObjectModel != nil) { + return managedObjectModel; + } + managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; + return managedObjectModel; +} + + +/** + Returns the persistent store coordinator for the application. + If the coordinator doesn't already exist, it is created and the application's store added to it. + */ +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { + + if (persistentStoreCoordinator != nil) { + return persistentStoreCoordinator; + } + + NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Locations.sqlite"]]; + + NSError *error; + persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; + if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) { + // Handle the error. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + exit(-1); // Fail + } + + return persistentStoreCoordinator; +} + + +#pragma mark - +#pragma mark Application's documents directory + +/** + Returns the path to the application's documents directory. + */ +- (NSString *)applicationDocumentsDirectory { + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; + return basePath; +} + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + + [managedObjectContext release]; + [managedObjectModel release]; + [persistentStoreCoordinator release]; + + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/TaggedLocations/Info.plist b/TaggedLocations/Info.plist new file mode 100644 index 0000000..55d4ff0 --- /dev/null +++ b/TaggedLocations/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.3 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TaggedLocations/ReadMe.txt b/TaggedLocations/ReadMe.txt new file mode 100644 index 0000000..c4548f4 --- /dev/null +++ b/TaggedLocations/ReadMe.txt @@ -0,0 +1,91 @@ +### Locations ### + +=========================================================================== +DESCRIPTION: + +This sample illustrates how to manipulate attributes and relationships in an iPhone application. + +The application extends the the completed project from the Core Data Tutorial for iPhone OS. The first screen displays a table view of events, which encapsulate a time stamp, a geographical location expressed in latitude and longitude, and a name for the event. The user can add, remove, and edit events using the first screen. + +Events have a to-many relationship to tags (which have an inverse to-many relationship to events). Tags have a name which describes a feature of an event. Tags are displayed in a second table view; when a tag is related to the selected event, a check mark is displayed in the corresponding row. + + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST: + +View Controllers +---------------- +RootViewController.{h,m} +The table view controller responsible for displaying the list of events, supporting additional functionality: + * Addition of new new events + * Deletion of existing events using UITableView's tableView:commitEditingStyle:forRowAtIndexPath: method + * Editing an event's name + +TagSelectionController.{h,m} +The table view controller responsible for displaying and editing tags. +The rows show a check mark if the selected event is related to the corresponding tag. + +Model +----- +TaggedLocations.xcdatamodel +The Core Data managed object model for the application. + +Event.{h,m} +A Core Data managed object class to represent an event containing geographical coordinates and a time stamp. + +Tag.{h,m} +A Core Data managed object class to represent a tag. + +Table View Cells +---------------- +EventTableViewCell.{h,m} +EventTableViewCell.xib +Table view cell to display information about an event. +The File's Owner is the RootViewController table view controller which acts as: +* The name text field's delegate to respond to editing operations +* The target of the tag button to initiate tag editing + + +EditableTableViewCell.{h,m} +EditableTableViewCell.xib +Table view cell to present an editable text field. +The File's Owner is the TagSelectionController table view controller which acts as the text field's delegate to respond to editing operations. + + +Application configuration +------------------------- +LocationsAppDelegate.{h,m} +Configures the Core Data stack and the first view controller. + +MainWindow.xib +Loaded automatically by the application. Creates the application's delegate and window. + + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.3 +- Added CFBundleIconFiles in Info.plist. + +Version 1.2 +- Upgraded project to build with the iOS 4.0 SDK. + +Version 1.1 +- Added identifier to table view cell in EditableTableViewCell.xib. + +Version 1.0 +- First version. + +=========================================================================== +Copyright (C) 2009-2010 Apple Inc. All rights reserved. diff --git a/TaggedLocations/TaggedLocations.xcdatamodel/elements b/TaggedLocations/TaggedLocations.xcdatamodel/elements new file mode 100644 index 0000000..a91e66b Binary files /dev/null and b/TaggedLocations/TaggedLocations.xcdatamodel/elements differ diff --git a/TaggedLocations/TaggedLocations.xcdatamodel/layout b/TaggedLocations/TaggedLocations.xcdatamodel/layout new file mode 100644 index 0000000..e01864b Binary files /dev/null and b/TaggedLocations/TaggedLocations.xcdatamodel/layout differ diff --git a/TaggedLocations/TaggedLocations.xcodeproj/project.pbxproj b/TaggedLocations/TaggedLocations.xcodeproj/project.pbxproj new file mode 100755 index 0000000..955ee79 --- /dev/null +++ b/TaggedLocations/TaggedLocations.xcodeproj/project.pbxproj @@ -0,0 +1,401 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1811EF0C11D0292E0068DA4C /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF0511D0292E0068DA4C /* Icon-72.png */; }; + 1811EF0D11D0292E0068DA4C /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF0611D0292E0068DA4C /* Icon-Small-50.png */; }; + 1811EF0E11D0292E0068DA4C /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF0711D0292E0068DA4C /* Icon-Small.png */; }; + 1811EF0F11D0292E0068DA4C /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF0811D0292E0068DA4C /* Icon-Small@2x.png */; }; + 1811EF1011D0292E0068DA4C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF0911D0292E0068DA4C /* Icon.png */; }; + 1811EF1111D0292E0068DA4C /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1811EF0A11D0292E0068DA4C /* Icon@2x.png */; }; + 1825951211D11AE8000B79F7 /* EditableTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1825950C11D11AE8000B79F7 /* EditableTableViewCell.xib */; }; + 1825951311D11AE8000B79F7 /* EventTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1825950E11D11AE8000B79F7 /* EventTableViewCell.xib */; }; + 1825951411D11AE8000B79F7 /* TagsHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1825951011D11AE8000B79F7 /* TagsHeaderView.xib */; }; + 1825964811D13136000B79F7 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1825964611D13136000B79F7 /* MainWindow.xib */; }; + 18AD6B8711D56DAA005232E4 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18AD6B8611D56DAA005232E4 /* iTunesArtwork */; }; + 1D3623260D0F684500981E51 /* TaggedLocationsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* TaggedLocationsAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 283558A70F688B81002A3A38 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 283558A60F688B81002A3A38 /* ReadMe.txt */; }; + 283659D00FD8513400B8A769 /* Tag.m in Sources */ = {isa = PBXBuildFile; fileRef = 283659CF0FD8513400B8A769 /* Tag.m */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28A9E88C0F43C7410016529B /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A9E88B0F43C7410016529B /* CoreData.framework */; }; + 28A9E8BA0F43C7B50016529B /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A9E8B90F43C7B50016529B /* CoreLocation.framework */; }; + 28A9E9330F43CA900016529B /* TaggedLocations.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 28A9E9320F43CA900016529B /* TaggedLocations.xcdatamodel */; }; + 28B124790FCDB70900FA3CBF /* EditableTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 28B124760FCDB70900FA3CBF /* EditableTableViewCell.m */; }; + 28B1247A0FCDB70900FA3CBF /* EventTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 28B124780FCDB70900FA3CBF /* EventTableViewCell.m */; }; + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; + 28C95C640F4FB4660037F30F /* Event.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C95C630F4FB4660037F30F /* Event.m */; }; + 28FB88860FCCA80500EBA711 /* TagSelectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28FB88850FCCA80500EBA711 /* TagSelectionController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1811EF0511D0292E0068DA4C /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 1811EF0611D0292E0068DA4C /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 1811EF0711D0292E0068DA4C /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 1811EF0811D0292E0068DA4C /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 1811EF0911D0292E0068DA4C /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 1811EF0A11D0292E0068DA4C /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 1825950D11D11AE8000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/EditableTableViewCell.xib; sourceTree = ""; }; + 1825950F11D11AE8000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/EventTableViewCell.xib; sourceTree = ""; }; + 1825951111D11AE8000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TagsHeaderView.xib; sourceTree = ""; }; + 1825964711D13136000B79F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 18AD6B8611D56DAA005232E4 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* TaggedLocationsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedLocationsAppDelegate.h; path = Classes/TaggedLocationsAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* TaggedLocationsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TaggedLocationsAppDelegate.m; path = Classes/TaggedLocationsAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* TaggedLocations.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TaggedLocations.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 283558A60F688B81002A3A38 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 283659CE0FD8513400B8A769 /* Tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tag.h; path = Classes/Tag.h; sourceTree = ""; }; + 283659CF0FD8513400B8A769 /* Tag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Tag.m; path = Classes/Tag.m; sourceTree = ""; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* TaggedLocations_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaggedLocations_Prefix.pch; sourceTree = ""; }; + 28A9E88B0F43C7410016529B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 28A9E8B90F43C7B50016529B /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 28A9E9320F43CA900016529B /* TaggedLocations.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = TaggedLocations.xcdatamodel; sourceTree = ""; }; + 28B124750FCDB70800FA3CBF /* EditableTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditableTableViewCell.h; path = Classes/EditableTableViewCell.h; sourceTree = ""; }; + 28B124760FCDB70900FA3CBF /* EditableTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditableTableViewCell.m; path = Classes/EditableTableViewCell.m; sourceTree = ""; }; + 28B124770FCDB70900FA3CBF /* EventTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EventTableViewCell.h; path = Classes/EventTableViewCell.h; sourceTree = ""; }; + 28B124780FCDB70900FA3CBF /* EventTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EventTableViewCell.m; path = Classes/EventTableViewCell.m; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; + 28C95C620F4FB4660037F30F /* Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Event.h; path = Classes/Event.h; sourceTree = ""; }; + 28C95C630F4FB4660037F30F /* Event.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Event.m; path = Classes/Event.m; sourceTree = ""; }; + 28FB88840FCCA80500EBA711 /* TagSelectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagSelectionController.h; sourceTree = ""; }; + 28FB88850FCCA80500EBA711 /* TagSelectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TagSelectionController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + 28A9E88C0F43C7410016529B /* CoreData.framework in Frameworks */, + 28A9E8BA0F43C7B50016529B /* CoreLocation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* View Controllers */ = { + isa = PBXGroup; + children = ( + 28C286DF0D94DF7D0034E888 /* RootViewController.h */, + 28C286E00D94DF7D0034E888 /* RootViewController.m */, + 28FB88840FCCA80500EBA711 /* TagSelectionController.h */, + 28FB88850FCCA80500EBA711 /* TagSelectionController.m */, + ); + name = "View Controllers"; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* TaggedLocations.app */, + ); + name = Products; + sourceTree = ""; + }; + 28B123130FCD2F5700FA3CBF /* Table View Cells */ = { + isa = PBXGroup; + children = ( + 28B124770FCDB70900FA3CBF /* EventTableViewCell.h */, + 28B124780FCDB70900FA3CBF /* EventTableViewCell.m */, + 28B124750FCDB70800FA3CBF /* EditableTableViewCell.h */, + 28B124760FCDB70900FA3CBF /* EditableTableViewCell.m */, + ); + name = "Table View Cells"; + sourceTree = ""; + }; + 28FB887C0FCCA69C00EBA711 /* Application */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* TaggedLocationsAppDelegate.h */, + 1D3623250D0F684500981E51 /* TaggedLocationsAppDelegate.m */, + ); + name = Application; + sourceTree = ""; + }; + 28FB887D0FCCA6C700EBA711 /* Model */ = { + isa = PBXGroup; + children = ( + 28C95C620F4FB4660037F30F /* Event.h */, + 28C95C630F4FB4660037F30F /* Event.m */, + 283659CE0FD8513400B8A769 /* Tag.h */, + 283659CF0FD8513400B8A769 /* Tag.m */, + 28A9E9320F43CA900016529B /* TaggedLocations.xcdatamodel */, + ); + name = Model; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 283558A60F688B81002A3A38 /* ReadMe.txt */, + 28FB887D0FCCA6C700EBA711 /* Model */, + 080E96DDFE201D6D7F000001 /* View Controllers */, + 28B123130FCD2F5700FA3CBF /* Table View Cells */, + 28FB887C0FCCA69C00EBA711 /* Application */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* TaggedLocations_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18AD6B8611D56DAA005232E4 /* iTunesArtwork */, + 1825964611D13136000B79F7 /* MainWindow.xib */, + 1825950C11D11AE8000B79F7 /* EditableTableViewCell.xib */, + 1825950E11D11AE8000B79F7 /* EventTableViewCell.xib */, + 1825951011D11AE8000B79F7 /* TagsHeaderView.xib */, + 1811EF0511D0292E0068DA4C /* Icon-72.png */, + 1811EF0611D0292E0068DA4C /* Icon-Small-50.png */, + 1811EF0711D0292E0068DA4C /* Icon-Small.png */, + 1811EF0811D0292E0068DA4C /* Icon-Small@2x.png */, + 1811EF0911D0292E0068DA4C /* Icon.png */, + 1811EF0A11D0292E0068DA4C /* Icon@2x.png */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 28A9E8B90F43C7B50016529B /* CoreLocation.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + 28A9E88B0F43C7410016529B /* CoreData.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* TaggedLocations */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TaggedLocations" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TaggedLocations; + productName = Locations; + productReference = 1D6058910D05DD3D006BFB54 /* TaggedLocations.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TaggedLocations" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* TaggedLocations */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 283558A70F688B81002A3A38 /* ReadMe.txt in Resources */, + 1811EF0C11D0292E0068DA4C /* Icon-72.png in Resources */, + 1811EF0D11D0292E0068DA4C /* Icon-Small-50.png in Resources */, + 1811EF0E11D0292E0068DA4C /* Icon-Small.png in Resources */, + 1811EF0F11D0292E0068DA4C /* Icon-Small@2x.png in Resources */, + 1811EF1011D0292E0068DA4C /* Icon.png in Resources */, + 1811EF1111D0292E0068DA4C /* Icon@2x.png in Resources */, + 1825951211D11AE8000B79F7 /* EditableTableViewCell.xib in Resources */, + 1825951311D11AE8000B79F7 /* EventTableViewCell.xib in Resources */, + 1825951411D11AE8000B79F7 /* TagsHeaderView.xib in Resources */, + 1825964811D13136000B79F7 /* MainWindow.xib in Resources */, + 18AD6B8711D56DAA005232E4 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* TaggedLocationsAppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, + 28A9E9330F43CA900016529B /* TaggedLocations.xcdatamodel in Sources */, + 28C95C640F4FB4660037F30F /* Event.m in Sources */, + 28FB88860FCCA80500EBA711 /* TagSelectionController.m in Sources */, + 28B124790FCDB70900FA3CBF /* EditableTableViewCell.m in Sources */, + 28B1247A0FCDB70900FA3CBF /* EventTableViewCell.m in Sources */, + 283659D00FD8513400B8A769 /* Tag.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 1825950C11D11AE8000B79F7 /* EditableTableViewCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 1825950D11D11AE8000B79F7 /* en */, + ); + name = EditableTableViewCell.xib; + sourceTree = ""; + }; + 1825950E11D11AE8000B79F7 /* EventTableViewCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 1825950F11D11AE8000B79F7 /* en */, + ); + name = EventTableViewCell.xib; + sourceTree = ""; + }; + 1825951011D11AE8000B79F7 /* TagsHeaderView.xib */ = { + isa = PBXVariantGroup; + children = ( + 1825951111D11AE8000B79F7 /* en */, + ); + name = TagsHeaderView.xib; + sourceTree = ""; + }; + 1825964611D13136000B79F7 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 1825964711D13136000B79F7 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = TaggedLocations_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = TaggedLocations; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = TaggedLocations_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = TaggedLocations; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TaggedLocations" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TaggedLocations" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TaggedLocations/TaggedLocations_Prefix.pch b/TaggedLocations/TaggedLocations_Prefix.pch new file mode 100644 index 0000000..8066b1d --- /dev/null +++ b/TaggedLocations/TaggedLocations_Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the 'TaggedLocations' target in the 'TaggedLocations' project +// + +#import + +#ifndef __IPHONE_3_0 +// #warning "Projects that use Core Data only build using iPhone SDK 3.0 and later" +#endif + +#ifdef __OBJC__ +#import +#import +#import +#endif diff --git a/TaggedLocations/en.lproj/EditableTableViewCell.xib b/TaggedLocations/en.lproj/EditableTableViewCell.xib new file mode 100644 index 0000000..c47b914 --- /dev/null +++ b/TaggedLocations/en.lproj/EditableTableViewCell.xib @@ -0,0 +1,476 @@ + + + + 768 + 10A403 + 732 + 1031 + 432.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 60 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 256 + + YES + + + 274 + {{11, 0}, {263, 43}} + + NO + NO + 0 + Editable text field + Tag name + + 3 + MAA + + 2 + + + + Helvetica-Bold + 17 + 16 + + YES + 17 + + 2 + 9 + + + + {320, 43} + + + 3 + MCAwAA + + NO + YES + 4 + YES + + + {320, 44} + + + 1 + MSAxIDEAA + + NO + 1 + + EditableTableViewCell + + + + + YES + + + editableTableViewCell + + + + 4 + + + + textField + + + + 5 + + + + delegate + + + + 6 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + 3 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.IBPluginDependency + + + YES + TagSelectionController + UIResponder + EditableTableViewCell + {{111, 534}, {320, 44}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 6 + + + + YES + + EditableTableViewCell + UITableViewCell + + textField + UITextField + + + IBProjectSource + Classes/EditableTableViewCell.h + + + + TagSelectionController + UITableViewController + + YES + + YES + editableTableViewCell + headerLabel + headerView + + + YES + EditableTableViewCell + UILabel + UIView + + + + IBProjectSource + Classes/TagSelectionController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableViewCell + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITableViewCell.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UITextField + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + TaggedLocations.xcodeproj + 3 + 3.1 + + diff --git a/TaggedLocations/en.lproj/EventTableViewCell.xib b/TaggedLocations/en.lproj/EventTableViewCell.xib new file mode 100644 index 0000000..8d5f147 --- /dev/null +++ b/TaggedLocations/en.lproj/EventTableViewCell.xib @@ -0,0 +1,655 @@ + + + + 768 + 10A380 + 731 + 1025.2 + 427.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 256 + + YES + + + 292 + {{14, 29}, {149, 21}} + + + 3 + MQA + + YES + NO + Label + + Helvetica + 13 + 16 + + + 3 + MC41AA + + 2 + + + + 1 + 10 + + + + 289 + {{171, 29}, {143, 21}} + + + YES + NO + Label + + + 3 + MC41AA + + + + 1 + 10 + 2 + + + + 290 + {{14, 3}, {300, 30}} + + + NO + NO + 0 + + Event name + + 3 + MAA + + + + Helvetica-Bold + 18 + 16 + + YES + 17 + + 2 + 9 + + + + + 292 + {{14, 50}, {300, 21}} + + + NO + NO + 0 + Text Field + + 3 + MAA + + + YES + 17 + + + + + -2147483356 + {{14, 52}, {300, 19}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 15 + 16 + + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MC41AA + + + + {328, 76} + + + 3 + MCAwAA + + NO + YES + 4 + YES + + + {328, 77} + + + 1 + MSAxIDEAA + + NO + 1 + 0 + + + + + + YES + + + creationDateLabel + + + + 10 + + + + locationLabel + + + + 11 + + + + eventTableViewCell + + + + 13 + + + + delegate + + + + 15 + + + + nameField + + + + 16 + + + + tagsButton + + + + 29 + + + + tagsField + + + + 33 + + + + editTags: + + + 7 + + 34 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + + + + 3 + + + + + 5 + + + + + 14 + + + + + 32 + + + + + 28 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 14.IBPluginDependency + 2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 28.IBPluginDependency + 3.IBPluginDependency + 32.IBPluginDependency + 5.IBPluginDependency + + + YES + RootViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EventTableViewCell + {{147, 719}, {328, 77}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 34 + + + + YES + + EventTableViewCell + UITableViewCell + + YES + + YES + creationDateLabel + locationLabel + nameField + tagsButton + tagsField + + + YES + UILabel + UILabel + UITextField + UIButton + UITextField + + + + IBProjectSource + Classes/EventTableViewCell.h + + + + RootViewController + UITableViewController + + editTags: + UIButton + + + eventTableViewCell + EventTableViewCell + + + IBProjectSource + Classes/RootViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableViewCell + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITableViewCell.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UITextField + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + TaggedLocations.xcodeproj + 3 + 3.0 + + diff --git a/TaggedLocations/en.lproj/MainWindow.xib b/TaggedLocations/en.lproj/MainWindow.xib new file mode 100644 index 0000000..fd69255 --- /dev/null +++ b/TaggedLocations/en.lproj/MainWindow.xib @@ -0,0 +1,198 @@ + + + + 544 + 10A374 + 731 + 1025.1 + 426.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TaggedLocationsAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 15 + + + + YES + + TaggedLocationsAppDelegate + NSObject + + saveAction: + id + + + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + + + + IBUserSource + + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Locations.xcodeproj + 3 + 3.0 + + diff --git a/TaggedLocations/en.lproj/TagsHeaderView.xib b/TaggedLocations/en.lproj/TagsHeaderView.xib new file mode 100644 index 0000000..5e68252 --- /dev/null +++ b/TaggedLocations/en.lproj/TagsHeaderView.xib @@ -0,0 +1,465 @@ + + + + 768 + 10A380 + 731 + 1025.2 + 427.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 292 + {{10, 0}, {300, 64}} + + + 3 + MCAwAA + + NO + YES + NO + TGFiZWwKCg + + 1 + MCAwIDAAA + + + 1 + 10 + 2 + 1 + + + {320, 64} + + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA + + + + + + + groupTableViewBackgroundColor + + NO + + + + + YES + + + headerView + + + + 4 + + + + headerLabel + + + + 5 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + 3 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.IBPluginDependency + + + YES + TagSelectionController + UIResponder + {{923, 770}, {320, 64}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 5 + + + + YES + + EditableTableViewCell + UITableViewCell + + textField + UITextField + + + IBProjectSource + Classes/EditableTableViewCell.h + + + + TagSelectionController + UITableViewController + + YES + + YES + editableTableViewCell + headerLabel + headerView + + + YES + EditableTableViewCell + UILabel + UIView + + + + IBProjectSource + Classes/TagSelectionController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableViewCell + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITableViewCell.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UITextField + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + TaggedLocations.xcodeproj + 3 + 3.0 + + diff --git a/TaggedLocations/images/Icon-72.png b/TaggedLocations/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TaggedLocations/images/Icon-72.png differ diff --git a/TaggedLocations/images/Icon-Small-50.png b/TaggedLocations/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TaggedLocations/images/Icon-Small-50.png differ diff --git a/TaggedLocations/images/Icon-Small.png b/TaggedLocations/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TaggedLocations/images/Icon-Small.png differ diff --git a/TaggedLocations/images/Icon-Small@2x.png b/TaggedLocations/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TaggedLocations/images/Icon-Small@2x.png differ diff --git a/TaggedLocations/images/Icon.png b/TaggedLocations/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TaggedLocations/images/Icon.png differ diff --git a/TaggedLocations/images/Icon@2x.png b/TaggedLocations/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TaggedLocations/images/Icon@2x.png differ diff --git a/TaggedLocations/images/iTunesArtwork b/TaggedLocations/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TaggedLocations/images/iTunesArtwork differ diff --git a/TaggedLocations/main.m b/TaggedLocations/main.m new file mode 100644 index 0000000..70c89c8 --- /dev/null +++ b/TaggedLocations/main.m @@ -0,0 +1,55 @@ + +/* + File: main.m + Abstract: Default main.m + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/Teslameter.zip b/Teslameter.zip new file mode 100644 index 0000000..1a0c548 Binary files /dev/null and b/Teslameter.zip differ diff --git a/Teslameter/Classes/AppDelegate.h b/Teslameter/Classes/AppDelegate.h new file mode 100755 index 0000000..8b59c1f --- /dev/null +++ b/Teslameter/Classes/AppDelegate.h @@ -0,0 +1,60 @@ +/* + File: AppDelegate.h +Abstract: The application delegate, adds the main view to the window and displays the window. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class TeslameterViewController; + +@interface AppDelegate : NSObject { + UIWindow *window; + TeslameterViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet TeslameterViewController *viewController; + +@end diff --git a/Teslameter/Classes/AppDelegate.m b/Teslameter/Classes/AppDelegate.m new file mode 100755 index 0000000..d1f7415 --- /dev/null +++ b/Teslameter/Classes/AppDelegate.m @@ -0,0 +1,69 @@ +/* + File: AppDelegate.m +Abstract: The application delegate, adds the main view to the window and displays the window. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "TeslameterViewController.h" + +@implementation AppDelegate + +@synthesize window; +@synthesize viewController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/Teslameter/Classes/GraphView.h b/Teslameter/Classes/GraphView.h new file mode 100755 index 0000000..9fb1a20 --- /dev/null +++ b/Teslameter/Classes/GraphView.h @@ -0,0 +1,58 @@ +/* + File: GraphView.h +Abstract: A custom view for plotting history of x, y, and z magnetic values. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "TeslameterViewController.h" + +@interface GraphView : UIView { + NSUInteger nextIndex; + CLHeadingComponentValue history[150][3]; +} + +- (void)updateHistoryWithX:(CLHeadingComponentValue)x y:(CLHeadingComponentValue)y z:(CLHeadingComponentValue)z; + +@end + diff --git a/Teslameter/Classes/GraphView.m b/Teslameter/Classes/GraphView.m new file mode 100755 index 0000000..6dd3b4b --- /dev/null +++ b/Teslameter/Classes/GraphView.m @@ -0,0 +1,139 @@ +/* + File: GraphView.m +Abstract: A custom view for plotting history of x, y, and z magnetic values. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "GraphView.h" + +@implementation GraphView + +- (void)updateHistoryWithX:(CLHeadingComponentValue)x y:(CLHeadingComponentValue)y z:(CLHeadingComponentValue)z { + + // Add to history. + history[nextIndex][0] = x; + history[nextIndex][1] = y; + history[nextIndex][2] = z; + + // Advance the index counter. + nextIndex = (nextIndex + 1) % 150; + + // Mark itself as needing to be redrawn. + [self setNeedsDisplay]; +} + +- (void)drawGraphInContext:(CGContextRef)context withBounds:(CGRect)bounds { + CGFloat value, temp; + + // Save any previous graphics state settings before setting the color and line width for the current draw. + CGContextSaveGState(context); + CGContextSetLineWidth(context, 1.0); + + // Draw the intermediate lines + CGContextSetGrayStrokeColor(context, 0.6, 1.0); + CGContextBeginPath(context); + for (value = -5 + 1.0; value <= 5 - 1.0; value += 1.0) { + + if (value == 0.0) { + continue; + } + temp = 0.5 + roundf(bounds.origin.y + bounds.size.height / 2 + value / (2 * 5) * bounds.size.height); + CGContextMoveToPoint(context, bounds.origin.x, temp); + CGContextAddLineToPoint(context, bounds.origin.x + bounds.size.width, temp); + } + CGContextStrokePath(context); + + // Draw the center line + CGContextSetGrayStrokeColor(context, 0.25, 1.0); + CGContextBeginPath(context); + temp = 0.5 + roundf(bounds.origin.y + bounds.size.height / 2); + CGContextMoveToPoint(context, bounds.origin.x, temp); + CGContextAddLineToPoint(context, bounds.origin.x + bounds.size.width, temp); + CGContextStrokePath(context); + + // Restore previous graphics state. + CGContextRestoreGState(context); +} + +- (void)drawHistory:(NSUInteger)axis fromIndex:(NSUInteger)index inContext:(CGContextRef)context bounds:(CGRect)bounds { + CGFloat value; + + CGContextBeginPath(context); + for (NSUInteger counter = 0; counter < 150; ++counter) { + // UIView referential has the Y axis going down, so we need to draw upside-down. + value = history[(index + counter) % 150][axis] / -128; + if (counter > 0) { + CGContextAddLineToPoint(context, bounds.origin.x + (float)counter / (float)(150 - 1) * bounds.size.width, bounds.origin.y + bounds.size.height / 2 + value * bounds.size.height / 2); + } else { + CGContextMoveToPoint(context, bounds.origin.x + (float)counter / (float)(150 - 1) * bounds.size.width, bounds.origin.y + bounds.size.height / 2 + value * bounds.size.height / 2); + } + } + // Save any previous graphics state settings before setting the color and line width for the current draw. + CGContextSaveGState(context); + CGContextSetRGBStrokeColor(context, (axis == 0 ? 1.0 : 0.0), (axis == 1 ? 1.0 : 0.0), (axis == 2 ? 1.0 : 0.0), 1.0); + CGContextSetLineWidth(context, 2.0); + CGContextStrokePath(context); + // Restore previous graphics state. + CGContextRestoreGState(context); +} + +- (void)drawRect:(CGRect)clip { + NSUInteger index = nextIndex; + + CGContextRef context = UIGraphicsGetCurrentContext(); + CGRect bounds = CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height); + + // create the graph + [self drawGraphInContext:context withBounds:bounds]; + + // plot x,y,z with anti-aliasing turned off + CGContextSetAllowsAntialiasing(context, false); + for (NSUInteger i = 0; i < 3; ++i) { + [self drawHistory:i fromIndex:index inContext:context bounds:bounds]; + } + CGContextSetAllowsAntialiasing(context, true); +} + + +@end diff --git a/Teslameter/Classes/TeslameterViewController.h b/Teslameter/Classes/TeslameterViewController.h new file mode 100755 index 0000000..060d526 --- /dev/null +++ b/Teslameter/Classes/TeslameterViewController.h @@ -0,0 +1,74 @@ +/* + File: TeslameterViewController.h +Abstract: A view controller that manages the primary view within the application. It creates a CLLocationManager and turns on heading updates. As updates are received, it displays them in a graph, x, y, and z labels, and also computes the magnitude (size or strength) of the magnetic vector. The units for all values are microteslas. + + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import + +@class GraphView; + +@interface TeslameterViewController : UIViewController { + UILabel *magnitudeLabel; + UILabel *xLabel; + UILabel *yLabel; + UILabel *zLabel; + GraphView *graphView; + + CLLocationManager *locationManager; +} + +// IBOutlets +@property (nonatomic, retain) IBOutlet UILabel *magnitudeLabel; +@property (nonatomic, retain) IBOutlet UILabel *xLabel; +@property (nonatomic, retain) IBOutlet UILabel *yLabel; +@property (nonatomic, retain) IBOutlet UILabel *zLabel; +@property (nonatomic, retain) IBOutlet GraphView *graphView; + +@property (nonatomic, retain) CLLocationManager *locationManager; + +@end + diff --git a/Teslameter/Classes/TeslameterViewController.m b/Teslameter/Classes/TeslameterViewController.m new file mode 100755 index 0000000..9b6a820 --- /dev/null +++ b/Teslameter/Classes/TeslameterViewController.m @@ -0,0 +1,135 @@ +/* + File: TeslameterViewController.m +Abstract: A view controller that manages the primary view within the application. It creates a CLLocationManager and turns on heading updates. As updates are received, it displays them in a graph, x, y, and z labels, and also computes the magnitude (size or strength) of the magnetic vector. The units for all values are microteslas. + + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "TeslameterViewController.h" +#import "GraphView.h" + +@implementation TeslameterViewController + +@synthesize magnitudeLabel; +@synthesize xLabel; +@synthesize yLabel; +@synthesize zLabel; +@synthesize graphView; + +@synthesize locationManager; + +- (void)viewDidLoad { + [super viewDidLoad]; + + // setup the location manager + self.locationManager = [[[CLLocationManager alloc] init] autorelease]; + + // check if the hardware has a compass + if ([CLLocationManager headingAvailable] == NO) { + // No compass is available. This application cannot function without a compass, + // so a dialog will be displayed and no magnetic data will be measured. + self.locationManager = nil; + UIAlertView *noCompassAlert = [[UIAlertView alloc] initWithTitle:@"No Compass!" message:@"This device does not have the ability to measure magnetic fields." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [noCompassAlert show]; + [noCompassAlert release]; + } else { + // heading service configuration + locationManager.headingFilter = kCLHeadingFilterNone; + + // setup delegate callbacks + locationManager.delegate = self; + + // start the compass + [locationManager startUpdatingHeading]; + } +} + +- (void)viewDidUnload { + self.magnitudeLabel = nil; + self.xLabel = nil; + self.yLabel = nil; + self.zLabel = nil; + self.graphView = nil; +} + +- (void)dealloc { + [magnitudeLabel release]; + [xLabel release]; + [yLabel release]; + [zLabel release]; + [graphView release]; + + // Stop the compass + [locationManager stopUpdatingHeading]; + [locationManager release]; + [super dealloc]; +} + +// This delegate method is invoked when the location manager has heading data. +- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)heading { + // Update the labels with the raw x, y, and z values. + [xLabel setText:[NSString stringWithFormat:@"%.1f", heading.x]]; + [yLabel setText:[NSString stringWithFormat:@"%.1f", heading.y]]; + [zLabel setText:[NSString stringWithFormat:@"%.1f", heading.z]]; + + // Compute and display the magnitude (size or strength) of the vector. + // magnitude = sqrt(x^2 + y^2 + z^2) + CGFloat magnitude = sqrt(heading.x*heading.x + heading.y*heading.y + heading.z*heading.z); + [magnitudeLabel setText:[NSString stringWithFormat:@"%.1f", magnitude]]; + + // Update the graph with the new magnetic reading. + [graphView updateHistoryWithX:heading.x y:heading.y z:heading.z]; +} + +// This delegate method is invoked when the location managed encounters an error condition. +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { + if ([error code] == kCLErrorDenied) { + // This error indicates that the user has denied the application's request to use location services. + [manager stopUpdatingHeading]; + } else if ([error code] == kCLErrorHeadingFailure) { + // This error indicates that the heading could not be determined, most likely because of strong magnetic interference. + } +} + +@end diff --git a/Teslameter/ReadMe.txt b/Teslameter/ReadMe.txt new file mode 100644 index 0000000..f0ed899 --- /dev/null +++ b/Teslameter/ReadMe.txt @@ -0,0 +1,51 @@ +### Teslameter ### + +=========================================================================== +DESCRIPTION: + +This application implements a Teslameter, a magnetic field detector. It displays the raw x, y, and z magnetometer values, a plotted history of those values, and a computed magnitude (size or strength) of the magnetic field. + +The use of the Core Location API for getting "heading" data is contained in the TeslameterViewController class. It creates a CLLocationManager object and uses it to get heading by invoking -[CLLocationManager startUpdatingHeading]. It implements the CLLocationManagerDelegate APIs for receiving heading and updates its user interface accordingly. + +=========================================================================== +BUILD REQUIREMENTS: + +iOS SDK 4.0 + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later and iPhone 3GS or iPhone 4 +Requires a device with a magnetometer. This sample will run in the Simulator but only one magnetic measurement will be received. + +=========================================================================== +PACKAGING LIST: + +AppDelegate: + +The application delegate, adds the main view to the window and displays the window. + + +TeslameterViewController: + +A view controller that manages the primary view within the application. It creates a CLLocationManager and turns on heading updates. As updates are received, it displays them in a graph, x, y, and z labels, and also computes the magnitude (size or strength) of the magnetic vector. The units for all values are microteslas. + + +GraphView: + +A custom view for plotting history of x, y, and z magnetic values. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.2 +- Updated to work with iOS 4.0. + +Version 1.1 +- Minor post-WWDC clean-up + +Version 1.0 +- First version. + +=========================================================================== +Copyright (C) 2009-2010 Apple Inc. All rights reserved. diff --git a/Teslameter/Resources/Background.png b/Teslameter/Resources/Background.png new file mode 100644 index 0000000..6482711 Binary files /dev/null and b/Teslameter/Resources/Background.png differ diff --git a/Teslameter/Resources/Icon-72.png b/Teslameter/Resources/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/Teslameter/Resources/Icon-72.png differ diff --git a/Teslameter/Resources/Icon-Small-50.png b/Teslameter/Resources/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/Teslameter/Resources/Icon-Small-50.png differ diff --git a/Teslameter/Resources/Icon-Small.png b/Teslameter/Resources/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/Teslameter/Resources/Icon-Small.png differ diff --git a/Teslameter/Resources/Icon-Small@2x.png b/Teslameter/Resources/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/Teslameter/Resources/Icon-Small@2x.png differ diff --git a/Teslameter/Resources/Icon.png b/Teslameter/Resources/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/Teslameter/Resources/Icon.png differ diff --git a/Teslameter/Resources/Icon@2x.png b/Teslameter/Resources/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/Teslameter/Resources/Icon@2x.png differ diff --git a/Teslameter/Resources/en.lproj/MainWindow.xib b/Teslameter/Resources/en.lproj/MainWindow.xib new file mode 100755 index 0000000..5fe5391 --- /dev/null +++ b/Teslameter/Resources/en.lproj/MainWindow.xib @@ -0,0 +1,454 @@ + + + + 768 + 10A394 + 731 + 1027.1 + 430.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + Teslameter + TeslameterViewController + + 2 + + + + + 292 + {320, 480} + + + 1 + MC4wMTA4Njk1NjMgMC4wMTA4Njk1NjMgMC4wMTA4Njk1NjMAA + + NO + + 2 + + + + + + YES + + + delegate + + + + 21 + + + + window + + + + 23 + + + + viewController + + + + 24 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 10 + + + + + 12 + + + + + 16 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 16.CustomClassName + 16.IBPluginDependency + + + YES + UIApplication + UIResponder + TeslameterViewController + {{512, 351}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{1041, 166}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 24 + + + + YES + + AppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + TeslameterViewController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + GraphView + UIView + + IBProjectSource + Classes/GraphView.h + + + + TeslameterViewController + UIViewController + + YES + + YES + graphView + magnitudeLabel + xLabel + yLabel + zLabel + + + YES + GraphView + UILabel + UILabel + UILabel + UILabel + + + + IBProjectSource + Classes/TeslameterViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../Teslameter.xcodeproj + 3 + 3.0 + + diff --git a/Teslameter/Resources/en.lproj/TeslameterViewController.xib b/Teslameter/Resources/en.lproj/TeslameterViewController.xib new file mode 100755 index 0000000..cb30214 --- /dev/null +++ b/Teslameter/Resources/en.lproj/TeslameterViewController.xib @@ -0,0 +1,383 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 292 + {{0, -20}, {320, 480}} + + NO + NO + 4 + NO + + NSImage + Background.png + + + + + 292 + {{20, 20}, {280, 124}} + + NO + YES + 7.000000e-01 + NO + --.- + + Helvetica + 9.600000e+01 + 16 + + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + 2 + + + + 292 + {{20, 386}, {71, 33}} + + NO + YES + NO + 0.0 + + Helvetica-Bold + 1.800000e+01 + 16 + + + 1 + MSAwIDAAA + + + 1 + 1.000000e+01 + 2 + + + + 292 + {{120, 386}, {74, 33}} + + NO + YES + NO + 0.0 + + + 1 + MC4xNDEzOTU0NSAwLjc3MTczOTEzIDAuMDEyMjcxODE0AA + + + 1 + 1.000000e+01 + 2 + + + + 292 + {{224, 387}, {75, 32}} + + NO + YES + NO + 0.0 + + + 1 + MC4wNzcxNjMzOTggMC4wNjU4Nzk5NDEgMQA + + + 1 + 1.000000e+01 + 2 + + + + 292 + {{17, 199}, {286, 134}} + + + 3 + MQA + + 2 + + + NO + + + {320, 460} + + + 1 + MC4wMTA4Njk1NjMgMC4wMTA4Njk1NjMgMC4wMTA4Njk1NjMAA + + NO + + 2 + + + + + + YES + + + view + + + + 7 + + + + xLabel + + + + 12 + + + + yLabel + + + + 13 + + + + zLabel + + + + 14 + + + + magnitudeLabel + + + + 15 + + + + graphView + + + + 27 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 6 + + + YES + + + + + + + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 22 + + + + + 26 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 22.IBPluginDependency + 26.CustomClassName + 26.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + TeslameterViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + GraphView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{733, 277}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 27 + + + + YES + + GraphView + UIView + + IBProjectSource + GraphView.h + + + + TeslameterViewController + UIViewController + + YES + + YES + graphView + magnitudeLabel + xLabel + yLabel + zLabel + + + YES + GraphView + UILabel + UILabel + UILabel + UILabel + + + + IBProjectSource + Classes/TeslameterViewController.h + + + + + 0 + ../Teslameter.xcodeproj + 3 + 3.0 + + diff --git a/Teslameter/Resources/iTunesArtwork b/Teslameter/Resources/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/Teslameter/Resources/iTunesArtwork differ diff --git a/Teslameter/Teslameter-Info.plist b/Teslameter/Teslameter-Info.plist new file mode 100755 index 0000000..a0a6145 --- /dev/null +++ b/Teslameter/Teslameter-Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.2 + UIStatusBarStyle + UIStatusBarStyleBlackOpaque + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + + diff --git a/Teslameter/Teslameter.xcodeproj/project.pbxproj b/Teslameter/Teslameter.xcodeproj/project.pbxproj new file mode 100755 index 0000000..a6eb9c3 --- /dev/null +++ b/Teslameter/Teslameter.xcodeproj/project.pbxproj @@ -0,0 +1,322 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 28D7ACF80DDB3853001CB0EB /* TeslameterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* TeslameterViewController.m */; }; + 2B44A17411CA971200B24959 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B44A17311CA971200B24959 /* CoreGraphics.framework */; }; + 2B44A17611CA971200B24959 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B44A17511CA971200B24959 /* CoreLocation.framework */; }; + 2B44A17811CA971200B24959 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B44A17711CA971200B24959 /* Foundation.framework */; }; + 2B44A17A11CA971200B24959 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B44A17911CA971200B24959 /* UIKit.framework */; }; + 2B44A1A911CA996400B24959 /* TeslameterViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1A811CA996400B24959 /* TeslameterViewController.xib */; }; + 2B44A1AB11CA996F00B24959 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1AA11CA996F00B24959 /* MainWindow.xib */; }; + 2B44A1EA11CA9A8400B24959 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1E311CA9A8400B24959 /* Icon-72.png */; }; + 2B44A1EB11CA9A8400B24959 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1E411CA9A8400B24959 /* Icon-Small-50.png */; }; + 2B44A1EC11CA9A8400B24959 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1E511CA9A8400B24959 /* Icon-Small.png */; }; + 2B44A1ED11CA9A8400B24959 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1E611CA9A8400B24959 /* Icon-Small@2x.png */; }; + 2B44A1EE11CA9A8400B24959 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1E711CA9A8400B24959 /* Icon.png */; }; + 2B44A1EF11CA9A8400B24959 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B44A1E811CA9A8400B24959 /* Icon@2x.png */; }; + 2BA881B011D2D7B300419525 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 2BA881AF11D2D7B300419525 /* iTunesArtwork */; }; + CFC5A65B0FD3E1A3001B9CB3 /* GraphView.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC5A65A0FD3E1A3001B9CB3 /* GraphView.m */; }; + CFF363450FD4816800BB1137 /* Background.png in Resources */ = {isa = PBXBuildFile; fileRef = CFF363440FD4816800BB1137 /* Background.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* Teslameter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Teslameter.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 28D7ACF60DDB3853001CB0EB /* TeslameterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeslameterViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* TeslameterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeslameterViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B44A17311CA971200B24959 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2B44A17511CA971200B24959 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 2B44A17711CA971200B24959 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2B44A17911CA971200B24959 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2B44A1CB11CA99A600B24959 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/TeslameterViewController.xib; sourceTree = ""; }; + 2B44A1CC11CA99B500B24959 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = Resources/en.lproj/MainWindow.xib; sourceTree = ""; }; + 2B44A1E311CA9A8400B24959 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Resources/Icon-72.png"; sourceTree = ""; }; + 2B44A1E411CA9A8400B24959 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Resources/Icon-Small-50.png"; sourceTree = ""; }; + 2B44A1E511CA9A8400B24959 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Resources/Icon-Small.png"; sourceTree = ""; }; + 2B44A1E611CA9A8400B24959 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Resources/Icon-Small@2x.png"; sourceTree = ""; }; + 2B44A1E711CA9A8400B24959 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Resources/Icon.png; sourceTree = ""; }; + 2B44A1E811CA9A8400B24959 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Resources/Icon@2x.png"; sourceTree = ""; }; + 2BA881AF11D2D7B300419525 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Resources/iTunesArtwork; sourceTree = ""; }; + 30385B690FFC024D006C2CD2 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Teslameter_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Teslameter_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Teslameter-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Teslameter-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + CFC5A6590FD3E1A3001B9CB3 /* GraphView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphView.h; sourceTree = ""; }; + CFC5A65A0FD3E1A3001B9CB3 /* GraphView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GraphView.m; sourceTree = ""; }; + CFF363440FD4816800BB1137 /* Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Background.png; path = Resources/Background.png; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B44A17411CA971200B24959 /* CoreGraphics.framework in Frameworks */, + 2B44A17611CA971200B24959 /* CoreLocation.framework in Frameworks */, + 2B44A17811CA971200B24959 /* Foundation.framework in Frameworks */, + 2B44A17A11CA971200B24959 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* TeslameterViewController.h */, + 28D7ACF70DDB3853001CB0EB /* TeslameterViewController.m */, + CFC5A6590FD3E1A3001B9CB3 /* GraphView.h */, + CFC5A65A0FD3E1A3001B9CB3 /* GraphView.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Teslameter.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 30385B690FFC024D006C2CD2 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Teslameter_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 2BA881AF11D2D7B300419525 /* iTunesArtwork */, + 2B44A1E311CA9A8400B24959 /* Icon-72.png */, + 2B44A1E411CA9A8400B24959 /* Icon-Small-50.png */, + 2B44A1E511CA9A8400B24959 /* Icon-Small.png */, + 2B44A1E611CA9A8400B24959 /* Icon-Small@2x.png */, + 2B44A1E711CA9A8400B24959 /* Icon.png */, + 2B44A1E811CA9A8400B24959 /* Icon@2x.png */, + CFF363440FD4816800BB1137 /* Background.png */, + 8D1107310486CEB800E47090 /* Teslameter-Info.plist */, + 2B44A1A811CA996400B24959 /* TeslameterViewController.xib */, + 2B44A1AA11CA996F00B24959 /* MainWindow.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B44A17311CA971200B24959 /* CoreGraphics.framework */, + 2B44A17511CA971200B24959 /* CoreLocation.framework */, + 2B44A17711CA971200B24959 /* Foundation.framework */, + 2B44A17911CA971200B24959 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Teslameter */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Teslameter" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Teslameter; + productName = Teslameter; + productReference = 1D6058910D05DD3D006BFB54 /* Teslameter.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Teslameter" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Teslameter */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B44A1AB11CA996F00B24959 /* MainWindow.xib in Resources */, + 2B44A1A911CA996400B24959 /* TeslameterViewController.xib in Resources */, + CFF363450FD4816800BB1137 /* Background.png in Resources */, + 2B44A1EA11CA9A8400B24959 /* Icon-72.png in Resources */, + 2B44A1EB11CA9A8400B24959 /* Icon-Small-50.png in Resources */, + 2B44A1EC11CA9A8400B24959 /* Icon-Small.png in Resources */, + 2B44A1ED11CA9A8400B24959 /* Icon-Small@2x.png in Resources */, + 2B44A1EE11CA9A8400B24959 /* Icon.png in Resources */, + 2B44A1EF11CA9A8400B24959 /* Icon@2x.png in Resources */, + 2BA881B011D2D7B300419525 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* TeslameterViewController.m in Sources */, + CFC5A65B0FD3E1A3001B9CB3 /* GraphView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2B44A1A811CA996400B24959 /* TeslameterViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 2B44A1CB11CA99A600B24959 /* en */, + ); + name = TeslameterViewController.xib; + sourceTree = ""; + }; + 2B44A1AA11CA996F00B24959 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 2B44A1CC11CA99B500B24959 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Teslameter_Prefix.pch; + INFOPLIST_FILE = "Teslameter-Info.plist"; + PRODUCT_NAME = Teslameter; + VALID_ARCHS = "armv6 armv7"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Teslameter_Prefix.pch; + INFOPLIST_FILE = "Teslameter-Info.plist"; + PRODUCT_NAME = Teslameter; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Teslameter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Teslameter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Teslameter/Teslameter_Prefix.pch b/Teslameter/Teslameter_Prefix.pch new file mode 100755 index 0000000..85f5215 --- /dev/null +++ b/Teslameter/Teslameter_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'Teslameter' target in the 'Teslameter' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Teslameter/main.m b/Teslameter/main.m new file mode 100755 index 0000000..7c08e9a --- /dev/null +++ b/Teslameter/main.m @@ -0,0 +1,58 @@ +/* + File: main.m +Abstract: Entry point for all applications. Creates the application object +and causes the event loop to start. + + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TheElements.zip b/TheElements.zip new file mode 100644 index 0000000..e043232 Binary files /dev/null and b/TheElements.zip differ diff --git a/TheElements/Classes/AtomicElement.h b/TheElements/Classes/AtomicElement.h new file mode 100644 index 0000000..907cedb --- /dev/null +++ b/TheElements/Classes/AtomicElement.h @@ -0,0 +1,86 @@ +/* + File: AtomicElement.h + Abstract: Simple object that encapsulate the Atomic Element values and images for the states. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface AtomicElement : NSObject { + NSNumber *atomicNumber; + NSString *name; + NSString *symbol; + NSString *state; + NSNumber *group; + NSNumber *period; + NSNumber *vertPos; + NSNumber *horizPos; + BOOL radioactive; + NSString *atomicWeight; + NSString *discoveryYear; + +} + +- (id)initWithDictionary:(NSDictionary *)aDictionary; + +@property (nonatomic, retain) NSNumber *atomicNumber; +@property (nonatomic, retain) NSString *name; +@property (nonatomic, retain) NSString *symbol; +@property (nonatomic, retain) NSString *state; +@property (nonatomic, retain) NSNumber *group; +@property (nonatomic, retain) NSNumber *period; +@property (nonatomic, retain) NSNumber *vertPos; +@property (nonatomic, retain) NSNumber *horizPos; + +@property (readonly) UIImage *stateImageForAtomicElementTileView; +@property (readonly) UIImage *flipperImageForAtomicElementNavigationItem; +@property (readonly) UIImage *stateImageForAtomicElementView; +@property (readonly) CGPoint positionForElement; +@property BOOL radioactive; +@property (nonatomic, retain) NSString *atomicWeight; +@property (nonatomic, retain) NSString *discoveryYear; + + +@end diff --git a/TheElements/Classes/AtomicElement.m b/TheElements/Classes/AtomicElement.m new file mode 100644 index 0000000..c32108c --- /dev/null +++ b/TheElements/Classes/AtomicElement.m @@ -0,0 +1,151 @@ +/* + File: AtomicElement.m + Abstract: Simple object that encapsulate the Atomic Element values and images for the states. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AtomicElement.h" + + +@implementation AtomicElement + +@synthesize atomicNumber; +@synthesize name; +@synthesize symbol; +@synthesize state; +@synthesize group; +@synthesize period; +@synthesize vertPos; +@synthesize horizPos; +@synthesize radioactive; +@synthesize atomicWeight; +@synthesize discoveryYear; + +- (id)initWithDictionary:(NSDictionary *)aDictionary { + if ([self init]) { + self.atomicNumber = [aDictionary valueForKey:@"atomicNumber"]; + self.atomicWeight = [aDictionary valueForKey:@"atomicWeight"]; + self.discoveryYear = [aDictionary valueForKey:@"discoveryYear"]; + self.radioactive = [[aDictionary valueForKey:@"radioactive"] boolValue]; + self.name = [aDictionary valueForKey:@"name"]; + self.symbol = [aDictionary valueForKey:@"symbol"]; + self.state = [aDictionary valueForKey:@"state"]; + self.group = [aDictionary valueForKey:@"group"]; + self.period = [aDictionary valueForKey:@"period"]; + self.vertPos = [aDictionary valueForKey:@"vertPos"]; + self.horizPos = [aDictionary valueForKey:@"horizPos"]; + + } + return self; +} + +- (void)dealloc { + [atomicNumber release]; + [atomicWeight release]; + [discoveryYear release]; + [name release]; + [symbol release]; + [state release]; + [group release]; + [period release]; + [vertPos release]; + [horizPos release]; + [super dealloc]; +} + +// this returns the position of the element in the classic periodic table locations +-(CGPoint)positionForElement { + return CGPointMake([[self horizPos] intValue] * 26-8,[[self vertPos] intValue]*26+35); + +} + +- (UIImage *)stateImageForAtomicElementTileView { + return [UIImage imageNamed:[NSString stringWithFormat:@"%@_37.png",state]]; +} + + +- (UIImage *)stateImageForAtomicElementView { + return [UIImage imageNamed:[NSString stringWithFormat:@"%@_256.png",state]]; +} + +- (UIImage *)stateImageForPeriodicTableView { + return [UIImage imageNamed:[NSString stringWithFormat:@"%@_24.png",state]]; +} + + +- (UIImage *)flipperImageForAtomicElementNavigationItem { + + // return a 30 x 30 image that is a reduced version + // of the AtomicElementTileView content + // this is used to display the flipper button in the navigation bar + CGSize itemSize=CGSizeMake(30.0,30.0); + UIGraphicsBeginImageContext(itemSize); + + UIImage *backgroundImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_30.png",state]]; + CGRect elementSymbolRectangle = CGRectMake(0,0, itemSize.width, itemSize.height); + [backgroundImage drawInRect:elementSymbolRectangle]; + + // draw the element name + [[UIColor whiteColor] set]; + + // draw the element number + UIFont *font = [UIFont boldSystemFontOfSize:8]; + CGPoint point = CGPointMake(2,1); + [[self.atomicNumber stringValue] drawAtPoint:point withFont:font]; + + // draw the element symbol + font = [UIFont boldSystemFontOfSize:13]; + CGSize stringSize = [self.symbol sizeWithFont:font]; + point = CGPointMake((elementSymbolRectangle.size.width-stringSize.width)/2,10); + + [self.symbol drawAtPoint:point withFont:font]; + + UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return theImage; +} + + + +@end diff --git a/TheElements/Classes/AtomicElementFlippedView.h b/TheElements/Classes/AtomicElementFlippedView.h new file mode 100644 index 0000000..f7953a3 --- /dev/null +++ b/TheElements/Classes/AtomicElementFlippedView.h @@ -0,0 +1,58 @@ +/* + File: AtomicElementFlippedView.h + Abstract: Displays the Atomic Element information with a link to Wikipedia. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "AtomicElementView.h" + +@interface AtomicElementFlippedView : AtomicElementView { + UIButton *wikipediaButton; +} + +@property (nonatomic,retain) UIButton *wikipediaButton; + + +@end diff --git a/TheElements/Classes/AtomicElementFlippedView.m b/TheElements/Classes/AtomicElementFlippedView.m new file mode 100644 index 0000000..7f8b309 --- /dev/null +++ b/TheElements/Classes/AtomicElementFlippedView.m @@ -0,0 +1,175 @@ +/* + File: AtomicElementFlippedView.m + Abstract: Displays the Atomic Element information with a link to Wikipedia. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AtomicElementView.h" +#import "AtomicElement.h" +#import "PeriodicElements.h" +#import "AtomicElementFlippedView.h" +#import + + +@implementation AtomicElementFlippedView + +@synthesize wikipediaButton; + + +-(void)setupUserInterface { + CGRect buttonFrame = CGRectMake(10.0, 209.0, 234.0, 37.0); + // create the button + self.wikipediaButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + self.wikipediaButton.frame=buttonFrame; + + [self.wikipediaButton setTitle:@"View at Wikipedia" forState:UIControlStateNormal]; + + // Center the text on the button, considering the button's shadow + self.wikipediaButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; + self.wikipediaButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + + [self.wikipediaButton addTarget:self action:@selector(jumpToWikipedia:) forControlEvents:UIControlEventTouchUpInside]; + + [self addSubview:self.wikipediaButton]; + return; +} + + +- (id)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) + { + [self setAutoresizesSubviews:YES]; + [self setupUserInterface]; + + // set the background color of the view to clearn + self.backgroundColor=[UIColor clearColor]; + } + return self; +} + +- (void)jumpToWikipedia:(id)sender { + // create the string that points to the correct Wikipedia page for the element name + NSString *wikiPageString = [NSString stringWithFormat:@"http://en.wikipedia.org/wiki/%@",element.name]; + if (![[UIApplication sharedApplication] openURL:[NSURL URLWithString:wikiPageString]]) + { + // there was an error trying to open the URL. for the moment we'll simply ignore it. + } +} + + +- (void)drawRect:(CGRect)rect { + + // get the background image for the state of the element + // position it appropriately and draw the image + UIImage *backgroundImage = [element stateImageForAtomicElementView]; + CGRect elementSymbolRectangle = CGRectMake(0,0, [backgroundImage size].width, [backgroundImage size].height); + [backgroundImage drawInRect:elementSymbolRectangle]; + + // all the text is drawn in white + [[UIColor whiteColor] set]; + + + // draw the element number + UIFont *font = [UIFont boldSystemFontOfSize:32]; + CGPoint point = CGPointMake(10,5); + [[NSString stringWithFormat:@"%@",element.atomicNumber] drawAtPoint:point withFont:font]; + + // draw the element symbol + CGSize stringSize = [element.symbol sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width-10),5); + [element.symbol drawAtPoint:point withFont:font]; + + // draw the element name + font = [UIFont boldSystemFontOfSize:36]; + stringSize = [element.name sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,50); + [element.name drawAtPoint:point withFont:font]; + + + float verticalStartingPoint=95; + + // draw the element weight + font = [UIFont boldSystemFontOfSize:14]; + NSString *atomicWeightString=[NSString stringWithFormat:@"Atomic Weight: %@",element.atomicWeight]; + stringSize = [atomicWeightString sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,verticalStartingPoint); + [atomicWeightString drawAtPoint:point withFont:font]; + + // draw the element state + font = [UIFont boldSystemFontOfSize:14]; + NSString *stateString=[NSString stringWithFormat:@"State: %@",element.state]; + stringSize = [stateString sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,verticalStartingPoint+20); + [stateString drawAtPoint:point withFont:font]; + + // draw the element period + font = [UIFont boldSystemFontOfSize:14]; + NSString *periodString=[NSString stringWithFormat:@"Period: %@",element.period]; + stringSize = [periodString sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,verticalStartingPoint+40); + [periodString drawAtPoint:point withFont:font]; + + // draw the element group + font = [UIFont boldSystemFontOfSize:14]; + NSString *groupString=[NSString stringWithFormat:@"Group: %@",element.group]; + stringSize = [groupString sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,verticalStartingPoint+60); + [groupString drawAtPoint:point withFont:font]; + + // draw the discovery year + NSString *discoveryYearString = [NSString stringWithFormat:@"Discovered: %@",element.discoveryYear]; + stringSize = [discoveryYearString sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,verticalStartingPoint+80); + [discoveryYearString drawAtPoint:point withFont:font]; + + + +} + +- (void)dealloc { + [wikipediaButton release]; + [super dealloc]; +} + +@end diff --git a/TheElements/Classes/AtomicElementTableViewCell.h b/TheElements/Classes/AtomicElementTableViewCell.h new file mode 100644 index 0000000..dc9f359 --- /dev/null +++ b/TheElements/Classes/AtomicElementTableViewCell.h @@ -0,0 +1,64 @@ +/* + File: AtomicElementTableViewCell.h + Abstract: Draws the tableview cell and lays out the subviews. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class AtomicElement; +@class AtomicElementTileView; + + +@interface AtomicElementTableViewCell : UITableViewCell { + AtomicElement *element; + AtomicElementTileView *elementTileView; + UILabel *labelView; +} + +@property (nonatomic,retain) AtomicElement *element; +@property (nonatomic,retain) AtomicElementTileView *elementTileView; +@property (nonatomic,retain) UILabel *labelView; + +@end diff --git a/TheElements/Classes/AtomicElementTableViewCell.m b/TheElements/Classes/AtomicElementTableViewCell.m new file mode 100644 index 0000000..1da61e5 --- /dev/null +++ b/TheElements/Classes/AtomicElementTableViewCell.m @@ -0,0 +1,133 @@ +/* + File: AtomicElementTableViewCell.m + Abstract: Draws the tableview cell and lays out the subviews. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AtomicElementTableViewCell.h" +#import "AtomicElement.h" +#import "AtomicElementTileView.h" + +@implementation AtomicElementTableViewCell + +@synthesize element; +@synthesize elementTileView; +@synthesize labelView; + + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + element = nil; + elementTileView = nil; + labelView = nil; + + // create the elementTileView and the labelView + // both of these will be laid out again by the layoutSubviews method + AtomicElementTileView *tileView = [[AtomicElementTileView alloc] initWithFrame:CGRectZero]; + self.elementTileView = tileView; + [self.contentView addSubview:tileView]; + [tileView release]; + + UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; + // set the label view to have a clear background and a 20 point font + label.backgroundColor = [UIColor clearColor]; + label.font = [UIFont boldSystemFontOfSize:20]; + self.labelView = label; + [self.contentView addSubview:label]; + [label release]; + + + // add both the label and elementTile to the TableViewCell view + } + return self; +} + + +- (void)layoutSubviews { + [super layoutSubviews]; + + // determine the content rect for the cell. This will change depending on the + // style of table (grouped vs plain) + CGRect contentRect = self.contentView.bounds; + + // position the image tile in the content rect. + CGRect elementTileRect = self.contentView.bounds; + elementTileRect.size = [AtomicElementTileView preferredViewSize]; + elementTileRect = CGRectOffset(elementTileRect,10,3); + elementTileView.frame = elementTileRect; + + // position the elment name in the content rect + CGRect labelRect = contentRect; + labelRect.origin.x = labelRect.origin.x+56; + labelRect.origin.y = labelRect.origin.y+3; + labelView.frame = labelRect; +} + + +- (void)dealloc { + [element release]; + [elementTileView release]; + [labelView release]; + [super dealloc]; +} + + +// the element setter +// we implement this because the table cell values need +// to be updated when this property changes, and this allows +// for the changes to be encapsulated +- (void)setElement:(AtomicElement *)anElement { + if (anElement != element) { + [element release]; + [anElement retain]; + element = anElement; + } + elementTileView.element = element; + labelView.text = element.name; + [elementTileView setNeedsDisplay]; + [labelView setNeedsDisplay]; +} + +@end diff --git a/TheElements/Classes/AtomicElementTileView.h b/TheElements/Classes/AtomicElementTileView.h new file mode 100644 index 0000000..c3ba5ba --- /dev/null +++ b/TheElements/Classes/AtomicElementTileView.h @@ -0,0 +1,60 @@ +/* + File: AtomicElementTileView.h + Abstract: Draws the small tile view displayed in the tableview rows. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class AtomicElement; + +@interface AtomicElementTileView : UIView { + AtomicElement *element; +} + +@property (nonatomic, retain) AtomicElement *element; + ++ (CGSize)preferredViewSize; + +@end diff --git a/TheElements/Classes/AtomicElementTileView.m b/TheElements/Classes/AtomicElementTileView.m new file mode 100644 index 0000000..c016fdd --- /dev/null +++ b/TheElements/Classes/AtomicElementTileView.m @@ -0,0 +1,96 @@ +/* + File: AtomicElementTileView.m + Abstract: Draws the small tile view displayed in the tableview rows. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AtomicElementTileView.h" +#import "AtomicElement.h" + + +@implementation AtomicElementTileView +@synthesize element; + ++ (CGSize)preferredViewSize { + return CGSizeMake(37,37); +} + + +- (id)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + element = nil; + } + return self; +} + +- (void)drawRect:(CGRect)rect { + CGPoint point; + // get the image that represents the element physical state and draw it + UIImage *backgroundImage = element.stateImageForAtomicElementTileView; + CGRect elementSymbolRectangle = CGRectMake(0,0, [backgroundImage size].width, [backgroundImage size].height); + [backgroundImage drawInRect:elementSymbolRectangle]; + + [[UIColor whiteColor] set]; + + // draw the element number + UIFont *font = [UIFont boldSystemFontOfSize:11]; + point = CGPointMake(3,2); + [[element.atomicNumber stringValue] drawAtPoint:point withFont:font]; + + // draw the element symbol + font = [UIFont boldSystemFontOfSize:18]; + CGSize stringSize = [element.symbol sizeWithFont:font]; + point = CGPointMake((elementSymbolRectangle.size.width-stringSize.width)/2,14); + + [element.symbol drawAtPoint:point withFont:font]; +} + + +- (void)dealloc { + [element release]; + [super dealloc]; +} + + +@end diff --git a/TheElements/Classes/AtomicElementView.h b/TheElements/Classes/AtomicElementView.h new file mode 100644 index 0000000..3863074 --- /dev/null +++ b/TheElements/Classes/AtomicElementView.h @@ -0,0 +1,63 @@ +/* + File: AtomicElementView.h + Abstract: Displays the Atomic Element information in a large format tile. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class AtomicElement; +@class AtomicElementViewController; + +@interface AtomicElementView : UIView { + AtomicElement *element; + AtomicElementViewController *viewController; +} + +@property (nonatomic,retain) AtomicElement *element; +@property (nonatomic, assign) AtomicElementViewController *viewController; + ++ (CGSize)preferredViewSize; +- (UIImage *)reflectedImageRepresentationWithHeight:(NSUInteger)height; +@end diff --git a/TheElements/Classes/AtomicElementView.m b/TheElements/Classes/AtomicElementView.m new file mode 100644 index 0000000..e93c308 --- /dev/null +++ b/TheElements/Classes/AtomicElementView.m @@ -0,0 +1,248 @@ +/* + File: AtomicElementView.m + Abstract: Displays the Atomic Element information in a large format tile. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AtomicElementView.h" +#import "AtomicElementViewController.h" +#import "AtomicElement.h" +#import "PeriodicElements.h" +#import + + +@implementation AtomicElementView +@synthesize element; +@synthesize viewController; + + +// the preferred size of this view is the size of the background image ++ (CGSize)preferredViewSize { + return CGSizeMake(256,256); +} + + +// initialize the view, calling super and setting the +// properties to nil +- (id)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + // Initialization code here. + element = nil; + viewController = nil; + // set the background color of the view to clearn + self.backgroundColor=[UIColor clearColor]; + + } + return self; +} + +// yes this view can become first responder +- (BOOL)canBecomeFirstResponder { + return YES; +} + +// when a touch event occurs tell the view controller to flip this view to the +// back and show the AtomicElementFlippedView instead. +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + + [viewController flipCurrentView]; + +} + + +- (void)drawRect:(CGRect)rect { + + // get the background image for the state of the element + // position it appropriately and draw the image + UIImage *backgroundImage = [element stateImageForAtomicElementView]; + CGRect elementSymbolRectangle = CGRectMake(0,0, [backgroundImage size].width, [backgroundImage size].height); + [backgroundImage drawInRect:elementSymbolRectangle]; + + // all the text is drawn in white + [[UIColor whiteColor] set]; + + // draw the element name + UIFont *font = [UIFont boldSystemFontOfSize:36]; + CGSize stringSize = [element.name sizeWithFont:font]; + CGPoint point = CGPointMake((self.bounds.size.width-stringSize.width)/2,256/2-50); + [element.name drawAtPoint:point withFont:font]; + + // draw the element number + font = [UIFont boldSystemFontOfSize:48]; + point = CGPointMake(10,0); + [[NSString stringWithFormat:@"%@",element.atomicNumber] drawAtPoint:point withFont:font]; + + + // draw the element symbol + font = [UIFont boldSystemFontOfSize:96]; + stringSize = [element.symbol sizeWithFont:font]; + point = CGPointMake((self.bounds.size.width-stringSize.width)/2,256-120); + [element.symbol drawAtPoint:point withFont:font]; +} + + +- (void)dealloc { + // the view controller is an assign, so just set it to nil + viewController = nil; + + [element release]; + [super dealloc]; +} + + +CGImageRef AEViewCreateGradientImage (int pixelsWide, + int pixelsHigh) +{ + CGImageRef theCGImage = NULL; + CGContextRef gradientBitmapContext = NULL; + CGColorSpaceRef colorSpace; + CGGradientRef grayScaleGradient; + CGPoint gradientStartPoint, gradientEndPoint; + + // Our gradient is always black-white and the mask + // must be in the gray colorspace + colorSpace = CGColorSpaceCreateDeviceGray(); + + // create the bitmap context + gradientBitmapContext = CGBitmapContextCreate (NULL, pixelsWide, pixelsHigh, + 8, 0, colorSpace, kCGImageAlphaNone); + + if (gradientBitmapContext != NULL) { + // define the start and end grayscale values (with the alpha, even though + // our bitmap context doesn't support alpha the gradient requires it) + CGFloat colors[] = {0.0, 1.0,1.0, 1.0,}; + + // create the CGGradient and then release the gray color space + grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2); + + // create the start and end points for the gradient vector (straight down) + gradientStartPoint = CGPointZero; + gradientEndPoint = CGPointMake(0,pixelsHigh); + + // draw the gradient into the gray bitmap context + CGContextDrawLinearGradient (gradientBitmapContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, kCGGradientDrawsAfterEndLocation); + + // clean up the gradient + CGGradientRelease(grayScaleGradient); + + // convert the context into a CGImageRef and release the + // context + theCGImage=CGBitmapContextCreateImage(gradientBitmapContext); + CGContextRelease(gradientBitmapContext); + + } + + // clean up the colorspace + CGColorSpaceRelease(colorSpace); + + // return the imageref containing the gradient + return theCGImage; +} + + + + +- (UIImage *)reflectedImageRepresentationWithHeight:(NSUInteger)height +{ + CGContextRef mainViewContentContext; + CGColorSpaceRef colorSpace; + + colorSpace = CGColorSpaceCreateDeviceRGB(); + + // create a bitmap graphics context the size of the image + mainViewContentContext = CGBitmapContextCreate (NULL, self.bounds.size.width,height, 8,0, colorSpace, kCGImageAlphaPremultipliedLast); + + // free the rgb colorspace + CGColorSpaceRelease(colorSpace); + + if (mainViewContentContext==NULL) + return NULL; + + // offset the context. This is necessary because, by default, the layer created by a view for + // caching its content is flipped. But when you actually access the layer content and have + // it rendered it is inverted. Since we're only creating a context the size of our + // reflection view (a fraction of the size of the main view) we have to translate the context the + // delta in size, render it, and then translate back (we could have saved/restored the graphics + // state + + CGFloat translateVertical=self.bounds.size.height-height; + CGContextTranslateCTM(mainViewContentContext,0,-translateVertical); + + // render the layer into the bitmap context + [self.layer renderInContext:mainViewContentContext]; + + // translate the context back + CGContextTranslateCTM(mainViewContentContext,0,translateVertical); + + // Create CGImageRef of the main view bitmap content, and then + // release that bitmap context + CGImageRef mainViewContentBitmapContext=CGBitmapContextCreateImage(mainViewContentContext); + CGContextRelease(mainViewContentContext); + + // create a 2 bit CGImage containing a gradient that will be used for masking the + // main view content to create the 'fade' of the reflection. The CGImageCreateWithMask + // function will stretch the bitmap image as required, so we can create a 1 pixel wide + // gradient + CGImageRef gradientMaskImage=AEViewCreateGradientImage(1,height); + + // Create an image by masking the bitmap of the mainView content with the gradient view + // then release the pre-masked content bitmap and the gradient bitmap + CGImageRef reflectionImage=CGImageCreateWithMask(mainViewContentBitmapContext,gradientMaskImage); + CGImageRelease(mainViewContentBitmapContext); + CGImageRelease(gradientMaskImage); + + // convert the finished reflection image to a UIImage + UIImage *theImage=[UIImage imageWithCGImage:reflectionImage]; + + // image is retained by the property setting above, so we can + // release the original + CGImageRelease(reflectionImage); + + // return the image + return theImage; +} + + + +@end diff --git a/TheElements/Classes/AtomicElementViewController.h b/TheElements/Classes/AtomicElementViewController.h new file mode 100644 index 0000000..374732a --- /dev/null +++ b/TheElements/Classes/AtomicElementViewController.h @@ -0,0 +1,77 @@ +/* + File: AtomicElementViewController.h + Abstract: Controller that manages the full tile view of the atomic information, + creating the reflection, and the flipping of the tile. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class AtomicElement; +@class AtomicElementView; +@class AtomicElementFlippedView; + +@interface AtomicElementViewController : UIViewController { + AtomicElement *element; + + AtomicElementView *atomicElementView; + AtomicElementFlippedView *atomicElementFlippedView; + UIImageView *reflectionView; + UIView *containerView; + UIButton *flipIndicatorButton; + BOOL frontViewIsVisible; +} + +@property (assign) BOOL frontViewIsVisible; +@property (nonatomic,retain) AtomicElement *element; +@property (nonatomic,retain) UIView *containerView; +@property (nonatomic,retain) AtomicElementView *atomicElementView; +@property (nonatomic,retain) UIImageView *reflectionView; +@property (nonatomic,retain) AtomicElementFlippedView *atomicElementFlippedView; +@property (nonatomic,retain) UIButton *flipIndicatorButton; + +- (void)flipCurrentView; +- (void)myTransitionDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context; + +@end diff --git a/TheElements/Classes/AtomicElementViewController.m b/TheElements/Classes/AtomicElementViewController.m new file mode 100644 index 0000000..eedd445 --- /dev/null +++ b/TheElements/Classes/AtomicElementViewController.m @@ -0,0 +1,238 @@ +/* + File: AtomicElementViewController.m + Abstract: Controller that manages the full tile view of the atomic information, + creating the reflection, and the flipping of the tile. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AtomicElementViewController.h" +#import "AtomicElementView.h" +#import "AtomicElementFlippedView.h" +#import "AtomicElement.h" + +@implementation AtomicElementViewController + +@synthesize element; +@synthesize atomicElementFlippedView; +@synthesize atomicElementView; +@synthesize containerView; +@synthesize reflectionView; +@synthesize flipIndicatorButton; +@synthesize frontViewIsVisible; + + +#define reflectionFraction 0.35 +#define reflectionOpacity 0.5 + + +- (id)init { + if (self = [super init]) { + element = nil; + atomicElementView = nil; + atomicElementFlippedView = nil; + self.frontViewIsVisible=YES; + self.hidesBottomBarWhenPushed = YES; + + } + return self; +} + + +- (void)loadView { + // create and store a container view + + UIView *localContainerView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; + self.containerView = localContainerView; + [localContainerView release]; + + containerView.backgroundColor = [UIColor blackColor]; + + CGSize preferredAtomicElementViewSize = [AtomicElementView preferredViewSize]; + + CGRect viewRect = CGRectMake((containerView.bounds.size.width-preferredAtomicElementViewSize.width)/2, + (containerView.bounds.size.height-preferredAtomicElementViewSize.height)/2-40, + preferredAtomicElementViewSize.width,preferredAtomicElementViewSize.height); + + // create the atomic element view + AtomicElementView *localAtomicElementView = [[AtomicElementView alloc] initWithFrame:viewRect]; + self.atomicElementView = localAtomicElementView; + [localAtomicElementView release]; + + // add the atomic element view to the containerView + atomicElementView.element = element; + [containerView addSubview:atomicElementView]; + + atomicElementView.viewController = self; + self.view = containerView; + + // create the atomic element flipped view + + AtomicElementFlippedView *localAtomicElementFlippedView = [[AtomicElementFlippedView alloc] initWithFrame:viewRect]; + self.atomicElementFlippedView = localAtomicElementFlippedView; + [localAtomicElementFlippedView release]; + + atomicElementFlippedView.element = element; + atomicElementFlippedView.viewController = self; + + + // create the reflection view + CGRect reflectionRect=viewRect; + + // the reflection is a fraction of the size of the view being reflected + reflectionRect.size.height=reflectionRect.size.height*reflectionFraction; + + // and is offset to be at the bottom of the view being reflected + reflectionRect=CGRectOffset(reflectionRect,0,viewRect.size.height); + + UIImageView *localReflectionImageView = [[UIImageView alloc] initWithFrame:reflectionRect]; + self.reflectionView = localReflectionImageView; + [localReflectionImageView release]; + + // determine the size of the reflection to create + NSUInteger reflectionHeight=atomicElementView.bounds.size.height*reflectionFraction; + + // create the reflection image, assign it to the UIImageView and add the image view to the containerView + reflectionView.image=[self.atomicElementView reflectedImageRepresentationWithHeight:reflectionHeight]; + reflectionView.alpha=reflectionOpacity; + + [containerView addSubview:reflectionView]; + + + UIButton *localFlipIndicator=[[UIButton alloc] initWithFrame:CGRectMake(0,0,30,30)]; + self.flipIndicatorButton=localFlipIndicator; + [localFlipIndicator release]; + + // front view is always visible at first + [flipIndicatorButton setBackgroundImage:[UIImage imageNamed:@"flipper_list_blue.png"] forState:UIControlStateNormal]; + + UIBarButtonItem *flipButtonBarItem; + flipButtonBarItem=[[UIBarButtonItem alloc] initWithCustomView:flipIndicatorButton]; + + [self.navigationItem setRightBarButtonItem:flipButtonBarItem animated:YES]; + [flipButtonBarItem release]; + + [flipIndicatorButton addTarget:self action:@selector(flipCurrentView) forControlEvents:(UIControlEventTouchDown )]; + + +} + + + +- (void)flipCurrentView { + NSUInteger reflectionHeight; + UIImage *reflectedImage; + + // disable user interaction during the flip + containerView.userInteractionEnabled = NO; + flipIndicatorButton.userInteractionEnabled = NO; + + // setup the animation group + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.75]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(myTransitionDidStop:finished:context:)]; + + // swap the views and transition + if (frontViewIsVisible==YES) { + [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:containerView cache:YES]; + [atomicElementView removeFromSuperview]; + [containerView addSubview:atomicElementFlippedView]; + + + // update the reflection image for the new view + reflectionHeight=atomicElementFlippedView.bounds.size.height*reflectionFraction; + reflectedImage = [atomicElementFlippedView reflectedImageRepresentationWithHeight:reflectionHeight]; + reflectionView.image=reflectedImage; + } else { + [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:containerView cache:YES]; + [atomicElementFlippedView removeFromSuperview]; + [containerView addSubview:atomicElementView]; + // update the reflection image for the new view + reflectionHeight=atomicElementView.bounds.size.height*reflectionFraction; + reflectedImage = [atomicElementView reflectedImageRepresentationWithHeight:reflectionHeight]; + reflectionView.image=reflectedImage; + } + [UIView commitAnimations]; + + + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.75]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(myTransitionDidStop:finished:context:)]; + + if (frontViewIsVisible==YES) + { + [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:flipIndicatorButton cache:YES]; + [flipIndicatorButton setBackgroundImage:element.flipperImageForAtomicElementNavigationItem forState:UIControlStateNormal]; + } + else + { + [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:flipIndicatorButton cache:YES]; + [flipIndicatorButton setBackgroundImage:[UIImage imageNamed:@"flipper_list_blue.png"] forState:UIControlStateNormal]; + + } + [UIView commitAnimations]; + frontViewIsVisible=!frontViewIsVisible; +} + + +- (void)myTransitionDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { + // re-enable user interaction when the flip is completed. + containerView.userInteractionEnabled = YES; + flipIndicatorButton.userInteractionEnabled = YES; + +} + + + +- (void)dealloc { + [atomicElementView release]; + [reflectionView release]; + [atomicElementFlippedView release]; + [element release]; + [super dealloc]; +} + + +@end diff --git a/TheElements/Classes/ElementsDataSourceProtocol.h b/TheElements/Classes/ElementsDataSourceProtocol.h new file mode 100644 index 0000000..cfd9409 --- /dev/null +++ b/TheElements/Classes/ElementsDataSourceProtocol.h @@ -0,0 +1,76 @@ +/* + File: ElementsDataSourceProtocol.h + Abstract: Protocol that defines information each Element tableview datasource must provide. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "AtomicElement.h" + +@protocol ElementsDataSource + +@required + +// these properties are used by the view controller +// for the navigation and tab bar +@property (readonly) NSString *name; +@property (readonly) NSString *navigationBarName; +@property (readonly) UIImage *tabBarImage; + +// this property determines the style of table view displayed +@property (readonly) UITableViewStyle tableViewStyle; + +// provides a standardized means of asking for the element at the specific +// index path, regardless of the sorting or display technique for the specific +// datasource +- (AtomicElement *)atomicElementForIndexPath:(NSIndexPath *)indexPath; +- (BOOL)showDisclosureIcon; + +@optional + +// this optional protocol allows us to send the datasource this message, since it has the +// required information +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; + +@end diff --git a/TheElements/Classes/ElementsSortedByAtomicNumberDataSource.h b/TheElements/Classes/ElementsSortedByAtomicNumberDataSource.h new file mode 100644 index 0000000..57f8ac1 --- /dev/null +++ b/TheElements/Classes/ElementsSortedByAtomicNumberDataSource.h @@ -0,0 +1,56 @@ +/* + File: ElementsSortedByAtomicNumberDataSource.h + Abstract: Provides the table view data for the elements sorted by atomic number. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ElementsDataSourceProtocol.h" + + +@interface ElementsSortedByAtomicNumberDataSource : NSObject { +} + + +@end diff --git a/TheElements/Classes/ElementsSortedByAtomicNumberDataSource.m b/TheElements/Classes/ElementsSortedByAtomicNumberDataSource.m new file mode 100644 index 0000000..b2d23ef --- /dev/null +++ b/TheElements/Classes/ElementsSortedByAtomicNumberDataSource.m @@ -0,0 +1,125 @@ +/* + File: ElementsSortedByAtomicNumberDataSource.m + Abstract: Provides the table view data for the elements sorted by atomic number. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ElementsSortedByAtomicNumberDataSource.h" +#import "TheElementsAppDelegate.h" +#import "PeriodicElements.h" +#import "AtomicElement.h" +#import "AtomicElementTableViewCell.h" + + +@implementation ElementsSortedByAtomicNumberDataSource + +// ElementsDataSourceProtocol methods + + +// return the data used by the navigation controller and tab bar item +- (NSString *)navigationBarName { + return @"Sorted by Atomic Number"; +} + +- (NSString *)name { + return @"Number"; +} + + +- (UIImage *)tabBarImage { + return [UIImage imageNamed:@"number_gray.png"]; +} + + +- (BOOL)showDisclosureIcon +{ + return YES; +} + + +// atomic number is displayed in a plain style tableview +- (UITableViewStyle)tableViewStyle { + return UITableViewStylePlain; +} + + +// return the atomic element at the index in the sorted by numbers array +- (AtomicElement *)atomicElementForIndexPath:(NSIndexPath *)indexPath { + return [[[PeriodicElements sharedPeriodicElements] elementsSortedByNumber] objectAtIndex:indexPath.row]; +} + + +// UITableViewDataSource methods + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + AtomicElementTableViewCell *cell = (AtomicElementTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"AtomicElementTableViewCell"]; + if (cell == nil) { + cell = [[[AtomicElementTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AtomicElementTableViewCell"] autorelease]; + } + + // configure cell contents + // all the rows should show the disclosure indicator + if ([self showDisclosureIcon]) + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + // set the element for this cell as specified by the datasource. The atomicElementForIndexPath: is declared + // as part of the ElementsDataSource Protocol and will return the appropriate element for the index row + cell.element = [self atomicElementForIndexPath:indexPath]; + + return cell; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // this table has only one section + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // get the shared elements object + // ask for, and return, the number of elements in the array of elements sorted by number + return [[[PeriodicElements sharedPeriodicElements] elementsSortedByNumber] count]; +} + +@end diff --git a/TheElements/Classes/ElementsSortedByNameDataSource.h b/TheElements/Classes/ElementsSortedByNameDataSource.h new file mode 100644 index 0000000..fc2797c --- /dev/null +++ b/TheElements/Classes/ElementsSortedByNameDataSource.h @@ -0,0 +1,55 @@ +/* + File: ElementsSortedByNameDataSource.h + Abstract: Provides the table view data for the elements sorted by name. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ElementsDataSourceProtocol.h" + +@interface ElementsSortedByNameDataSource : NSObject { +} + + +@end diff --git a/TheElements/Classes/ElementsSortedByNameDataSource.m b/TheElements/Classes/ElementsSortedByNameDataSource.m new file mode 100644 index 0000000..c51aee7 --- /dev/null +++ b/TheElements/Classes/ElementsSortedByNameDataSource.m @@ -0,0 +1,157 @@ +/* + File: ElementsSortedByNameDataSource.m + Abstract: Provides the table view data for the elements sorted by name. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ElementsSortedByNameDataSource.h" +#import "TheElementsAppDelegate.h" +#import "PeriodicElements.h" +#import "AtomicElement.h" +#import "AtomicElementTableViewCell.h" +#import "AtomicElementViewController.h" + +@implementation ElementsSortedByNameDataSource + + +// ElementsDataSourceProtocol methods + +// return the data used by the navigation controller and tab bar item + +- (NSString *)name { + return @"Name"; +} + +- (NSString *)navigationBarName { + return @"Sorted by Name"; +} + +- (BOOL)showDisclosureIcon +{ + return NO; +} +- (UIImage *)tabBarImage { + return [UIImage imageNamed:@"name_gray.png"]; +} + +// atomic name is displayed in a plain style tableview + +- (UITableViewStyle)tableViewStyle { + return UITableViewStylePlain; +}; + +// return the atomic element at the index + +- (AtomicElement *)atomicElementForIndexPath:(NSIndexPath *)indexPath { + return [[[PeriodicElements sharedPeriodicElements] elementsWithInitialLetter:[[[PeriodicElements sharedPeriodicElements] elementNameIndexArray] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row]; +} + + + +// UITableViewDataSource methods + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + AtomicElementTableViewCell *cell = (AtomicElementTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"AtomicElementTableViewCell"]; + if (cell == nil) { + cell = [[[AtomicElementTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AtomicElementTableViewCell"] autorelease]; + } + + // configure cell contents + // all the rows should show the disclosure indicator + if ([self showDisclosureIcon]) + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + // set the element for this cell as specified by the datasource. The atomicElementForIndexPath: is declared + // as part of the ElementsDataSource Protocol and will return the appropriate element for the index row + cell.element = [self atomicElementForIndexPath:indexPath]; + + return cell; +} + + + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // this table has multiple sections. One for each unique character that an element begins with + // [A,B,C,D,E,F,G,H,I,K,L,M,N,O,P,R,S,T,U,V,X,Y,Z] + // return the count of that array + return [[[PeriodicElements sharedPeriodicElements] elementNameIndexArray] count]; +} + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { + // returns the array of section titles. There is one entry for each unique character that an element begins with + // [A,B,C,D,E,F,G,H,I,K,L,M,N,O,P,R,S,T,U,V,X,Y,Z] + return [[PeriodicElements sharedPeriodicElements] elementNameIndexArray]; +} + +- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { + return index; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // the section represents the initial letter of the element + // return that letter + NSString *initialLetter = [[[PeriodicElements sharedPeriodicElements] elementNameIndexArray] objectAtIndex:section]; + + // get the array of elements that begin with that letter + NSArray *elementsWithInitialLetter = [[PeriodicElements sharedPeriodicElements] elementsWithInitialLetter:initialLetter]; + + // return the count + return [elementsWithInitialLetter count]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + // this table has multiple sections. One for each unique character that an element begins with + // [A,B,C,D,E,F,G,H,I,K,L,M,N,O,P,R,S,T,U,V,X,Y,Z] + // return the letter that represents the requested section + // this is actually a delegate method, but we forward the request to the datasource in the view controller + + return [[[PeriodicElements sharedPeriodicElements] elementNameIndexArray] objectAtIndex:section]; +} + + + +@end diff --git a/TheElements/Classes/ElementsSortedByStateDataSource.h b/TheElements/Classes/ElementsSortedByStateDataSource.h new file mode 100644 index 0000000..a744fd9 --- /dev/null +++ b/TheElements/Classes/ElementsSortedByStateDataSource.h @@ -0,0 +1,56 @@ +/* + File: ElementsSortedByStateDataSource.h + Abstract: Provides the table view data for the elements sorted by their standard physical state. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ElementsDataSourceProtocol.h" + +@interface ElementsSortedByStateDataSource : NSObject { +} + + +@end + \ No newline at end of file diff --git a/TheElements/Classes/ElementsSortedByStateDataSource.m b/TheElements/Classes/ElementsSortedByStateDataSource.m new file mode 100644 index 0000000..dce977f --- /dev/null +++ b/TheElements/Classes/ElementsSortedByStateDataSource.m @@ -0,0 +1,152 @@ +/* + File: ElementsSortedByStateDataSource.m + Abstract: Provides the table view data for the elements sorted by their standard physical state. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ElementsSortedByStateDataSource.h" +#import "TheElementsAppDelegate.h" +#import "PeriodicElements.h" +#import "AtomicElement.h" +#import "AtomicElementTableViewCell.h" + +@implementation ElementsSortedByStateDataSource + +// ElementsDataSourceProtocol methods + + +// return the data used by the navigation controller and tab bar item + +- (NSString *)name { + return @"State"; +} + +- (NSString *)navigationBarName { + return @"Grouped by State"; +} + +- (UIImage *)tabBarImage { + return [UIImage imageNamed:@"state_gray.png"]; +} + +- (BOOL)showDisclosureIcon +{ + return YES; +} + + +// atomic state is displayed in a grouped style tableview +- (UITableViewStyle)tableViewStyle { + return UITableViewStylePlain; +} + +// return the atomic element at the index +- (AtomicElement *)atomicElementForIndexPath:(NSIndexPath *)indexPath { + + // this table has multiple sections. One for each physical state + // [solid, liquid, gas, artificial] + // the section represents the index in the state array + // the row the index into the array of data for a particular state + + // get the state + NSString *elementState = [[[PeriodicElements sharedPeriodicElements] elementPhysicalStatesArray] objectAtIndex:indexPath.section]; + + // return the element in the state array + return [[[PeriodicElements sharedPeriodicElements] elementsWithPhysicalState:elementState] objectAtIndex:indexPath.row]; +} + + +// UITableViewDataSource methods + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + AtomicElementTableViewCell *cell = (AtomicElementTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"AtomicElementTableViewCell"]; + if (cell == nil) { + cell = [[[AtomicElementTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AtomicElementTableViewCell"] autorelease]; + } + + // configure cell contents + // all the rows should show the disclosure indicator + if ([self showDisclosureIcon]) + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + // set the element for this cell as specified by the datasource. The atomicElementForIndexPath: is declared + // as part of the ElementsDataSource Protocol and will return the appropriate element for the index row + cell.element = [self atomicElementForIndexPath:indexPath]; + + return cell; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // this table has multiple sections. One for each physical state + // [solid, liquid, gas, artificial] + // return the number of items in the states array + return [[[PeriodicElements sharedPeriodicElements] elementPhysicalStatesArray] count]; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // this table has multiple sections. One for each physical state + // [solid, liquid, gas, artificial] + + // get the state key for the requested section + NSString *stateKey = [[[PeriodicElements sharedPeriodicElements] elementPhysicalStatesArray] objectAtIndex:section]; + + // return the number of items that are in the array for that state + return [[[PeriodicElements sharedPeriodicElements] elementsWithPhysicalState:stateKey] count]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + // this table has multiple sections. One for each physical state + + // [solid, liquid, gas, artificial] + // return the state that represents the requested section + // this is actually a delegate method, but we forward the request to the datasource in the view controller + + return [[[PeriodicElements sharedPeriodicElements] elementPhysicalStatesArray] objectAtIndex:section]; +} + + +@end diff --git a/TheElements/Classes/ElementsSortedBySymbolDataSource.h b/TheElements/Classes/ElementsSortedBySymbolDataSource.h new file mode 100644 index 0000000..50b749c --- /dev/null +++ b/TheElements/Classes/ElementsSortedBySymbolDataSource.h @@ -0,0 +1,54 @@ +/* + File: ElementsSortedBySymbolDataSource.h + Abstract: Provides the table view data for the elements sorted by atomic symbol. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ElementsDataSourceProtocol.h" + +@interface ElementsSortedBySymbolDataSource : NSObject { +} + +@end diff --git a/TheElements/Classes/ElementsSortedBySymbolDataSource.m b/TheElements/Classes/ElementsSortedBySymbolDataSource.m new file mode 100644 index 0000000..16eda21 --- /dev/null +++ b/TheElements/Classes/ElementsSortedBySymbolDataSource.m @@ -0,0 +1,128 @@ +/* + File: ElementsSortedBySymbolDataSource.m + Abstract: Provides the table view data for the elements sorted by atomic symbol. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ElementsSortedBySymbolDataSource.h" +#import "TheElementsAppDelegate.h" +#import "PeriodicElements.h" +#import "AtomicElement.h" +#import "AtomicElementTableViewCell.h" + + +@implementation ElementsSortedBySymbolDataSource + +// ElementsDataSourceProtocol methods + +// return the data used by the navigation controller and tab bar item +- (NSString *)navigationBarName { + return @"Sorted by Atomic Symbol"; +} + +- (NSString *)name { + return @"Symbol"; +} + + +- (UIImage *)tabBarImage { + return [UIImage imageNamed:@"symbol_gray.png"]; +} + + +- (BOOL)showDisclosureIcon +{ + return YES; +} + + +// atomic number is displayed in a plain style tableview +- (UITableViewStyle)tableViewStyle { + return UITableViewStylePlain; +} + + +// return the atomic element at the index in the sorted by symbol array +- (AtomicElement *)atomicElementForIndexPath:(NSIndexPath *)indexPath { + + return [[[PeriodicElements sharedPeriodicElements] elementsSortedBySymbol] objectAtIndex:indexPath.row]; +} + + +// UITableViewDataSource methods + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + AtomicElementTableViewCell *cell = (AtomicElementTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"AtomicElementTableViewCell"]; + if (cell == nil) { + cell = [[[AtomicElementTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AtomicElementTableViewCell"] autorelease]; + } + + // configure cell contents + // all the rows should show the disclosure indicator + if ([self showDisclosureIcon]) + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + // set the element for this cell as specified by the datasource. The atomicElementForIndexPath: is declared + // as part of the ElementsDataSource Protocol and will return the appropriate element for the index row + cell.element = [self atomicElementForIndexPath:indexPath]; + + return cell; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // this table has only one section + return 1; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // get the shared elements object + // ask for, and return, the number of elements in the array of elements sorted by symbol + + return [[[PeriodicElements sharedPeriodicElements] elementsSortedBySymbol] count]; +} + + +@end diff --git a/TheElements/Classes/ElementsTableViewController.h b/TheElements/Classes/ElementsTableViewController.h new file mode 100644 index 0000000..098ab13 --- /dev/null +++ b/TheElements/Classes/ElementsTableViewController.h @@ -0,0 +1,67 @@ +/* + File: ElementsTableViewController.h + Abstract: Coordinates the tableviews and element data sources. It also responds + to changes of selection in the table view and provides the cells. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "ElementsDataSourceProtocol.h" + +@class AtomicElement; + + +@interface ElementsTableViewController : UIViewController { + UITableView *theTableView; + id dataSource; + +} + +@property (nonatomic,retain) UITableView *theTableView; +@property (nonatomic,retain) id dataSource; + +- (id)initWithDataSource:(id)theDataSource; + + +@end diff --git a/TheElements/Classes/ElementsTableViewController.m b/TheElements/Classes/ElementsTableViewController.m new file mode 100644 index 0000000..3eb4688 --- /dev/null +++ b/TheElements/Classes/ElementsTableViewController.m @@ -0,0 +1,163 @@ +/* + File: ElementsTableViewController.m + Abstract: Coordinates the tableviews and element data sources. It also responds + to changes of selection in the table view and provides the cells. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "ElementsTableViewController.h" + +#import "AtomicElement.h" +#import "AtomicElementTableViewCell.h" +#import "AtomicElementViewController.h" +#import "TheElementsAppDelegate.h" +#import "ElementsDataSourceProtocol.h" + + +@implementation ElementsTableViewController + +@synthesize theTableView; +@synthesize dataSource; + + +// this is the custom initialization method for the ElementsTableViewController +// it expects an object that conforms to both the UITableViewDataSource protocol +// which provides data to the tableview, and the ElementDataSource protocol which +// provides information about the elements data that is displayed, +- (id)initWithDataSource:(id)theDataSource { + if ([self init]) { + theTableView = nil; + + // retain the data source + self.dataSource = theDataSource; + // set the title, and tab bar images from the dataSource + // object. These are part of the ElementsDataSource Protocol + self.title = [dataSource name]; + self.tabBarItem.image = [dataSource tabBarImage]; + + // set the long name shown in the navigation bar + self.navigationItem.title=[dataSource navigationBarName]; + + // create a custom navigation bar button and set it to always say "back" + UIBarButtonItem *temporaryBarButtonItem=[[UIBarButtonItem alloc] init]; + temporaryBarButtonItem.title=@"Back"; + self.navigationItem.backBarButtonItem = temporaryBarButtonItem; + [temporaryBarButtonItem release]; + + } + return self; +} + + +- (void)dealloc { + theTableView.delegate = nil; + theTableView.dataSource = nil; + [theTableView release]; + [dataSource release]; + [super dealloc]; +} + + +- (void)loadView { + + // create a new table using the full application frame + // we'll ask the datasource which type of table to use (plain or grouped) + UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] + style:[dataSource tableViewStyle]]; + + // set the autoresizing mask so that the table will always fill the view + tableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight); + + // set the cell separator to a single straight line. + tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; + + // set the tableview delegate to this object and the datasource to the datasource which has already been set + tableView.delegate = self; + tableView.dataSource = dataSource; + + tableView.sectionIndexMinimumDisplayRowCount=10; + + // set the tableview as the controller view + self.theTableView = tableView; + self.view = tableView; + [tableView release]; + +} + +-(void)viewWillAppear:(BOOL)animated +{ + // force the tableview to load + + [theTableView reloadData]; +} + + +// +// +// UITableViewDelegate methods +// +// + +// the user selected a row in the table. +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath { + // deselect the new row using animation + [tableView deselectRowAtIndexPath:newIndexPath animated:YES]; + + // get the element that is represented by the selected row. + AtomicElement *element = [dataSource atomicElementForIndexPath:newIndexPath]; + + // create an AtomicElementViewController. This controller will display the full size tile for the element + AtomicElementViewController *elementController = [[AtomicElementViewController alloc] init]; + + // set the element for the controller + elementController.element = element; + + // push the element view controller onto the navigation stack to display it + [[self navigationController] pushViewController:elementController animated:YES]; + [elementController release]; +} + + + +@end diff --git a/TheElements/Classes/PeriodicElements.h b/TheElements/Classes/PeriodicElements.h new file mode 100644 index 0000000..8e6e751 --- /dev/null +++ b/TheElements/Classes/PeriodicElements.h @@ -0,0 +1,78 @@ +/* + File: PeriodicElements.h + Abstract: Encapsulates the collection of elements and returns them in presorted states. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + + +@interface PeriodicElements : NSObject { + NSMutableDictionary *elementsDictionary; + NSMutableDictionary *statesDictionary; + + NSMutableDictionary *nameIndexesDictionary; + NSArray *elementNameIndexArray; + + NSArray *elementsSortedByNumber; + NSArray *elementsSortedBySymbol; + NSArray *elementPhysicalStatesArray; + +} + +@property (nonatomic,retain) NSMutableDictionary *statesDictionary; +@property (nonatomic,retain) NSMutableDictionary *elementsDictionary; +@property (nonatomic,retain) NSMutableDictionary *nameIndexesDictionary; +@property (nonatomic,retain) NSArray *elementNameIndexArray; +@property (nonatomic,retain) NSArray *elementsSortedByNumber; +@property (nonatomic,retain) NSArray *elementsSortedBySymbol; +@property (nonatomic,retain) NSArray *elementPhysicalStatesArray; + ++ (PeriodicElements*)sharedPeriodicElements; +- (NSArray *)elementsWithPhysicalState:(NSString*)aState; + +- (NSArray *)elementsWithInitialLetter:(NSString*)aKey; + + +@end diff --git a/TheElements/Classes/PeriodicElements.m b/TheElements/Classes/PeriodicElements.m new file mode 100644 index 0000000..d68f096 --- /dev/null +++ b/TheElements/Classes/PeriodicElements.m @@ -0,0 +1,282 @@ +/* + File: PeriodicElements.m + Abstract: Encapsulates the collection of elements and returns them in presorted states. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "PeriodicElements.h" +#import "AtomicElement.h" + +@interface PeriodicElements(mymethods) +// these are private methods that outside classes need not use +- (void)presortElementsByPhysicalState; +- (void)presortElementInitialLetterIndexes; +- (void)presortElementNamesForInitialLetter:(NSString *)aKey; +- (void)presortElementsWithPhysicalState:(NSString *)state; +- (NSArray *)presortElementsByNumber; +- (NSArray *)presortElementsBySymbol; +- (void)setupElementsArray; +@end + + +@implementation PeriodicElements + +@synthesize statesDictionary; +@synthesize elementsDictionary; +@synthesize nameIndexesDictionary; +@synthesize elementNameIndexArray; +@synthesize elementsSortedByNumber; +@synthesize elementsSortedBySymbol; +@synthesize elementPhysicalStatesArray; + + +// we use the singleton approach, one collection for the entire application +static PeriodicElements *sharedPeriodicElementsInstance = nil; + ++ (PeriodicElements *)sharedPeriodicElements +{ + @synchronized(self) { + static dispatch_once_t pred; + dispatch_once(&pred, ^{ sharedPeriodicElementsInstance = [[self alloc] init]; }); + } + return sharedPeriodicElementsInstance; +} + ++ (id)allocWithZone:(NSZone *)zone { + @synchronized(self) { + if (sharedPeriodicElementsInstance == nil) { + sharedPeriodicElementsInstance = [super allocWithZone:zone]; + return sharedPeriodicElementsInstance; // assignment and return on first allocation + } + } + return nil; //on subsequent allocation attempts return nil +} + +- (id)copyWithZone:(NSZone *)zone { + return self; +} + +- (id)retain { + return self; +} + +- (unsigned)retainCount { + return UINT_MAX; //denotes an object that cannot be released +} + +- (void)release { + //do nothing +} + +- (id)autorelease { + return self; +} + + +// setup the data collection +- init { + if (self = [super init]) { + [self setupElementsArray]; + } + return self; +} + + +- (void)setupElementsArray { + NSDictionary *eachElement; + + // create dictionaries that contain the arrays of element data indexed by + // name + self.elementsDictionary = [NSMutableDictionary dictionary]; + // physical state + self.statesDictionary = [NSMutableDictionary dictionary]; + // unique first characters (for the Name index table) + self.nameIndexesDictionary = [NSMutableDictionary dictionary]; + + // create empty array entries in the states Dictionary or each physical state + [statesDictionary setObject:[NSMutableArray array] forKey:@"Solid"]; + [statesDictionary setObject:[NSMutableArray array] forKey:@"Liquid"]; + [statesDictionary setObject:[NSMutableArray array] forKey:@"Gas"]; + [statesDictionary setObject:[NSMutableArray array] forKey:@"Artificial"]; + + // read the element data from the plist + NSString *thePath = [[NSBundle mainBundle] pathForResource:@"Elements" ofType:@"plist"]; + NSArray *rawElementsArray = [[NSArray alloc] initWithContentsOfFile:thePath]; + + // iterate over the values in the raw elements dictionary + for (eachElement in rawElementsArray) + { + // create an atomic element instance for each + AtomicElement *anElement = [[AtomicElement alloc] initWithDictionary:eachElement]; + + // store that item in the elements dictionary with the name as the key + [elementsDictionary setObject:anElement forKey:anElement.name]; + + // add that element to the appropriate array in the physical state dictionary + [[statesDictionary objectForKey:anElement.state] addObject:anElement]; + + // get the element's initial letter + NSString *firstLetter = [anElement.name substringToIndex:1]; + NSMutableArray *existingArray; + + // if an array already exists in the name index dictionary + // simply add the element to it, otherwise create an array + // and add it to the name index dictionary with the letter as the key + if (existingArray = [nameIndexesDictionary valueForKey:firstLetter]) + { + [existingArray addObject:anElement]; + } else { + NSMutableArray *tempArray = [NSMutableArray array]; + [nameIndexesDictionary setObject:tempArray forKey:firstLetter]; + [tempArray addObject:anElement]; + } + + // release the element, it is held by the various collections + [anElement release]; + + } + // release the raw element data + [rawElementsArray release]; + + + + // create the dictionary containing the possible element states + // and presort the states data + self.elementPhysicalStatesArray = [NSArray arrayWithObjects:@"Solid",@"Liquid",@"Gas",@"Artificial",nil]; + [self presortElementsByPhysicalState]; + + // presort the dictionaries now + // this could be done the first time they are requested instead + + [self presortElementInitialLetterIndexes]; + + self.elementsSortedByNumber = [self presortElementsByNumber]; + self.elementsSortedBySymbol = [self presortElementsBySymbol]; + + + +} + +// return the array of elements for the requested physical state +- (NSArray *)elementsWithPhysicalState:(NSString*)aState { + return [statesDictionary objectForKey:aState]; +} + +// presort each of the arrays for the physical states +- (void)presortElementsByPhysicalState { + for (NSString *stateKey in elementPhysicalStatesArray) { + [self presortElementsWithPhysicalState:stateKey]; + } + +} + +- (void)presortElementsWithPhysicalState:(NSString *)state { + NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" + ascending:YES + selector:@selector(localizedCaseInsensitiveCompare:)] ; + + NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor]; + [[statesDictionary objectForKey:state] sortUsingDescriptors:descriptors]; + [nameDescriptor release]; + +} + + + +// return an array of elements for an initial letter (ie A, B, C, ...) +- (NSArray *)elementsWithInitialLetter:(NSString*)aKey { + return [nameIndexesDictionary objectForKey:aKey]; +} + +// presort the name index arrays so the elements are in the correct order +- (void)presortElementInitialLetterIndexes { + self.elementNameIndexArray = [[nameIndexesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + for (NSString *eachNameIndex in elementNameIndexArray) { + [self presortElementNamesForInitialLetter:eachNameIndex]; + } +} + +- (void)presortElementNamesForInitialLetter:(NSString *)aKey { + NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" + ascending:YES + selector:@selector(localizedCaseInsensitiveCompare:)] ; + + NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor]; + [[nameIndexesDictionary objectForKey:aKey] sortUsingDescriptors:descriptors]; + [nameDescriptor release]; +} + + + + +// presort the elementsSortedByNumber array +- (NSArray *)presortElementsByNumber { + NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"atomicNumber" + ascending:YES + selector:@selector(compare:)] ; + + NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor]; + NSArray *sortedElements = [[elementsDictionary allValues] sortedArrayUsingDescriptors:descriptors]; + [nameDescriptor release]; + return sortedElements; +} + + +// presort the elementsSortedBySymbol array + +- (NSArray *)presortElementsBySymbol { + NSSortDescriptor *symbolDescriptor = [[NSSortDescriptor alloc] initWithKey:@"symbol" + ascending:YES + selector:@selector(localizedCaseInsensitiveCompare:)] ; + + NSArray *descriptors = [NSArray arrayWithObject:symbolDescriptor]; + NSArray *sortedElements = [[elementsDictionary allValues] sortedArrayUsingDescriptors:descriptors]; + [symbolDescriptor release]; + return sortedElements; + +} + + + +@end \ No newline at end of file diff --git a/TheElements/Classes/TheElementsAppDelegate.h b/TheElements/Classes/TheElementsAppDelegate.h new file mode 100644 index 0000000..9306926 --- /dev/null +++ b/TheElements/Classes/TheElementsAppDelegate.h @@ -0,0 +1,60 @@ +/* + File: TheElementsAppDelegate.h + Abstract: Application delegate that sets up the application. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface TheElementsAppDelegate : NSObject { + + UIWindow *portraitWindow; + UITabBarController *tabBarController; +} + +@property (nonatomic, retain) UITabBarController *tabBarController; +@property (nonatomic, retain) UIWindow *portraitWindow; + + +@end diff --git a/TheElements/Classes/TheElementsAppDelegate.m b/TheElements/Classes/TheElementsAppDelegate.m new file mode 100644 index 0000000..5f1181c --- /dev/null +++ b/TheElements/Classes/TheElementsAppDelegate.m @@ -0,0 +1,207 @@ +/* + File: TheElementsAppDelegate.m + Abstract: Application delegate that sets up the application. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TheElementsAppDelegate.h" +#import "PeriodicElements.h" +#import "AtomicElement.h" +#import "ElementsSortedByNameDataSource.h" +#import "ElementsSortedByAtomicNumberDataSource.h" +#import "ElementsSortedBySymbolDataSource.h" +#import "ElementsSortedByStateDataSource.h" +#import "ElementsTableViewController.h" + + + +@implementation TheElementsAppDelegate + +@synthesize tabBarController; +@synthesize portraitWindow; + + +- init { + if (self = [super init]) { + // initialize to nil + portraitWindow = nil; + tabBarController = nil; + } + return self; +} + +- (UINavigationController *)newNavigationControllerWrappingViewControllerForDataSourceOfClass:(Class)datasourceClass { + // this is entirely a convenience method to reduce the repetition of the code + // in the setupPortaitUserInterface + // it returns a retained instance of the UINavigationController class. This is unusual, but + // it is necessary to limit the autorelease use as much as possible. + + // for each tableview 'screen' we need to create a datasource instance (the class that is passed in) + // we then need to create an instance of ElementsTableViewController with that datasource instance + // finally we need to return a UINaviationController for each screen, with the ElementsTableViewController + // as the root view controller. + + // many of these require the temporary creation of objects that need to be released after they are configured + // and factoring this out makes the setup code much easier to follow, but you can still see the actual + // implementation here + + + // the class type for the datasource is not crucial, but that it implements the + // ElementsDataSource protocol and the UITableViewDataSource Protocol is. + id dataSource = [[datasourceClass alloc] init]; + + // create the ElementsTableViewController and set the datasource + ElementsTableViewController *theViewController; + theViewController = [[ElementsTableViewController alloc] initWithDataSource:dataSource]; + + // create the navigation controller with the view controller + UINavigationController *theNavigationController; + theNavigationController = [[UINavigationController alloc] initWithRootViewController:theViewController]; + + // before we return we can release the dataSource (it is now managed by the ElementsTableViewController instance + [dataSource release]; + + // and we can release the viewController because it is managed by the navigation controller + [theViewController release]; + + return theNavigationController; +} + + +- (void)setupPortraitUserInterface { + // a local navigation variable + // this is reused several times + UINavigationController *localNavigationController; + + // Set up the portraitWindow and content view + UIWindow *localPortraitWindow; + localPortraitWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.portraitWindow = localPortraitWindow; + + // the localPortraitWindow data is now retained by the application delegate + // so we can release the local variable + [localPortraitWindow release]; + + + [portraitWindow setBackgroundColor:[UIColor blackColor]]; + + // Create a tabbar controller and an array to contain the view controllers + tabBarController = [[UITabBarController alloc] init]; + NSMutableArray *localViewControllersArray = [[NSMutableArray alloc] initWithCapacity:4]; + + // setup the 4 view controllers for the different data representations + + // create the view controller and datasource for the ElementsSortedByNameDataSource + // wrap it in a UINavigationController, and add that navigationController to the + // viewControllersArray array + + localNavigationController = [self newNavigationControllerWrappingViewControllerForDataSourceOfClass:[ElementsSortedByNameDataSource class]]; + [localViewControllersArray addObject:localNavigationController]; + + // the localNavigationController data is now retained by the application delegate + // so we can release the local variable + [localNavigationController release]; + + + // repeat the process for the ElementsSortedByAtomicNumberDataSource + localNavigationController = [self newNavigationControllerWrappingViewControllerForDataSourceOfClass:[ElementsSortedByAtomicNumberDataSource class]]; + [localViewControllersArray addObject:localNavigationController]; + + // the localNavigationController data is now retained by the application delegate + // so we can release the local variable + [localNavigationController release]; + + + // repeat the process for the ElementsSortedBySymbolDataSource + localNavigationController = [self newNavigationControllerWrappingViewControllerForDataSourceOfClass:[ElementsSortedBySymbolDataSource class]]; + [localViewControllersArray addObject:localNavigationController]; + + // the localNavigationController data is now retained by the application delegate + // so we can release the local variable + [localNavigationController release]; + + + // repeat the process for the ElementsSortedByStateDataSource + localNavigationController = [self newNavigationControllerWrappingViewControllerForDataSourceOfClass:[ElementsSortedByStateDataSource class]]; + [localViewControllersArray addObject:localNavigationController]; + + // the localNavigationController data is now retained by the application delegate + // so we can release the local variable + [localNavigationController release]; + + + + // set the tab bar controller view controller array to the localViewControllersArray + tabBarController.viewControllers = localViewControllersArray; + + // the localViewControllersArray data is now retained by the tabBarController + // so we can release this version + [localViewControllersArray release]; + + // set the window subview as the tab bar controller + [portraitWindow addSubview:tabBarController.view]; + + // make the window visible + [portraitWindow makeKeyAndVisible]; + + +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // configure the portrait user interface + [self setupPortraitUserInterface]; + + +} + + +- (void)dealloc { + [tabBarController release]; + [portraitWindow release]; + [super dealloc]; +} + +@end + diff --git a/TheElements/Elements.plist b/TheElements/Elements.plist new file mode 100644 index 0000000..ee04bb1 --- /dev/null +++ b/TheElements/Elements.plist @@ -0,0 +1,2838 @@ + + + + + + atomicNumber + 89 + atomicWeight + 227 + discoveryYear + 1899 A.D. + group + 3 + horizPos + 4 + name + Actinium + period + 7 + radioactive + True + state + Solid + symbol + Ac + vertPos + 10 + + + atomicNumber + 13 + atomicWeight + 26.981538 + discoveryYear + 1825 A.D. + group + 13 + horizPos + 13 + name + Aluminum + period + 3 + radioactive + False + state + Solid + symbol + Al + vertPos + 3 + + + atomicNumber + 95 + atomicWeight + 243 + discoveryYear + 1944 A.D. + group + 3 + horizPos + 10 + name + Americium + period + 7 + radioactive + True + state + Artificial + symbol + Am + vertPos + 10 + + + atomicNumber + 51 + atomicWeight + 121.760 + discoveryYear + Ancient + group + 15 + horizPos + 15 + name + Antimony + period + 5 + radioactive + False + state + Solid + symbol + Sb + vertPos + 5 + + + atomicNumber + 18 + atomicWeight + 39.948 + discoveryYear + 1894 A.D. + group + 18 + horizPos + 18 + name + Argon + period + 3 + radioactive + False + state + Gas + symbol + Ar + vertPos + 3 + + + atomicNumber + 33 + atomicWeight + 74.92160 + discoveryYear + 1250 A.D. + group + 15 + horizPos + 15 + name + Arsenic + period + 4 + radioactive + False + state + Solid + symbol + As + vertPos + 4 + + + atomicNumber + 85 + atomicWeight + 210 + discoveryYear + 1940 A.D. + group + 17 + horizPos + 17 + name + Astatine + period + 6 + radioactive + True + state + Solid + symbol + At + vertPos + 6 + + + atomicNumber + 56 + atomicWeight + 137.327 + discoveryYear + 1808 A.D. + group + 2 + horizPos + 2 + name + Barium + period + 6 + radioactive + False + state + Solid + symbol + Ba + vertPos + 6 + + + atomicNumber + 97 + atomicWeight + 247 + discoveryYear + 1949 A.D. + group + 3 + horizPos + 12 + name + Berkelium + period + 7 + radioactive + True + state + Artificial + symbol + Bk + vertPos + 10 + + + atomicNumber + 4 + atomicWeight + 9.012182 + discoveryYear + 1797 A.D. + group + 2 + horizPos + 2 + name + Beryllium + period + 2 + radioactive + False + state + Solid + symbol + Be + vertPos + 2 + + + atomicNumber + 83 + atomicWeight + 208.98038 + discoveryYear + 1400 A.D. + group + 15 + horizPos + 15 + name + Bismuth + period + 6 + radioactive + False + state + Solid + symbol + Bi + vertPos + 6 + + + atomicNumber + 107 + atomicWeight + 264 + discoveryYear + 1981 A.D. + group + 7 + horizPos + 7 + name + Bohrium + period + 7 + radioactive + True + state + Artificial + symbol + Bh + vertPos + 7 + + + atomicNumber + 5 + atomicWeight + 10.811 + discoveryYear + 1808 A.D. + group + 13 + horizPos + 13 + name + Boron + period + 2 + radioactive + False + state + Solid + symbol + B + vertPos + 2 + + + atomicNumber + 35 + atomicWeight + 79.904 + discoveryYear + 1826 A.D. + group + 17 + horizPos + 17 + name + Bromine + period + 4 + radioactive + False + state + Liquid + symbol + Br + vertPos + 4 + + + atomicNumber + 48 + atomicWeight + 112.411 + discoveryYear + 1817 A.D. + group + 12 + horizPos + 12 + name + Cadmium + period + 5 + radioactive + False + state + Solid + symbol + Cd + vertPos + 5 + + + atomicNumber + 20 + atomicWeight + 40.078 + discoveryYear + 1808 A.D. + group + 2 + horizPos + 2 + name + Calcium + period + 4 + radioactive + False + state + Solid + symbol + Ca + vertPos + 4 + + + atomicNumber + 98 + atomicWeight + 251 + discoveryYear + 1950 A.D. + group + 3 + horizPos + 13 + name + Californium + period + 7 + radioactive + True + state + Artificial + symbol + Cf + vertPos + 10 + + + atomicNumber + 6 + atomicWeight + 12.0107 + discoveryYear + Prehistoric + group + 14 + horizPos + 14 + name + Carbon + period + 2 + radioactive + False + state + Solid + symbol + C + vertPos + 2 + + + atomicNumber + 58 + atomicWeight + 140.116 + discoveryYear + 1803 A.D. + group + 3 + horizPos + 5 + name + Cerium + period + 6 + radioactive + False + state + Solid + symbol + Ce + vertPos + 9 + + + atomicNumber + 55 + atomicWeight + 132.90545 + discoveryYear + 1860 A.D. + group + 1 + horizPos + 1 + name + Cesium + period + 6 + radioactive + False + state + Solid + symbol + Cs + vertPos + 6 + + + atomicNumber + 17 + atomicWeight + 35.453 + discoveryYear + 1774 A.D. + group + 17 + horizPos + 17 + name + Chlorine + period + 3 + radioactive + False + state + Gas + symbol + Cl + vertPos + 3 + + + atomicNumber + 24 + atomicWeight + 51.9961 + discoveryYear + 1797 A.D. + group + 6 + horizPos + 6 + name + Chromium + period + 4 + radioactive + False + state + Solid + symbol + Cr + vertPos + 4 + + + atomicNumber + 27 + atomicWeight + 58.9332 + discoveryYear + 1735 A.D. + group + 9 + horizPos + 9 + name + Cobalt + period + 4 + radioactive + False + state + Solid + symbol + Co + vertPos + 4 + + + atomicNumber + 29 + atomicWeight + 63.546 + discoveryYear + Prehistoric + group + 11 + horizPos + 11 + name + Copper + period + 4 + radioactive + False + state + Solid + symbol + Cu + vertPos + 4 + + + atomicNumber + 96 + atomicWeight + 247 + discoveryYear + 1944 A.D. + group + 3 + horizPos + 11 + name + Curium + period + 7 + radioactive + True + state + Artificial + symbol + Cm + vertPos + 10 + + + atomicNumber + 105 + atomicWeight + 262 + discoveryYear + 1967 A.D. + group + 5 + horizPos + 5 + name + Dubnium + period + 7 + radioactive + True + state + Artificial + symbol + Db + vertPos + 7 + + + atomicNumber + 66 + atomicWeight + 162.5 + discoveryYear + 1886 A.D. + group + 3 + horizPos + 13 + name + Dysprosium + period + 6 + radioactive + False + state + Solid + symbol + Dy + vertPos + 9 + + + atomicNumber + 99 + atomicWeight + 252 + discoveryYear + 1952 A.D. + group + 3 + horizPos + 14 + name + Einsteinium + period + 7 + radioactive + True + state + Artificial + symbol + Es + vertPos + 10 + + + atomicNumber + 68 + atomicWeight + 167.259 + discoveryYear + 1842 A.D. + group + 3 + horizPos + 15 + name + Erbium + period + 6 + radioactive + False + state + Solid + symbol + Er + vertPos + 9 + + + atomicNumber + 63 + atomicWeight + 151.964 + discoveryYear + 1901 A.D. + group + 3 + horizPos + 10 + name + Europium + period + 6 + radioactive + False + state + Solid + symbol + Eu + vertPos + 9 + + + atomicNumber + 100 + atomicWeight + 257 + discoveryYear + 1952 A.D. + group + 3 + horizPos + 15 + name + Fermium + period + 7 + radioactive + True + state + Artificial + symbol + Fm + vertPos + 10 + + + atomicNumber + 9 + atomicWeight + 18.9984032 + discoveryYear + 1886 A.D. + group + 17 + horizPos + 17 + name + Fluorine + period + 2 + radioactive + False + state + Gas + symbol + F + vertPos + 2 + + + atomicNumber + 87 + atomicWeight + 223 + discoveryYear + 1939 A.D. + group + 1 + horizPos + 1 + name + Francium + period + 7 + radioactive + True + state + Solid + symbol + Fr + vertPos + 7 + + + atomicNumber + 64 + atomicWeight + 157.25 + discoveryYear + 1880 A.D. + group + 3 + horizPos + 11 + name + Gadolinium + period + 6 + radioactive + False + state + Solid + symbol + Gd + vertPos + 9 + + + atomicNumber + 31 + atomicWeight + 69.723 + discoveryYear + 1875 A.D. + group + 13 + horizPos + 13 + name + Gallium + period + 4 + radioactive + False + state + Solid + symbol + Ga + vertPos + 4 + + + atomicNumber + 32 + atomicWeight + 72.64 + discoveryYear + 1886 A.D. + group + 14 + horizPos + 14 + name + Germanium + period + 4 + radioactive + False + state + Solid + symbol + Ge + vertPos + 4 + + + atomicNumber + 79 + atomicWeight + 196.96655 + discoveryYear + Ancient + group + 11 + horizPos + 11 + name + Gold + period + 6 + radioactive + False + state + Solid + symbol + Au + vertPos + 6 + + + atomicNumber + 72 + atomicWeight + 178.49 + discoveryYear + 1923 A.D. + group + 4 + horizPos + 4 + name + Hafnium + period + 6 + radioactive + False + state + Solid + symbol + Hf + vertPos + 6 + + + atomicNumber + 108 + atomicWeight + 277 + discoveryYear + 1984 A.D. + group + 8 + horizPos + 8 + name + Hassium + period + 7 + radioactive + True + state + Artificial + symbol + Hs + vertPos + 7 + + + atomicNumber + 2 + atomicWeight + 4.002602 + discoveryYear + 1895 A.D. + group + 18 + horizPos + 18 + name + Helium + period + 1 + radioactive + False + state + Gas + symbol + He + vertPos + 1 + + + atomicNumber + 67 + atomicWeight + 164.93032 + discoveryYear + 1878 A.D. + group + 3 + horizPos + 14 + name + Holmium + period + 6 + radioactive + False + state + Solid + symbol + Ho + vertPos + 9 + + + atomicNumber + 1 + atomicWeight + 1.00794 + discoveryYear + 1766 A.D. + group + 1 + horizPos + 1 + name + Hydrogen + period + 1 + radioactive + False + state + Gas + symbol + H + vertPos + 1 + + + atomicNumber + 49 + atomicWeight + 114.818 + discoveryYear + 1863 A.D. + group + 13 + horizPos + 13 + name + Indium + period + 5 + radioactive + False + state + Solid + symbol + In + vertPos + 5 + + + atomicNumber + 53 + atomicWeight + 126.90447 + discoveryYear + 1811 A.D. + group + 17 + horizPos + 17 + name + Iodine + period + 5 + radioactive + False + state + Solid + symbol + I + vertPos + 5 + + + atomicNumber + 77 + atomicWeight + 192.217 + discoveryYear + 1803 A.D. + group + 9 + horizPos + 9 + name + Iridium + period + 6 + radioactive + False + state + Solid + symbol + Ir + vertPos + 6 + + + atomicNumber + 26 + atomicWeight + 55.845 + discoveryYear + Prehistoric + group + 8 + horizPos + 8 + name + Iron + period + 4 + radioactive + False + state + Solid + symbol + Fe + vertPos + 4 + + + atomicNumber + 36 + atomicWeight + 83.798 + discoveryYear + 1898 A.D. + group + 18 + horizPos + 18 + name + Krypton + period + 4 + radioactive + False + state + Gas + symbol + Kr + vertPos + 4 + + + atomicNumber + 57 + atomicWeight + 138.9055 + discoveryYear + 1839 A.D. + group + 3 + horizPos + 4 + name + Lanthanum + period + 6 + radioactive + False + state + Solid + symbol + La + vertPos + 9 + + + atomicNumber + 103 + atomicWeight + 262 + discoveryYear + 1961 A.D. + group + 3 + horizPos + 18 + name + Lawrencium + period + 7 + radioactive + True + state + Artificial + symbol + Lr + vertPos + 10 + + + atomicNumber + 82 + atomicWeight + 207.2 + discoveryYear + Ancient + group + 14 + horizPos + 14 + name + Lead + period + 6 + radioactive + False + state + Solid + symbol + Pb + vertPos + 6 + + + atomicNumber + 3 + atomicWeight + 6.941 + discoveryYear + 1817 A.D. + group + 1 + horizPos + 1 + name + Lithium + period + 2 + radioactive + False + state + Solid + symbol + Li + vertPos + 2 + + + atomicNumber + 71 + atomicWeight + 174.967 + discoveryYear + 1907 A.D. + group + 3 + horizPos + 18 + name + Lutetium + period + 6 + radioactive + False + state + Solid + symbol + Lu + vertPos + 9 + + + atomicNumber + 12 + atomicWeight + 24.3050 + discoveryYear + 1755 A.D. + group + 2 + horizPos + 2 + name + Magnesium + period + 3 + radioactive + False + state + Solid + symbol + Mg + vertPos + 3 + + + atomicNumber + 25 + atomicWeight + 54.938049 + discoveryYear + 1774 A.D. + group + 7 + horizPos + 7 + name + Manganese + period + 4 + radioactive + False + state + Solid + symbol + Mn + vertPos + 4 + + + atomicNumber + 109 + atomicWeight + 268 + discoveryYear + 1982 A.D. + group + 9 + horizPos + 9 + name + Meitnerium + period + 7 + radioactive + True + state + Artificial + symbol + Mt + vertPos + 7 + + + atomicNumber + 101 + atomicWeight + 258 + discoveryYear + 1955 A.D. + group + 3 + horizPos + 16 + name + Mendelevium + period + 7 + radioactive + True + state + Artificial + symbol + Md + vertPos + 10 + + + atomicNumber + 80 + atomicWeight + 200.59 + discoveryYear + Ancient + group + 12 + horizPos + 12 + name + Mercury + period + 6 + radioactive + False + state + Liquid + symbol + Hg + vertPos + 6 + + + atomicNumber + 42 + atomicWeight + 95.94 + discoveryYear + 1781 A.D. + group + 6 + horizPos + 6 + name + Molybdenum + period + 5 + radioactive + False + state + Solid + symbol + Mo + vertPos + 5 + + + atomicNumber + 60 + atomicWeight + 144.24 + discoveryYear + 1885 A.D. + group + 3 + horizPos + 7 + name + Neodymium + period + 6 + radioactive + False + state + Solid + symbol + Nd + vertPos + 9 + + + atomicNumber + 10 + atomicWeight + 20.1797 + discoveryYear + 1898 A.D. + group + 18 + horizPos + 18 + name + Neon + period + 2 + radioactive + False + state + Gas + symbol + Ne + vertPos + 2 + + + atomicNumber + 93 + atomicWeight + 237 + discoveryYear + 1940 A.D. + group + 3 + horizPos + 8 + name + Neptunium + period + 7 + radioactive + True + state + Artificial + symbol + Np + vertPos + 10 + + + atomicNumber + 28 + atomicWeight + 58.6934 + discoveryYear + 1751 A.D. + group + 10 + horizPos + 10 + name + Nickel + period + 4 + radioactive + False + state + Solid + symbol + Ni + vertPos + 4 + + + atomicNumber + 41 + atomicWeight + 92.90638 + discoveryYear + 1801 A.D. + group + 5 + horizPos + 5 + name + Niobium + period + 5 + radioactive + False + state + Solid + symbol + Nb + vertPos + 5 + + + atomicNumber + 7 + atomicWeight + 14.0067 + discoveryYear + 1772 A.D. + group + 15 + horizPos + 15 + name + Nitrogen + period + 2 + radioactive + False + state + Gas + symbol + N + vertPos + 2 + + + atomicNumber + 102 + atomicWeight + 259 + discoveryYear + 1958 A.D. + group + 3 + horizPos + 17 + name + Nobelium + period + 7 + radioactive + True + state + Artificial + symbol + No + vertPos + 10 + + + atomicNumber + 76 + atomicWeight + 190.23 + discoveryYear + 1803 A.D. + group + 8 + horizPos + 8 + name + Osmium + period + 6 + radioactive + False + state + Solid + symbol + Os + vertPos + 6 + + + atomicNumber + 8 + atomicWeight + 15.9994 + discoveryYear + 1774 A.D. + group + 16 + horizPos + 16 + name + Oxygen + period + 2 + radioactive + False + state + Gas + symbol + O + vertPos + 2 + + + atomicNumber + 46 + atomicWeight + 106.42 + discoveryYear + 1803 A.D. + group + 10 + horizPos + 10 + name + Palladium + period + 5 + radioactive + False + state + Solid + symbol + Pd + vertPos + 5 + + + atomicNumber + 15 + atomicWeight + 30.973761 + discoveryYear + 1669 A.D. + group + 15 + horizPos + 15 + name + Phosphorus + period + 3 + radioactive + False + state + Solid + symbol + P + vertPos + 3 + + + atomicNumber + 78 + atomicWeight + 195.078 + discoveryYear + 1735 A.D. + group + 10 + horizPos + 10 + name + Platinum + period + 6 + radioactive + False + state + Solid + symbol + Pt + vertPos + 6 + + + atomicNumber + 94 + atomicWeight + 244 + discoveryYear + 1940 A.D. + group + 3 + horizPos + 9 + name + Plutonium + period + 7 + radioactive + True + state + Artificial + symbol + Pu + vertPos + 10 + + + atomicNumber + 84 + atomicWeight + 209 + discoveryYear + 1898 A.D. + group + 16 + horizPos + 16 + name + Polonium + period + 6 + radioactive + True + state + Solid + symbol + Po + vertPos + 6 + + + atomicNumber + 19 + atomicWeight + 39.0983 + discoveryYear + 1807 A.D. + group + 1 + horizPos + 1 + name + Potassium + period + 4 + radioactive + False + state + Solid + symbol + K + vertPos + 4 + + + atomicNumber + 59 + atomicWeight + 140.90765 + discoveryYear + 1885 A.D. + group + 3 + horizPos + 6 + name + Praseodymium + period + 6 + radioactive + False + state + Solid + symbol + Pr + vertPos + 9 + + + atomicNumber + 61 + atomicWeight + 145 + discoveryYear + 1945 A.D. + group + 3 + horizPos + 8 + name + Promethium + period + 6 + radioactive + True + state + Artificial + symbol + Pm + vertPos + 9 + + + atomicNumber + 91 + atomicWeight + 231.03588 + discoveryYear + 1913 A.D. + group + 3 + horizPos + 6 + name + Protactinium + period + 7 + radioactive + True + state + Solid + symbol + Pa + vertPos + 10 + + + atomicNumber + 88 + atomicWeight + 226 + discoveryYear + 1898 A.D. + group + 2 + horizPos + 2 + name + Radium + period + 7 + radioactive + True + state + Solid + symbol + Ra + vertPos + 7 + + + atomicNumber + 86 + atomicWeight + 222 + discoveryYear + 1900 A.D. + group + 18 + horizPos + 18 + name + Radon + period + 6 + radioactive + True + state + Gas + symbol + Rn + vertPos + 6 + + + atomicNumber + 75 + atomicWeight + 186.207 + discoveryYear + 1925 A.D. + group + 7 + horizPos + 7 + name + Rhenium + period + 6 + radioactive + False + state + Solid + symbol + Re + vertPos + 6 + + + atomicNumber + 45 + atomicWeight + 102.90550 + discoveryYear + 1803 A.D. + group + 9 + horizPos + 9 + name + Rhodium + period + 5 + radioactive + False + state + Solid + symbol + Rh + vertPos + 5 + + + atomicNumber + 37 + atomicWeight + 85.4678 + discoveryYear + 1861 A.D. + group + 1 + horizPos + 1 + name + Rubidium + period + 5 + radioactive + False + state + Solid + symbol + Rb + vertPos + 5 + + + atomicNumber + 44 + atomicWeight + 101.07 + discoveryYear + 1844 A.D. + group + 8 + horizPos + 8 + name + Ruthenium + period + 5 + radioactive + False + state + Solid + symbol + Ru + vertPos + 5 + + + atomicNumber + 104 + atomicWeight + 261 + discoveryYear + 1964 A.D. + group + 4 + horizPos + 4 + name + Rutherfordium + period + 7 + radioactive + True + state + Artificial + symbol + Rf + vertPos + 7 + + + atomicNumber + 62 + atomicWeight + 150.36 + discoveryYear + 1879 A.D. + group + 3 + horizPos + 9 + name + Samarium + period + 6 + radioactive + False + state + Solid + symbol + Sm + vertPos + 9 + + + atomicNumber + 21 + atomicWeight + 44.955910 + discoveryYear + 1879 A.D. + group + 3 + horizPos + 3 + name + Scandium + period + 4 + radioactive + False + state + Solid + symbol + Sc + vertPos + 4 + + + atomicNumber + 106 + atomicWeight + 266 + discoveryYear + 1974 A.D. + group + 6 + horizPos + 6 + name + Seaborgium + period + 7 + radioactive + True + state + Artificial + symbol + Sg + vertPos + 7 + + + atomicNumber + 34 + atomicWeight + 78.96 + discoveryYear + 1817 A.D. + group + 16 + horizPos + 16 + name + Selenium + period + 4 + radioactive + False + state + Solid + symbol + Se + vertPos + 4 + + + atomicNumber + 14 + atomicWeight + 28.0855 + discoveryYear + 1824 A.D. + group + 14 + horizPos + 14 + name + Silicon + period + 3 + radioactive + False + state + Solid + symbol + Si + vertPos + 3 + + + atomicNumber + 47 + atomicWeight + 107.8682 + discoveryYear + Ancient + group + 11 + horizPos + 11 + name + Silver + period + 5 + radioactive + False + state + Solid + symbol + Ag + vertPos + 5 + + + atomicNumber + 11 + atomicWeight + 22.989770 + discoveryYear + 1807 A.D. + group + 1 + horizPos + 1 + name + Sodium + period + 3 + radioactive + False + state + Solid + symbol + Na + vertPos + 3 + + + atomicNumber + 38 + atomicWeight + 87.62 + discoveryYear + 1790 A.D. + group + 2 + horizPos + 2 + name + Strontium + period + 5 + radioactive + False + state + Solid + symbol + Sr + vertPos + 5 + + + atomicNumber + 16 + atomicWeight + 32.065 + discoveryYear + Ancient + group + 16 + horizPos + 16 + name + Sulfur + period + 3 + radioactive + False + state + Solid + symbol + S + vertPos + 3 + + + atomicNumber + 73 + atomicWeight + 180.9479 + discoveryYear + 1802 A.D. + group + 5 + horizPos + 5 + name + Tantalum + period + 6 + radioactive + False + state + Solid + symbol + Ta + vertPos + 6 + + + atomicNumber + 43 + atomicWeight + 98 + discoveryYear + 1937 A.D. + group + 7 + horizPos + 7 + name + Technetium + period + 5 + radioactive + True + state + Artificial + symbol + Tc + vertPos + 5 + + + atomicNumber + 52 + atomicWeight + 127.60 + discoveryYear + 1783 A.D. + group + 16 + horizPos + 16 + name + Tellurium + period + 5 + radioactive + False + state + Solid + symbol + Te + vertPos + 5 + + + atomicNumber + 65 + atomicWeight + 158.92534 + discoveryYear + 1843 A.D. + group + 3 + horizPos + 12 + name + Terbium + period + 6 + radioactive + False + state + Solid + symbol + Tb + vertPos + 9 + + + atomicNumber + 81 + atomicWeight + 204.3833 + discoveryYear + 1861 A.D. + group + 13 + horizPos + 13 + name + Thallium + period + 6 + radioactive + False + state + Solid + symbol + Tl + vertPos + 6 + + + atomicNumber + 90 + atomicWeight + 232.0381 + discoveryYear + 1829 A.D. + group + 3 + horizPos + 5 + name + Thorium + period + 7 + radioactive + True + state + Solid + symbol + Th + vertPos + 10 + + + atomicNumber + 69 + atomicWeight + 168.93421 + discoveryYear + 1879 A.D. + group + 3 + horizPos + 16 + name + Thulium + period + 6 + radioactive + False + state + Solid + symbol + Tm + vertPos + 9 + + + atomicNumber + 50 + atomicWeight + 118.710 + discoveryYear + Ancient + group + 14 + horizPos + 14 + name + Tin + period + 5 + radioactive + False + state + Solid + symbol + Sn + vertPos + 5 + + + atomicNumber + 22 + atomicWeight + 47.867 + discoveryYear + 1791 A.D. + group + 4 + horizPos + 4 + name + Titanium + period + 4 + radioactive + False + state + Solid + symbol + Ti + vertPos + 4 + + + atomicNumber + 74 + atomicWeight + 183.84 + discoveryYear + 1783 A.D. + group + 6 + horizPos + 6 + name + Tungsten + period + 6 + radioactive + False + state + Solid + symbol + W + vertPos + 6 + + + atomicNumber + 112 + atomicWeight + 285 + discoveryYear + 1996 A.D. + group + 12 + horizPos + 12 + name + Ununbium + period + 7 + radioactive + True + state + Artificial + symbol + Uub + vertPos + 7 + + + atomicNumber + 116 + atomicWeight + 292 + discoveryYear + 2000 A.D. + group + 16 + horizPos + 16 + name + Ununhexium + period + 7 + radioactive + True + state + Artificial + symbol + Uuh + vertPos + 7 + + + atomicNumber + 110 + atomicWeight + 281 + discoveryYear + 1994 A.D. + group + 10 + horizPos + 10 + name + Ununnilium + period + 7 + radioactive + True + state + Artificial + symbol + Uun + vertPos + 7 + + + atomicNumber + 118 + atomicWeight + 294 + discoveryYear + 2006 A.D. + group + 18 + horizPos + 18 + name + Ununoctium + period + 7 + radioactive + True + state + Artificial + symbol + Uuo + vertPos + 7 + + + atomicNumber + 115 + atomicWeight + 288 + discoveryYear + 2004 A.D. + group + 15 + horizPos + 15 + name + Ununpentium + period + 7 + radioactive + True + state + Artificial + symbol + Uup + vertPos + 7 + + + atomicNumber + 114 + atomicWeight + 289 + discoveryYear + 1998 A.D. + group + 14 + horizPos + 14 + name + Ununquadium + period + 7 + radioactive + True + state + Artificial + symbol + Uuq + vertPos + 7 + + + atomicNumber + 117 + atomicWeight + [Unknown] + discoveryYear + [Undiscovered] + group + 17 + horizPos + 17 + name + Ununseptium + period + 7 + radioactive + True + state + Artificial + symbol + Uus + vertPos + 7 + + + atomicNumber + 113 + atomicWeight + 284 + discoveryYear + 2004 A.D. + group + 13 + horizPos + 13 + name + Ununtrium + period + 7 + radioactive + True + state + Artificial + symbol + Uut + vertPos + 7 + + + atomicNumber + 111 + atomicWeight + 272 + discoveryYear + 1994 A.D. + group + 11 + horizPos + 11 + name + Unununium + period + 7 + radioactive + True + state + Artificial + symbol + Uuu + vertPos + 7 + + + atomicNumber + 92 + atomicWeight + 238.02891 + discoveryYear + 1789 A.D. + group + 3 + horizPos + 7 + name + Uranium + period + 7 + radioactive + True + state + Solid + symbol + U + vertPos + 10 + + + atomicNumber + 23 + atomicWeight + 50.9415 + discoveryYear + 1801 A.D. + group + 5 + horizPos + 5 + name + Vanadium + period + 4 + radioactive + False + state + Solid + symbol + V + vertPos + 4 + + + atomicNumber + 54 + atomicWeight + 131.293 + discoveryYear + 1898 A.D. + group + 18 + horizPos + 18 + name + Xenon + period + 5 + radioactive + False + state + Gas + symbol + Xe + vertPos + 5 + + + atomicNumber + 70 + atomicWeight + 173.04 + discoveryYear + 1878 A.D. + group + 3 + horizPos + 17 + name + Ytterbium + period + 6 + radioactive + False + state + Solid + symbol + Yb + vertPos + 9 + + + atomicNumber + 39 + atomicWeight + 88.90585 + discoveryYear + 1794 A.D. + group + 3 + horizPos + 3 + name + Yttrium + period + 5 + radioactive + False + state + Solid + symbol + Y + vertPos + 5 + + + atomicNumber + 30 + atomicWeight + 65.409 + discoveryYear + 1500 A.D. + group + 12 + horizPos + 12 + name + Zinc + period + 4 + radioactive + False + state + Solid + symbol + Zn + vertPos + 4 + + + atomicNumber + 40 + atomicWeight + 91.224 + discoveryYear + 1789 A.D. + group + 4 + horizPos + 4 + name + Zirconium + period + 5 + radioactive + False + state + Solid + symbol + Zr + vertPos + 5 + + + diff --git a/TheElements/Images/ApplicationFlow.png b/TheElements/Images/ApplicationFlow.png new file mode 100644 index 0000000..d9eeb46 Binary files /dev/null and b/TheElements/Images/ApplicationFlow.png differ diff --git a/TheElements/Images/Artificial_24.png b/TheElements/Images/Artificial_24.png new file mode 100644 index 0000000..b404a9c Binary files /dev/null and b/TheElements/Images/Artificial_24.png differ diff --git a/TheElements/Images/Artificial_256.png b/TheElements/Images/Artificial_256.png new file mode 100644 index 0000000..77def9c Binary files /dev/null and b/TheElements/Images/Artificial_256.png differ diff --git a/TheElements/Images/Artificial_30.png b/TheElements/Images/Artificial_30.png new file mode 100644 index 0000000..6884521 Binary files /dev/null and b/TheElements/Images/Artificial_30.png differ diff --git a/TheElements/Images/Artificial_37.png b/TheElements/Images/Artificial_37.png new file mode 100644 index 0000000..a55ce42 Binary files /dev/null and b/TheElements/Images/Artificial_37.png differ diff --git a/TheElements/Images/Default.png b/TheElements/Images/Default.png new file mode 100644 index 0000000..e84a197 Binary files /dev/null and b/TheElements/Images/Default.png differ diff --git a/TheElements/Images/Gas_24.png b/TheElements/Images/Gas_24.png new file mode 100644 index 0000000..e55ffac Binary files /dev/null and b/TheElements/Images/Gas_24.png differ diff --git a/TheElements/Images/Gas_256.png b/TheElements/Images/Gas_256.png new file mode 100644 index 0000000..77038bd Binary files /dev/null and b/TheElements/Images/Gas_256.png differ diff --git a/TheElements/Images/Gas_30.png b/TheElements/Images/Gas_30.png new file mode 100644 index 0000000..03ffd92 Binary files /dev/null and b/TheElements/Images/Gas_30.png differ diff --git a/TheElements/Images/Gas_37.png b/TheElements/Images/Gas_37.png new file mode 100644 index 0000000..1c6face Binary files /dev/null and b/TheElements/Images/Gas_37.png differ diff --git a/TheElements/Images/Icon-72.png b/TheElements/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TheElements/Images/Icon-72.png differ diff --git a/TheElements/Images/Icon-Small-50.png b/TheElements/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TheElements/Images/Icon-Small-50.png differ diff --git a/TheElements/Images/Icon-Small.png b/TheElements/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TheElements/Images/Icon-Small.png differ diff --git a/TheElements/Images/Icon-Small@2x.png b/TheElements/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TheElements/Images/Icon-Small@2x.png differ diff --git a/TheElements/Images/Icon.png b/TheElements/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TheElements/Images/Icon.png differ diff --git a/TheElements/Images/Icon@2x.png b/TheElements/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TheElements/Images/Icon@2x.png differ diff --git a/TheElements/Images/Liquid_24.png b/TheElements/Images/Liquid_24.png new file mode 100644 index 0000000..ac81dcc Binary files /dev/null and b/TheElements/Images/Liquid_24.png differ diff --git a/TheElements/Images/Liquid_256.png b/TheElements/Images/Liquid_256.png new file mode 100644 index 0000000..7261c97 Binary files /dev/null and b/TheElements/Images/Liquid_256.png differ diff --git a/TheElements/Images/Liquid_30.png b/TheElements/Images/Liquid_30.png new file mode 100644 index 0000000..79449a6 Binary files /dev/null and b/TheElements/Images/Liquid_30.png differ diff --git a/TheElements/Images/Liquid_37.png b/TheElements/Images/Liquid_37.png new file mode 100644 index 0000000..d547a0c Binary files /dev/null and b/TheElements/Images/Liquid_37.png differ diff --git a/TheElements/Images/Solid_24.png b/TheElements/Images/Solid_24.png new file mode 100644 index 0000000..df0f540 Binary files /dev/null and b/TheElements/Images/Solid_24.png differ diff --git a/TheElements/Images/Solid_256.png b/TheElements/Images/Solid_256.png new file mode 100644 index 0000000..072c8a2 Binary files /dev/null and b/TheElements/Images/Solid_256.png differ diff --git a/TheElements/Images/Solid_30.png b/TheElements/Images/Solid_30.png new file mode 100644 index 0000000..eb704ef Binary files /dev/null and b/TheElements/Images/Solid_30.png differ diff --git a/TheElements/Images/Solid_37.png b/TheElements/Images/Solid_37.png new file mode 100644 index 0000000..0d6adac Binary files /dev/null and b/TheElements/Images/Solid_37.png differ diff --git a/TheElements/Images/buttonsWithSpacing.png b/TheElements/Images/buttonsWithSpacing.png new file mode 100644 index 0000000..34676a7 Binary files /dev/null and b/TheElements/Images/buttonsWithSpacing.png differ diff --git a/TheElements/Images/flipper_list_blue.png b/TheElements/Images/flipper_list_blue.png new file mode 100644 index 0000000..34d7dca Binary files /dev/null and b/TheElements/Images/flipper_list_blue.png differ diff --git a/TheElements/Images/iTunesArtwork b/TheElements/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TheElements/Images/iTunesArtwork differ diff --git a/TheElements/Images/name_gray.png b/TheElements/Images/name_gray.png new file mode 100644 index 0000000..82c3a75 Binary files /dev/null and b/TheElements/Images/name_gray.png differ diff --git a/TheElements/Images/number_gray.png b/TheElements/Images/number_gray.png new file mode 100644 index 0000000..8c345af Binary files /dev/null and b/TheElements/Images/number_gray.png differ diff --git a/TheElements/Images/state_gray.png b/TheElements/Images/state_gray.png new file mode 100644 index 0000000..17c1301 Binary files /dev/null and b/TheElements/Images/state_gray.png differ diff --git a/TheElements/Images/symbol_gray.png b/TheElements/Images/symbol_gray.png new file mode 100644 index 0000000..274372c Binary files /dev/null and b/TheElements/Images/symbol_gray.png differ diff --git a/TheElements/Images/table_gray.png b/TheElements/Images/table_gray.png new file mode 100644 index 0000000..b9baf3d Binary files /dev/null and b/TheElements/Images/table_gray.png differ diff --git a/TheElements/Info.plist b/TheElements/Info.plist new file mode 100644 index 0000000..e452a8c --- /dev/null +++ b/TheElements/Info.plist @@ -0,0 +1,35 @@ + + + + + LSRequiresIPhoneOS + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + TheElements + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.11 + + diff --git a/TheElements/Readme.txt b/TheElements/Readme.txt new file mode 100644 index 0000000..bd57a4f --- /dev/null +++ b/TheElements/Readme.txt @@ -0,0 +1,253 @@ +### TheElements ### + +================================================================================ +DESCRIPTION: + +TheElements is a sample application that provides access to the data contained in the Periodic Table of the Elements. The Periodic Table of the Elements catalogs all the known atomic elements in the universe. + +TheElements provides this data in multiple formats, allowing you to sort the data by name, atomic number, symbol name, and an elements physical state at room temperature. + +TheElements is structured as a Model-View-Controller application. There is +distinct separation of the model data, the views used to present that data, +and the controllers which act as a liaison between the model and controller. + +The application illustrates the following techniques: + + Configuring and responding to selections in a tab bar + Displaying information in a tableview using both plain and grouped style table views + Using navigation controllers to navigate deeper into a data structure + Subclassing UIView + Providing a custom UITableViewCell consisting of multiple subviews + Implementing the UITableViewDelegate protocol + Implementing the UITableViewDataSource protocol + Reacting to taps in views + Open a URL to an external web site using Safari + Flipping view content from front to back + Creating a reflection of a view in the interface + +TheElements is a fairly large application with many classes. This document +attempts to explain those classes and their roles in the application. + +To understand the flow of screens from one to the next when using the +application see the ApplicationFlow.pdf included with the project. + +================================================================================ +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +================================================================================ +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +================================================================================ +PACKAGING LIST: + +AtomicElement.h +AtomicElement.m + +The AtomicElement class encapsulates the data for a single atomic element. It +contains the name, atomic number, symbol, and state information, along with +layout information (horizontal and vertical positions). It returns the image +that represents the state of the object, which displayed in each visual +representation of an element. + +PeriodicTable.h +PeriodicTable.m + +The PeriodicTable class encapsulates the collection of AtomicElement +instances. It provides access to elements in a variety of formats: sorted +numerically, sorted by name, sorted by symbol, elements for an atomic state, +and elements that begin with a specific character. This data is pre-sorted and +indexed when the raw element information is read from the Elements.plist. The +PeriodicTable class is a singleton, there is one instance that is shared by +the entire application. + + +ElementsTableViewController.h +ElementsTableViewController.m + +ElementsTableViewController is the controller class that is used for each of +the four representations of the elements data that is displayed in UITableView +objects. There are four instances of this class created by the UIApplication +delegate when the application is launched. Each instance retains the an +instance of the appropriate Elements*DataSource object for its data +representation. This data source object also provides the images that the +UITabBarItem representing this view control use for display. + +The ElementsTableViewController is responsible for creating and configuring +instances of UITableView when requested. The ElementsTableViewController class +adopts the UITableViewDelegate protocol, agreeing to provide the cells for the +tableview. + +It provides instances of the custom table cell class ElementTableViewCell +pre-populated with the appropriate AtomicElement object when asked by the +UITableViewDelegate for the cell to be displayed for a row and section. + +As the UITableView delegate an instance of the ElementsTableViewController +class will also receive messages when a user taps on a row in the table view. +Upon receiving this event it asks its data source object for the AtomicElement +object that it represents and then instructs the navigation controller for the +view controller to push an instance of the AtomicElementViewController class +onto the navigation stack. + + +AtomicElementTableViewCell.h +AtomicElementTableViewCell.h + +Each row in a UITableView displays a custom table cell of the class +AtomicElementTableViewCell. This custom class displays a graphic indicating +the symbol, atomic number, and state of the element, as well as a text label +with the generally accepted name of the element. + +ElementsDataSourceProtocol.h +ElementsSortedByNameDataSource.h +ElementsSortedByNameDataSource.m +ElementsSortedByNumberDataSource.h +ElementsSortedByNumberDataSource.m +ElementsSortedBySymbolDataSource.h +ElementsSortedBySymbolDataSource.m +ElementsSortedByStateDataSource.h +ElementsSortedByStateDataSource.m + +The data source classes provide the data for the ElementsTableViewController, +the UITabBarItem, the UINavigationController and the UITableView that is +displayed within those views. There are four classes: +ElementsSortedByNameDataSource, ElementsSortedByAtomicNumberDataSource, +ElementsSortedBySymbolDataSource, and ElementsSortedByStateDataSource. + +These classes all adopt and implement the UITableViewDataSource protocol and +are set as the dataSource for the UITableView displayed for the data sorted in +each manner. As the table view requires data it sends messages to its +dataSource (one of these class instances) and that data is displayed. + +These classes also adopt the ElementsDataSource protocol. This protocol is +defined by the application and provides a uniform means for the +ElementsTableViewController to determine the title displayed in the tab bar +and navigation controller, the images displayed in the UITabBarItem for this +data representation, and the style the UITableView uses to display the data +(indexed or grouped depending on the sorted representation of the Periodic +Table data. + + +AtomicElementViewController.h +AtomicElementViewController.m + +When a user taps on a row in a UITableView listing a collection of elements +the table's delegate (ElementsTableViewController) receives a message. Upon +receiving this event the ElementsTableViewController asks its data source +object for the AtomicElement object that it represents and then instructs the +navigation controller for the view controller to push an instance of the +AtomicElementViewController class onto the navigation stack. + +The AtomicElementViewController is responsible for displaying the single +element view as a large tile. The initial view displayed is the +AtomicElementView. It is also responsible for ensuring that the flipper button +in the navigation bar shows that there is another view available for the +content by tapping on the tile. + + +AtomicElementView.h +AtomicElementView.m + +The AtomicElementView is displayed in the content of the +AtomicElementViewController. It displays the atomic name, number, symbol, and +state of the element. By tapping on the element the display will 'flip' to +show the AtomicElementFlippedView. + + +AtomicElementFlippedView.h +AtomicElementFlippedView.m + +This view displays the Atomic name, number, and state of the current element, +as well as a link to the appropriate page on Wikipedia. + +================================================================================ +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.11 + - Upgraded project to build with the iOS 4.0 SDK. + +Version 1.9 + - Changed the target setting's "Code Signing Identity" to the proper value. + +Version 1.8 + - Upgraded for 3.0 SDK due to deprecated APIs; in "cellForRowAtIndexPath" it now uses UITableViewCell's initWithStyle. + +Version 1.7 + - Updated for and tested with iPhone OS 2.0. First public release. + - Added additional date to the Element View + - Fixed memory leaks in reflection implementation + +Version 1.6 + - Updated with API changes for beta 6 relesae of iPhone OS SDK. + - The UITableViewDelegate method tableView: cellForRowAtIndexPath: was + moved to the UITableViewDataSource protocol. This resulted in a change to + the ElementsTableViewController class and each of the datasources. + +Version 1.5 + - Updated with API changes for beta 5 release of iPhone OS SDK. + +Version 1.4 + - Updated with API changes for beta 4 release of iPhone OS SDK. + - Added code signing. + - Subviews of cells should no longer be directly inserted into the cell + as a subview. Instead they should be interted into the contentView of + the cell. + - Remove layout computations based on contentRectForBounds: in AtomicElmentTableViewCell. + Instead the CGRect returned by self.contentRect.bounds is now used. + +Version 1.3 + - Updated with API changes for third beta release of iPhone + SDK + - Changed designated initializer in AtomicElementTableViewCell.m to + initWithFrame:reuseIdentifier: + - Changed cell creation mechanism in ElementsTableViewController.m + (see tableView:cellForRowAtIndexPath:) + - Removed tabBar from Single Element View using new + hidesBottomBarWhenPushed API (see init in + AtomicElementViewController.m) + - Added flipped indicator to navigation bar in Single Element View + mode. + - Shows a more indicator when the front of the element is shown, + shows a representation of the front of the element when the back + is shown + - Renamed various element background images to indicate pixel size + +Version 1.2 + - Updated with API changes for second beta release of iPhone SDK + - replaced toolbar references with tabBar references throughout. + - Single Element View mode should now hide the toolbar + automatically when it is displayed. + - New implementation of the view reflection in the Single Element + View mode. + - Now creates the reflected image programmatically. This eliminates + the cheat that included a pre-rendered vertically flipped button + image. + - Added a method to AtomicElementView class to return an image that + contains the reflected image for the view, including the gradient. + - This version is generic. It will work on any color background, + and requires no special images for the reflection. + - Should be reusable in most cases. + - See AtomicElementView.m for + reflectedImageRepresentationOfHeight:, the method that creates + the reflection image. See AtomicElementViewController.m for the + creation and management of the UIImageView that displays the + reflected image. + - Elements by Name table now displays alphabetical side index + - Side index is now displayed rather than disclosure icon + - Added new method to the ElementsDataSource protocol to return if + the disclosure icon should be displayed for a sorted mode + - See sectionIndexTitlesForTableView:and + tableView:sectionForSectionIndexTitle:atIndex: in + ElementsByNameDataSource.m + +Version 1.1 + - Initial release. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. + + + diff --git a/TheElements/TheElements.xcodeproj/project.pbxproj b/TheElements/TheElements.xcodeproj/project.pbxproj new file mode 100755 index 0000000..f9d7ed5 --- /dev/null +++ b/TheElements/TheElements.xcodeproj/project.pbxproj @@ -0,0 +1,570 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 18313FEE11CFCF7E00C521F1 /* ApplicationFlow.png in Resources */ = {isa = PBXBuildFile; fileRef = 18313FEC11CFCF7E00C521F1 /* ApplicationFlow.png */; }; + 18313FEF11CFCF7E00C521F1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 18313FED11CFCF7E00C521F1 /* Default.png */; }; + 18313FF111CFCFAB00C521F1 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18313FF011CFCFAB00C521F1 /* Icon.png */; }; + 1D3623260D0F684500981E51 /* TheElementsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* TheElementsAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2883B6A10D944613003F08B5 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2883B6A00D944613003F08B5 /* QuartzCore.framework */; }; + 53339B0A11D27E76007AD342 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 53339B0311D27E76007AD342 /* Icon-72.png */; }; + 53339B0B11D27E76007AD342 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 53339B0411D27E76007AD342 /* Icon-Small-50.png */; }; + 53339B0C11D27E76007AD342 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 53339B0511D27E76007AD342 /* Icon-Small.png */; }; + 53339B0D11D27E76007AD342 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53339B0611D27E76007AD342 /* Icon-Small@2x.png */; }; + 53339B0F11D27E76007AD342 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53339B0811D27E76007AD342 /* Icon@2x.png */; }; + 53339B1011D27E76007AD342 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 53339B0911D27E76007AD342 /* iTunesArtwork */; }; + C839ED3D0D9E0F270016B510 /* flipper_list_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = C839ED3C0D9E0F270016B510 /* flipper_list_blue.png */; }; + C844D0420D70BEBE002C7CFD /* AtomicElementFlippedView.m in Sources */ = {isa = PBXBuildFile; fileRef = C844D0410D70BEBE002C7CFD /* AtomicElementFlippedView.m */; }; + C8657C240D59017B00CB6FC9 /* Elements.plist in Resources */ = {isa = PBXBuildFile; fileRef = C8657C230D59017B00CB6FC9 /* Elements.plist */; }; + C87D9ED70D65203C006094E8 /* AtomicElementTileView.m in Sources */ = {isa = PBXBuildFile; fileRef = C87D9ED60D65203C006094E8 /* AtomicElementTileView.m */; }; + C8842F8B0D61528100816072 /* AtomicElementViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C8842F8A0D61528100816072 /* AtomicElementViewController.m */; }; + C89ACE760DA4A34F006AB9BA /* Gas_30.png in Resources */ = {isa = PBXBuildFile; fileRef = C89ACE750DA4A34F006AB9BA /* Gas_30.png */; }; + C89ACE780DA4A359006AB9BA /* Solid_30.png in Resources */ = {isa = PBXBuildFile; fileRef = C89ACE770DA4A359006AB9BA /* Solid_30.png */; }; + C89ACE7A0DA4A35E006AB9BA /* Liquid_30.png in Resources */ = {isa = PBXBuildFile; fileRef = C89ACE790DA4A35E006AB9BA /* Liquid_30.png */; }; + C89ACE7C0DA4A363006AB9BA /* Artificial_30.png in Resources */ = {isa = PBXBuildFile; fileRef = C89ACE7B0DA4A363006AB9BA /* Artificial_30.png */; }; + C8B477C70D626E3700EA3613 /* Artificial_37.png in Resources */ = {isa = PBXBuildFile; fileRef = C8B477C30D626E3700EA3613 /* Artificial_37.png */; }; + C8B477C80D626E3700EA3613 /* Gas_37.png in Resources */ = {isa = PBXBuildFile; fileRef = C8B477C40D626E3700EA3613 /* Gas_37.png */; }; + C8B477C90D626E3700EA3613 /* Liquid_37.png in Resources */ = {isa = PBXBuildFile; fileRef = C8B477C50D626E3700EA3613 /* Liquid_37.png */; }; + C8B477CA0D626E3700EA3613 /* Solid_37.png in Resources */ = {isa = PBXBuildFile; fileRef = C8B477C60D626E3700EA3613 /* Solid_37.png */; }; + C8B477EC0D62715A00EA3613 /* AtomicElementView.m in Sources */ = {isa = PBXBuildFile; fileRef = C8B477EB0D62715A00EA3613 /* AtomicElementView.m */; }; + C8DE42800D581B7B00AFE181 /* AtomicElement.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE42710D581B7B00AFE181 /* AtomicElement.m */; }; + C8DE42810D581B7B00AFE181 /* AtomicElementTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE42730D581B7B00AFE181 /* AtomicElementTableViewCell.m */; }; + C8DE42820D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE42750D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.m */; }; + C8DE42830D581B7B00AFE181 /* ElementsSortedByStateDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE42770D581B7B00AFE181 /* ElementsSortedByStateDataSource.m */; }; + C8DE42840D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE42790D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.m */; }; + C8DE42850D581B7B00AFE181 /* ElementsSortedByNameDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE427B0D581B7B00AFE181 /* ElementsSortedByNameDataSource.m */; }; + C8DE42860D581B7B00AFE181 /* PeriodicElements.m in Sources */ = {isa = PBXBuildFile; fileRef = C8DE427D0D581B7B00AFE181 /* PeriodicElements.m */; }; + C8E2AC6E0D5B7AAE0056EE5C /* Artificial_24.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC650D5B7AAE0056EE5C /* Artificial_24.png */; }; + C8E2AC6F0D5B7AAE0056EE5C /* Artificial_256.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC660D5B7AAE0056EE5C /* Artificial_256.png */; }; + C8E2AC710D5B7AAE0056EE5C /* Gas_24.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC680D5B7AAE0056EE5C /* Gas_24.png */; }; + C8E2AC720D5B7AAE0056EE5C /* Gas_256.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC690D5B7AAE0056EE5C /* Gas_256.png */; }; + C8E2AC730D5B7AAE0056EE5C /* Liquid_24.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC6A0D5B7AAE0056EE5C /* Liquid_24.png */; }; + C8E2AC740D5B7AAE0056EE5C /* Liquid_256.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC6B0D5B7AAE0056EE5C /* Liquid_256.png */; }; + C8E2AC750D5B7AAE0056EE5C /* Solid_24.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC6C0D5B7AAE0056EE5C /* Solid_24.png */; }; + C8E2AC760D5B7AAE0056EE5C /* Solid_256.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC6D0D5B7AAE0056EE5C /* Solid_256.png */; }; + C8E2AC820D5B7B290056EE5C /* name_gray.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC780D5B7B290056EE5C /* name_gray.png */; }; + C8E2AC840D5B7B290056EE5C /* number_gray.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC7A0D5B7B290056EE5C /* number_gray.png */; }; + C8E2AC860D5B7B290056EE5C /* state_gray.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC7C0D5B7B290056EE5C /* state_gray.png */; }; + C8E2AC880D5B7B290056EE5C /* symbol_gray.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC7E0D5B7B290056EE5C /* symbol_gray.png */; }; + C8E2AC8A0D5B7B290056EE5C /* table_gray.png in Resources */ = {isa = PBXBuildFile; fileRef = C8E2AC800D5B7B290056EE5C /* table_gray.png */; }; + C8E2ACA60D5B7C950056EE5C /* ElementsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C8E2ACA50D5B7C950056EE5C /* ElementsTableViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 18313FEC11CFCF7E00C521F1 /* ApplicationFlow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ApplicationFlow.png; sourceTree = ""; }; + 18313FED11CFCF7E00C521F1 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 18313FF011CFCFAB00C521F1 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* TheElementsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TheElementsAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* TheElementsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TheElementsAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* TheElements.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TheElements.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2883B6A00D944613003F08B5 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* TheElements_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TheElements_Prefix.pch; sourceTree = ""; }; + 53339B0311D27E76007AD342 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 53339B0411D27E76007AD342 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 53339B0511D27E76007AD342 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 53339B0611D27E76007AD342 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 53339B0811D27E76007AD342 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 53339B0911D27E76007AD342 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 53B194650FB4DD8100B35AC9 /* Readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Readme.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C81948510D623D4E00632525 /* ElementsDataSourceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementsDataSourceProtocol.h; sourceTree = ""; }; + C839ED3C0D9E0F270016B510 /* flipper_list_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flipper_list_blue.png; sourceTree = ""; }; + C844D0400D70BEBE002C7CFD /* AtomicElementFlippedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicElementFlippedView.h; sourceTree = ""; }; + C844D0410D70BEBE002C7CFD /* AtomicElementFlippedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtomicElementFlippedView.m; sourceTree = ""; }; + C8657C230D59017B00CB6FC9 /* Elements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Elements.plist; sourceTree = ""; }; + C87B586D0DA580910072D2B4 /* Readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Readme.txt; sourceTree = ""; }; + C87D9ED50D65203C006094E8 /* AtomicElementTileView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicElementTileView.h; sourceTree = ""; }; + C87D9ED60D65203C006094E8 /* AtomicElementTileView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtomicElementTileView.m; sourceTree = ""; }; + C8842F890D61528100816072 /* AtomicElementViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicElementViewController.h; sourceTree = ""; }; + C8842F8A0D61528100816072 /* AtomicElementViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtomicElementViewController.m; sourceTree = ""; }; + C89ACE750DA4A34F006AB9BA /* Gas_30.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gas_30.png; sourceTree = ""; }; + C89ACE770DA4A359006AB9BA /* Solid_30.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Solid_30.png; sourceTree = ""; }; + C89ACE790DA4A35E006AB9BA /* Liquid_30.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Liquid_30.png; sourceTree = ""; }; + C89ACE7B0DA4A363006AB9BA /* Artificial_30.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Artificial_30.png; sourceTree = ""; }; + C8B477C30D626E3700EA3613 /* Artificial_37.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Artificial_37.png; sourceTree = ""; }; + C8B477C40D626E3700EA3613 /* Gas_37.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gas_37.png; sourceTree = ""; }; + C8B477C50D626E3700EA3613 /* Liquid_37.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Liquid_37.png; sourceTree = ""; }; + C8B477C60D626E3700EA3613 /* Solid_37.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Solid_37.png; sourceTree = ""; }; + C8B477EA0D62715A00EA3613 /* AtomicElementView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicElementView.h; sourceTree = ""; }; + C8B477EB0D62715A00EA3613 /* AtomicElementView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtomicElementView.m; sourceTree = ""; }; + C8DE42700D581B7B00AFE181 /* AtomicElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicElement.h; sourceTree = ""; }; + C8DE42710D581B7B00AFE181 /* AtomicElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtomicElement.m; sourceTree = ""; }; + C8DE42720D581B7B00AFE181 /* AtomicElementTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicElementTableViewCell.h; sourceTree = ""; }; + C8DE42730D581B7B00AFE181 /* AtomicElementTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AtomicElementTableViewCell.m; sourceTree = ""; }; + C8DE42740D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementsSortedByAtomicNumberDataSource.h; sourceTree = ""; }; + C8DE42750D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ElementsSortedByAtomicNumberDataSource.m; sourceTree = ""; }; + C8DE42760D581B7B00AFE181 /* ElementsSortedByStateDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementsSortedByStateDataSource.h; sourceTree = ""; }; + C8DE42770D581B7B00AFE181 /* ElementsSortedByStateDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ElementsSortedByStateDataSource.m; sourceTree = ""; }; + C8DE42780D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementsSortedBySymbolDataSource.h; sourceTree = ""; }; + C8DE42790D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ElementsSortedBySymbolDataSource.m; sourceTree = ""; }; + C8DE427A0D581B7B00AFE181 /* ElementsSortedByNameDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementsSortedByNameDataSource.h; sourceTree = ""; }; + C8DE427B0D581B7B00AFE181 /* ElementsSortedByNameDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ElementsSortedByNameDataSource.m; sourceTree = ""; }; + C8DE427C0D581B7B00AFE181 /* PeriodicElements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeriodicElements.h; sourceTree = ""; }; + C8DE427D0D581B7B00AFE181 /* PeriodicElements.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PeriodicElements.m; sourceTree = ""; }; + C8E2AC650D5B7AAE0056EE5C /* Artificial_24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Artificial_24.png; sourceTree = ""; }; + C8E2AC660D5B7AAE0056EE5C /* Artificial_256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Artificial_256.png; sourceTree = ""; }; + C8E2AC680D5B7AAE0056EE5C /* Gas_24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gas_24.png; sourceTree = ""; }; + C8E2AC690D5B7AAE0056EE5C /* Gas_256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gas_256.png; sourceTree = ""; }; + C8E2AC6A0D5B7AAE0056EE5C /* Liquid_24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Liquid_24.png; sourceTree = ""; }; + C8E2AC6B0D5B7AAE0056EE5C /* Liquid_256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Liquid_256.png; sourceTree = ""; }; + C8E2AC6C0D5B7AAE0056EE5C /* Solid_24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Solid_24.png; sourceTree = ""; }; + C8E2AC6D0D5B7AAE0056EE5C /* Solid_256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Solid_256.png; sourceTree = ""; }; + C8E2AC780D5B7B290056EE5C /* name_gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = name_gray.png; sourceTree = ""; }; + C8E2AC7A0D5B7B290056EE5C /* number_gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = number_gray.png; sourceTree = ""; }; + C8E2AC7C0D5B7B290056EE5C /* state_gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = state_gray.png; sourceTree = ""; }; + C8E2AC7E0D5B7B290056EE5C /* symbol_gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = symbol_gray.png; sourceTree = ""; }; + C8E2AC800D5B7B290056EE5C /* table_gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = table_gray.png; sourceTree = ""; }; + C8E2ACA40D5B7C950056EE5C /* ElementsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementsTableViewController.h; sourceTree = ""; }; + C8E2ACA50D5B7C950056EE5C /* ElementsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ElementsTableViewController.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 2883B6A10D944613003F08B5 /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + C8842F8D0D61532D00816072 /* Single Element View */, + C8285CEE0D5A4CB10036A28A /* TableView Representations */, + C83CD92A0D5822910066AE4B /* Data Model */, + C83CD92C0D5822C30066AE4B /* Application Support */, + ); + path = Classes; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 2883B6A00D944613003F08B5 /* QuartzCore.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* TheElements.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53B194650FB4DD8100B35AC9 /* Readme.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + C81A17C90D66590100E26CF7 /* ReadMe and Other Documentation */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* TheElements_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + C8E2AC640D5B7AAE0056EE5C /* Images */, + C8657C230D59017B00CB6FC9 /* Elements.plist */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + C819486C0D623ED800632525 /* Data Sources */ = { + isa = PBXGroup; + children = ( + C81948510D623D4E00632525 /* ElementsDataSourceProtocol.h */, + C8DE427A0D581B7B00AFE181 /* ElementsSortedByNameDataSource.h */, + C8DE427B0D581B7B00AFE181 /* ElementsSortedByNameDataSource.m */, + C8DE42740D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.h */, + C8DE42750D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.m */, + C8DE42780D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.h */, + C8DE42790D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.m */, + C8DE42760D581B7B00AFE181 /* ElementsSortedByStateDataSource.h */, + C8DE42770D581B7B00AFE181 /* ElementsSortedByStateDataSource.m */, + ); + name = "Data Sources"; + sourceTree = ""; + }; + C81A17C90D66590100E26CF7 /* ReadMe and Other Documentation */ = { + isa = PBXGroup; + children = ( + C87B586D0DA580910072D2B4 /* Readme.txt */, + ); + name = "ReadMe and Other Documentation"; + sourceTree = ""; + }; + C8285CEE0D5A4CB10036A28A /* TableView Representations */ = { + isa = PBXGroup; + children = ( + C83CD92B0D5822A80066AE4B /* View Controllers */, + C83CD9290D58227B0066AE4B /* User Interface Elements */, + C819486C0D623ED800632525 /* Data Sources */, + ); + name = "TableView Representations"; + sourceTree = ""; + }; + C83CD9290D58227B0066AE4B /* User Interface Elements */ = { + isa = PBXGroup; + children = ( + C87D9ED50D65203C006094E8 /* AtomicElementTileView.h */, + C87D9ED60D65203C006094E8 /* AtomicElementTileView.m */, + C8DE42720D581B7B00AFE181 /* AtomicElementTableViewCell.h */, + C8DE42730D581B7B00AFE181 /* AtomicElementTableViewCell.m */, + ); + name = "User Interface Elements"; + sourceTree = ""; + }; + C83CD92A0D5822910066AE4B /* Data Model */ = { + isa = PBXGroup; + children = ( + C8DE42700D581B7B00AFE181 /* AtomicElement.h */, + C8DE42710D581B7B00AFE181 /* AtomicElement.m */, + C8DE427C0D581B7B00AFE181 /* PeriodicElements.h */, + C8DE427D0D581B7B00AFE181 /* PeriodicElements.m */, + ); + name = "Data Model"; + sourceTree = ""; + }; + C83CD92B0D5822A80066AE4B /* View Controllers */ = { + isa = PBXGroup; + children = ( + C8E2ACA40D5B7C950056EE5C /* ElementsTableViewController.h */, + C8E2ACA50D5B7C950056EE5C /* ElementsTableViewController.m */, + ); + name = "View Controllers"; + sourceTree = ""; + }; + C83CD92C0D5822C30066AE4B /* Application Support */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* TheElementsAppDelegate.h */, + 1D3623250D0F684500981E51 /* TheElementsAppDelegate.m */, + ); + name = "Application Support"; + sourceTree = ""; + }; + C8842F8D0D61532D00816072 /* Single Element View */ = { + isa = PBXGroup; + children = ( + C8842F8E0D61534F00816072 /* View Controllers */, + C8B477E50D62713400EA3613 /* User Interface Elements */, + ); + name = "Single Element View"; + sourceTree = ""; + }; + C8842F8E0D61534F00816072 /* View Controllers */ = { + isa = PBXGroup; + children = ( + C8842F890D61528100816072 /* AtomicElementViewController.h */, + C8842F8A0D61528100816072 /* AtomicElementViewController.m */, + ); + name = "View Controllers"; + sourceTree = ""; + }; + C8B477E50D62713400EA3613 /* User Interface Elements */ = { + isa = PBXGroup; + children = ( + C8B477EA0D62715A00EA3613 /* AtomicElementView.h */, + C8B477EB0D62715A00EA3613 /* AtomicElementView.m */, + C844D0400D70BEBE002C7CFD /* AtomicElementFlippedView.h */, + C844D0410D70BEBE002C7CFD /* AtomicElementFlippedView.m */, + ); + name = "User Interface Elements"; + sourceTree = ""; + }; + C8B477EE0D6271EC00EA3613 /* Tab Bar Images */ = { + isa = PBXGroup; + children = ( + C8E2AC780D5B7B290056EE5C /* name_gray.png */, + C8E2AC7A0D5B7B290056EE5C /* number_gray.png */, + C8E2AC7C0D5B7B290056EE5C /* state_gray.png */, + C8E2AC7E0D5B7B290056EE5C /* symbol_gray.png */, + C8E2AC800D5B7B290056EE5C /* table_gray.png */, + ); + name = "Tab Bar Images"; + sourceTree = ""; + }; + C8B477EF0D62720A00EA3613 /* Element Backgrounds */ = { + isa = PBXGroup; + children = ( + C8B477C30D626E3700EA3613 /* Artificial_37.png */, + C89ACE750DA4A34F006AB9BA /* Gas_30.png */, + C89ACE770DA4A359006AB9BA /* Solid_30.png */, + C89ACE7B0DA4A363006AB9BA /* Artificial_30.png */, + C89ACE790DA4A35E006AB9BA /* Liquid_30.png */, + C8B477C40D626E3700EA3613 /* Gas_37.png */, + C8B477C50D626E3700EA3613 /* Liquid_37.png */, + C8B477C60D626E3700EA3613 /* Solid_37.png */, + C8E2AC650D5B7AAE0056EE5C /* Artificial_24.png */, + C8E2AC660D5B7AAE0056EE5C /* Artificial_256.png */, + C8E2AC680D5B7AAE0056EE5C /* Gas_24.png */, + C8E2AC690D5B7AAE0056EE5C /* Gas_256.png */, + C8E2AC6A0D5B7AAE0056EE5C /* Liquid_24.png */, + C8E2AC6B0D5B7AAE0056EE5C /* Liquid_256.png */, + C8E2AC6C0D5B7AAE0056EE5C /* Solid_24.png */, + C8E2AC6D0D5B7AAE0056EE5C /* Solid_256.png */, + ); + name = "Element Backgrounds"; + sourceTree = ""; + }; + C8E2AC640D5B7AAE0056EE5C /* Images */ = { + isa = PBXGroup; + children = ( + 18313FF011CFCFAB00C521F1 /* Icon.png */, + 53339B0311D27E76007AD342 /* Icon-72.png */, + 53339B0411D27E76007AD342 /* Icon-Small-50.png */, + 53339B0511D27E76007AD342 /* Icon-Small.png */, + 53339B0611D27E76007AD342 /* Icon-Small@2x.png */, + 53339B0811D27E76007AD342 /* Icon@2x.png */, + 53339B0911D27E76007AD342 /* iTunesArtwork */, + 18313FEC11CFCF7E00C521F1 /* ApplicationFlow.png */, + 18313FED11CFCF7E00C521F1 /* Default.png */, + C839ED3C0D9E0F270016B510 /* flipper_list_blue.png */, + C8B477EE0D6271EC00EA3613 /* Tab Bar Images */, + C8B477EF0D62720A00EA3613 /* Element Backgrounds */, + ); + path = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* TheElements */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TheElements" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TheElements; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* TheElements.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TheElements" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* TheElements */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C8657C240D59017B00CB6FC9 /* Elements.plist in Resources */, + C8E2AC6E0D5B7AAE0056EE5C /* Artificial_24.png in Resources */, + C8E2AC6F0D5B7AAE0056EE5C /* Artificial_256.png in Resources */, + C8E2AC710D5B7AAE0056EE5C /* Gas_24.png in Resources */, + C8E2AC720D5B7AAE0056EE5C /* Gas_256.png in Resources */, + C8E2AC730D5B7AAE0056EE5C /* Liquid_24.png in Resources */, + C8E2AC740D5B7AAE0056EE5C /* Liquid_256.png in Resources */, + C8E2AC750D5B7AAE0056EE5C /* Solid_24.png in Resources */, + C8E2AC760D5B7AAE0056EE5C /* Solid_256.png in Resources */, + C8E2AC820D5B7B290056EE5C /* name_gray.png in Resources */, + C8E2AC840D5B7B290056EE5C /* number_gray.png in Resources */, + C8E2AC860D5B7B290056EE5C /* state_gray.png in Resources */, + C8E2AC880D5B7B290056EE5C /* symbol_gray.png in Resources */, + C8E2AC8A0D5B7B290056EE5C /* table_gray.png in Resources */, + C8B477C70D626E3700EA3613 /* Artificial_37.png in Resources */, + C8B477C80D626E3700EA3613 /* Gas_37.png in Resources */, + C8B477C90D626E3700EA3613 /* Liquid_37.png in Resources */, + C8B477CA0D626E3700EA3613 /* Solid_37.png in Resources */, + C839ED3D0D9E0F270016B510 /* flipper_list_blue.png in Resources */, + C89ACE760DA4A34F006AB9BA /* Gas_30.png in Resources */, + C89ACE780DA4A359006AB9BA /* Solid_30.png in Resources */, + C89ACE7A0DA4A35E006AB9BA /* Liquid_30.png in Resources */, + C89ACE7C0DA4A363006AB9BA /* Artificial_30.png in Resources */, + 18313FEE11CFCF7E00C521F1 /* ApplicationFlow.png in Resources */, + 18313FEF11CFCF7E00C521F1 /* Default.png in Resources */, + 18313FF111CFCFAB00C521F1 /* Icon.png in Resources */, + 53339B0A11D27E76007AD342 /* Icon-72.png in Resources */, + 53339B0B11D27E76007AD342 /* Icon-Small-50.png in Resources */, + 53339B0C11D27E76007AD342 /* Icon-Small.png in Resources */, + 53339B0D11D27E76007AD342 /* Icon-Small@2x.png in Resources */, + 53339B0F11D27E76007AD342 /* Icon@2x.png in Resources */, + 53339B1011D27E76007AD342 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* TheElementsAppDelegate.m in Sources */, + C8DE42800D581B7B00AFE181 /* AtomicElement.m in Sources */, + C8DE42810D581B7B00AFE181 /* AtomicElementTableViewCell.m in Sources */, + C8DE42820D581B7B00AFE181 /* ElementsSortedByAtomicNumberDataSource.m in Sources */, + C8DE42830D581B7B00AFE181 /* ElementsSortedByStateDataSource.m in Sources */, + C8DE42840D581B7B00AFE181 /* ElementsSortedBySymbolDataSource.m in Sources */, + C8DE42850D581B7B00AFE181 /* ElementsSortedByNameDataSource.m in Sources */, + C8DE42860D581B7B00AFE181 /* PeriodicElements.m in Sources */, + C8E2ACA60D5B7C950056EE5C /* ElementsTableViewController.m in Sources */, + C8842F8B0D61528100816072 /* AtomicElementViewController.m in Sources */, + C8B477EC0D62715A00EA3613 /* AtomicElementView.m in Sources */, + C87D9ED70D65203C006094E8 /* AtomicElementTileView.m in Sources */, + C844D0420D70BEBE002C7CFD /* AtomicElementFlippedView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = TheElements_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Applications; + PREBINDING = NO; + PRODUCT_NAME = TheElements; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = TheElements_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Applications; + PREBINDING = NO; + PRODUCT_NAME = TheElements; + PROVISIONING_PROFILE = ""; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TheElements" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TheElements" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TheElements/TheElements_Prefix.pch b/TheElements/TheElements_Prefix.pch new file mode 100644 index 0000000..68766ad --- /dev/null +++ b/TheElements/TheElements_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'TheElements' target in the 'TheElements' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TheElements/main.m b/TheElements/main.m new file mode 100644 index 0000000..4639c88 --- /dev/null +++ b/TheElements/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: This file is included for support purposes and isn't necessary for understanding this sample. + Version: 1.11 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"TheElementsAppDelegate"); + [pool release]; + return retVal; +} diff --git a/TouchCells.zip b/TouchCells.zip new file mode 100644 index 0000000..a3041c4 Binary files /dev/null and b/TouchCells.zip differ diff --git a/TouchCells/AppDelegate.h b/TouchCells/AppDelegate.h new file mode 100755 index 0000000..05882d8 --- /dev/null +++ b/TouchCells/AppDelegate.h @@ -0,0 +1,65 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for installing our table view controller. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class DetailViewController; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navController; + DetailViewController *detailViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navController; +@property (nonatomic, retain) DetailViewController *detailViewController; + +- (void)showDetail:(NSDictionary *)detail; + +@end diff --git a/TouchCells/AppDelegate.m b/TouchCells/AppDelegate.m new file mode 100755 index 0000000..42bf551 --- /dev/null +++ b/TouchCells/AppDelegate.m @@ -0,0 +1,100 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for installing our table view controller. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MyTableViewController.h" +#import "DetailViewController.h" + +@implementation AppDelegate; + +@synthesize window, navController, detailViewController; + +- (void)dealloc +{ + [window release]; + [navController release]; + [detailViewController release]; + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; + detailViewController.loadView; + + [window addSubview:navController.view]; + [window makeKeyAndVisible]; +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + //.. +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +- (void)showDetail:(NSDictionary *)detail +{ + // make the image frame size the same as the image size + UIImage *checkImage = [UIImage imageNamed:@"checked.png"]; + CGRect finalFrame = detailViewController.checkedImage.frame; + finalFrame.size.width = checkImage.size.width; + finalFrame.size.height = checkImage.size.height; + detailViewController.checkedImage.frame = finalFrame; + + detailViewController.itemTitle.text = [detail objectForKey:@"text"]; + BOOL checked = [[detail objectForKey:@"checked"] boolValue]; + detailViewController.checkedImage.image = (checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"]; + + [self.navController pushViewController:detailViewController animated:YES]; +} + +@end diff --git a/TouchCells/CustomCell.h b/TouchCells/CustomCell.h new file mode 100755 index 0000000..761f68f --- /dev/null +++ b/TouchCells/CustomCell.h @@ -0,0 +1,63 @@ +/* + File: CustomCell.h + Abstract: The custom UITableViewCell for holding the checkmark button. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface CustomCell : UITableViewCell +{ + BOOL checked; + NSString *title; + + UIButton *checkButton; +} + +@property (nonatomic, retain) NSString *title; +@property (nonatomic, assign) BOOL checked; + +- (void)checkAction:(id)sender; + +@end diff --git a/TouchCells/CustomCell.m b/TouchCells/CustomCell.m new file mode 100755 index 0000000..2c1a364 --- /dev/null +++ b/TouchCells/CustomCell.m @@ -0,0 +1,114 @@ +/* + File: CustomCell.m + Abstract: The custom UITableViewCell for holding the checkmark button. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "CustomCell.h" + +@implementation CustomCell + +@synthesize checked, title; + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) + { + self.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; + + // cell's title label + self.textLabel.backgroundColor = self.backgroundColor; + self.textLabel.opaque = NO; + self.textLabel.textColor = [UIColor blackColor]; + self.textLabel.highlightedTextColor = [UIColor whiteColor]; + self.textLabel.font = [UIFont boldSystemFontOfSize:18.0]; + + // cell's check button + checkButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + checkButton.frame = CGRectZero; + checkButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + checkButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; + [checkButton addTarget:self action:@selector(checkAction:) forControlEvents:UIControlEventTouchDown]; + checkButton.backgroundColor = self.backgroundColor; + [self.contentView addSubview:checkButton]; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGRect contentRect = [self.contentView bounds]; + + CGRect frame = CGRectMake(contentRect.origin.x + 40.0, 8.0, contentRect.size.width, 30.0); + self.textLabel.frame = frame; + + // layout the check button image + UIImage *checkedImage = [UIImage imageNamed:@"checked.png"]; + frame = CGRectMake(contentRect.origin.x + 10.0, 12.0, checkedImage.size.width, checkedImage.size.height); + checkButton.frame = frame; + + UIImage *image = (self.checked) ? checkedImage: [UIImage imageNamed:@"unchecked.png"]; + UIImage *newImage = [image stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + [checkButton setBackgroundImage:newImage forState:UIControlStateNormal]; +} + +- (void)dealloc +{ + [checkButton release]; + [title release]; + [super dealloc]; +} + +// called when the checkmark button is touched +- (void)checkAction:(id)sender +{ + // note: we don't use 'sender' because this action method can be called separate from the button (i.e. from table selection) + self.checked = !self.checked; + UIImage *checkImage = (self.checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"]; + [checkButton setImage:checkImage forState:UIControlStateNormal]; +} + +@end diff --git a/TouchCells/DetailViewController.h b/TouchCells/DetailViewController.h new file mode 100644 index 0000000..d56d342 --- /dev/null +++ b/TouchCells/DetailViewController.h @@ -0,0 +1,59 @@ +/* + File: DetailViewController.h + Abstract: The custom ViewController for showing detailed information on each table row. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface DetailViewController : UIViewController +{ + UILabel *itemTitle; + UIImageView *checkedImage; +} + +@property (nonatomic, retain) IBOutlet UILabel *itemTitle; +@property (nonatomic, retain) IBOutlet UIImageView *checkedImage; + +@end diff --git a/TouchCells/DetailViewController.m b/TouchCells/DetailViewController.m new file mode 100644 index 0000000..9978091 --- /dev/null +++ b/TouchCells/DetailViewController.m @@ -0,0 +1,64 @@ +/* + File: DetailViewController.m + Abstract: The custom ViewController for showing detailed information on each table row. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "DetailViewController.h" + +@implementation DetailViewController + +@synthesize itemTitle, checkedImage; + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +- (void)dealloc +{ + [super dealloc]; +} + +@end diff --git a/TouchCells/Info.plist b/TouchCells/Info.plist new file mode 100755 index 0000000..5e07209 --- /dev/null +++ b/TouchCells/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.4 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/TouchCells/MyTableViewController.h b/TouchCells/MyTableViewController.h new file mode 100644 index 0000000..53621bf --- /dev/null +++ b/TouchCells/MyTableViewController.h @@ -0,0 +1,55 @@ +/* + File: MyTableViewController.h + Abstract: The main table view controller of this app. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface MyTableViewController : UITableViewController +{ + NSMutableArray *dataArray; +} + +@end diff --git a/TouchCells/MyTableViewController.m b/TouchCells/MyTableViewController.m new file mode 100644 index 0000000..afd951c --- /dev/null +++ b/TouchCells/MyTableViewController.m @@ -0,0 +1,156 @@ +/* + File: MyTableViewController.m + Abstract: The main table view controller of this app. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyTableViewController.h" +#import "CustomCell.h" +#import "AppDelegate.h" + +@interface MyTableViewController () +@property (nonatomic, retain) NSMutableArray *dataArray; +@end + +@implementation MyTableViewController + +@synthesize dataArray; + +- (void)viewDidLoad +{ + // load our data from a plist file inside our app bundle + NSString *path = [[NSBundle mainBundle] pathForResource:@"tableData" ofType:@"plist"]; + self.dataArray = [NSMutableArray arrayWithContentsOfFile:path]; +} + +- (void)viewDidUnload +{ + // release the array + self.dataArray = nil; +} + +- (void)dealloc +{ + [dataArray release]; + [super dealloc]; +} + + +#pragma mark - UIViewController delegate methods + +- (void)didReceiveMemoryWarning +{ + // invoke super's implementation to do the Right Thing, but also release the input controller since we can do that + // In practice this is unlikely to be used in this application, and it would be of little benefit, + // but the principle is the important thing. + // + [super didReceiveMemoryWarning]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + + +#pragma mark - UITableView delegate methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.dataArray count]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + // find the cell being touched and update its checked/unchecked image + CustomCell *targetCustomCell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath]; + [targetCustomCell checkAction:nil]; + + // don't keep the table selection + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + // update our data source array with the new checked state + NSMutableDictionary *selectedItem = [self.dataArray objectAtIndex:indexPath.row]; + [selectedItem setObject:[NSNumber numberWithBool:targetCustomCell.checked] forKey:@"checked"]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *kCustomCellID = @"MyCellID"; + + CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:kCustomCellID]; + if (cell == nil) + { + cell = (CustomCell *)[[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCustomCellID] autorelease]; + } + + NSDictionary *item = [dataArray objectAtIndex:indexPath.row]; + NSString* title = [item objectForKey:@"text"]; + cell.title = title; + cell.textLabel.text = title; + cell.checked = [[item objectForKey:@"checked"] boolValue]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath +{ + // called when the accessory view (disclosure button) is touched + CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath]; + + AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; + NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys: + cell.title, @"text", + [NSNumber numberWithBool:cell.checked], @"checked", + nil]; + [appDelegate showDetail:infoDict]; +} + +@end + diff --git a/TouchCells/Prefix.pch b/TouchCells/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/TouchCells/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TouchCells/ReadMe.txt b/TouchCells/ReadMe.txt new file mode 100644 index 0000000..cc14e53 --- /dev/null +++ b/TouchCells/ReadMe.txt @@ -0,0 +1,37 @@ +TouchCells + +Demonstrates how to implement trackable-settable UIControls embedded in a UITableView. This approach is handy if an application already uses its accessory view to the right of the table cell, but still wants a check mark view that supports toggling states of individual row items. The green check mark on the left provides this need which is trackable (checked/unchecked) independent of table selection. This is a similar user interface to that of Mail's Inbox table where mail items can be individually checked and unchecked for deletion. + +It implements a custom UITableViewCell and embeds a UIButton of type "UIButtonTypeCustom". The button has a target/action so that its appearance can be changed from checked to unchecked. The check/uncheck state is stored as a BOOL property inside the custom UITableViewCell, available for the table view controller. If an entire table row is touched, the delegate "didSelectRowAtIndexPath" will call the action method of that cell's button. + + +Build Requirements +iOS 4.0 SDK + + +Runtime Requirements +iPhone OS 3.2 or later + + +Using the Sample +Launch the TouchCells project using Xcode 3.1.3 or later. + +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. When launched, touch the check mark on the left of each table row to make it appear checked, touch again to uncheck it. Optionally you can select the entire row to check that item as well. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application's delegate to setup its window and content. +MyTableViewController.h/.m - The main UITableViewController. +DetailViewController.h/.m - A separate detail screen used to respond to taps of the accessory to the right. +CustomCell.h/.m - A subclass of UITableViewCell containing the UIButton for its checked/unchecked state. + + +Changes from Previous Versions +1.0 - First release. +1.1 - Fixed bug in that selection did not change NSArray data source; data source now originates from a plist. +1.2 - Adopted iPhone OS 3.0 UITableView and UITableViewCell APIs. +1.3 - Upgraded project to build with the iOS 4.0 SDK. +1.4 - Added CFBundleIconFiles in Info.plist. + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/TouchCells/TouchCells.xcodeproj/project.pbxproj b/TouchCells/TouchCells.xcodeproj/project.pbxproj new file mode 100755 index 0000000..baa66f8 --- /dev/null +++ b/TouchCells/TouchCells.xcodeproj/project.pbxproj @@ -0,0 +1,343 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 18247F5C11D924A00022009F /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18247F5B11D924A00022009F /* iTunesArtwork */; }; + 18C0CB2411D15B7700499C10 /* checked.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB1A11D15B7700499C10 /* checked.png */; }; + 18C0CB2511D15B7700499C10 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB1B11D15B7700499C10 /* Default.png */; }; + 18C0CB2611D15B7700499C10 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB1C11D15B7700499C10 /* Icon-72.png */; }; + 18C0CB2711D15B7700499C10 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB1D11D15B7700499C10 /* Icon-Small-50.png */; }; + 18C0CB2811D15B7700499C10 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB1E11D15B7700499C10 /* Icon-Small.png */; }; + 18C0CB2911D15B7700499C10 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB1F11D15B7700499C10 /* Icon-Small@2x.png */; }; + 18C0CB2A11D15B7700499C10 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB2011D15B7700499C10 /* Icon.png */; }; + 18C0CB2B11D15B7700499C10 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB2111D15B7700499C10 /* Icon@2x.png */; }; + 18C0CB2D11D15B7700499C10 /* unchecked.png in Resources */ = {isa = PBXBuildFile; fileRef = 18C0CB2311D15B7700499C10 /* unchecked.png */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF30D9C4D1A00F143AD /* AppDelegate.m */; }; + 5309602E0D9C4E0800F143AD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5309602D0D9C4E0800F143AD /* QuartzCore.framework */; }; + 5309C95B0EED8367001636AB /* tableData.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5309C95A0EED8367001636AB /* tableData.plist */; }; + 53743DB80E5A3E33006E6D4D /* CustomCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 53743DB60E5A3E33006E6D4D /* CustomCell.m */; }; + 53743E2D0E5A475E006E6D4D /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53743E2C0E5A475E006E6D4D /* DetailViewController.m */; }; + 539DD9CD0E5A538B00748D45 /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 539DD9CB0E5A538B00748D45 /* DetailViewController.xib */; }; + 53A7B2750E311095003A40F3 /* MyTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A7B2730E311095003A40F3 /* MyTableViewController.m */; }; + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EACC050DDA319F00908D73 /* MainWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 18247F5B11D924A00022009F /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 18C0CB1A11D15B7700499C10 /* checked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = checked.png; path = images/checked.png; sourceTree = ""; }; + 18C0CB1B11D15B7700499C10 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 18C0CB1C11D15B7700499C10 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18C0CB1D11D15B7700499C10 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18C0CB1E11D15B7700499C10 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18C0CB1F11D15B7700499C10 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18C0CB2011D15B7700499C10 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18C0CB2111D15B7700499C10 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18C0CB2311D15B7700499C10 /* unchecked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = unchecked.png; path = images/unchecked.png; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* TouchCells.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TouchCells.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53095FEF0D9C4D0500F143AD /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5309602D0D9C4E0800F143AD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 5309C95A0EED8367001636AB /* tableData.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = tableData.plist; sourceTree = ""; }; + 53743DB60E5A3E33006E6D4D /* CustomCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomCell.m; sourceTree = ""; }; + 53743DB70E5A3E33006E6D4D /* CustomCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomCell.h; sourceTree = ""; }; + 53743E2B0E5A475E006E6D4D /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + 53743E2C0E5A475E006E6D4D /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; + 539DD9CC0E5A538B00748D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController.xib; sourceTree = ""; }; + 53A7B2730E311095003A40F3 /* MyTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTableViewController.m; sourceTree = ""; }; + 53A7B2740E311095003A40F3 /* MyTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTableViewController.h; sourceTree = ""; }; + 53EACC060DDA319F00908D73 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 53F7EFC80E5B2CDC00963339 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 5309602E0D9C4E0800F143AD /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* TouchCells.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 53F7EFC80E5B2CDC00963339 /* ReadMe.txt */, + 53AF8AEC0D9C50B700726DBA /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18247F5B11D924A00022009F /* iTunesArtwork */, + 18C0CB1A11D15B7700499C10 /* checked.png */, + 18C0CB1B11D15B7700499C10 /* Default.png */, + 18C0CB1C11D15B7700499C10 /* Icon-72.png */, + 18C0CB1D11D15B7700499C10 /* Icon-Small-50.png */, + 18C0CB1E11D15B7700499C10 /* Icon-Small.png */, + 18C0CB1F11D15B7700499C10 /* Icon-Small@2x.png */, + 18C0CB2011D15B7700499C10 /* Icon.png */, + 18C0CB2111D15B7700499C10 /* Icon@2x.png */, + 18C0CB2311D15B7700499C10 /* unchecked.png */, + 5309C95A0EED8367001636AB /* tableData.plist */, + 8D1107310486CEB800E47090 /* Info.plist */, + 539DD9CB0E5A538B00748D45 /* DetailViewController.xib */, + 53EACC050DDA319F00908D73 /* MainWindow.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5309602D0D9C4E0800F143AD /* QuartzCore.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53AF8AEC0D9C50B700726DBA /* Sources */ = { + isa = PBXGroup; + children = ( + 53095FEF0D9C4D0500F143AD /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */, + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */, + 53A7B2740E311095003A40F3 /* MyTableViewController.h */, + 53A7B2730E311095003A40F3 /* MyTableViewController.m */, + 53743E2B0E5A475E006E6D4D /* DetailViewController.h */, + 53743E2C0E5A475E006E6D4D /* DetailViewController.m */, + 53743DB70E5A3E33006E6D4D /* CustomCell.h */, + 53743DB60E5A3E33006E6D4D /* CustomCell.m */, + ); + name = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* TouchCells */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TouchCells" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TouchCells; + productName = IBTest; + productReference = 1D6058910D05DD3D006BFB54 /* TouchCells.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TouchCells" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* TouchCells */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */, + 539DD9CD0E5A538B00748D45 /* DetailViewController.xib in Resources */, + 5309C95B0EED8367001636AB /* tableData.plist in Resources */, + 18C0CB2411D15B7700499C10 /* checked.png in Resources */, + 18C0CB2511D15B7700499C10 /* Default.png in Resources */, + 18C0CB2611D15B7700499C10 /* Icon-72.png in Resources */, + 18C0CB2711D15B7700499C10 /* Icon-Small-50.png in Resources */, + 18C0CB2811D15B7700499C10 /* Icon-Small.png in Resources */, + 18C0CB2911D15B7700499C10 /* Icon-Small@2x.png in Resources */, + 18C0CB2A11D15B7700499C10 /* Icon.png in Resources */, + 18C0CB2B11D15B7700499C10 /* Icon@2x.png in Resources */, + 18C0CB2D11D15B7700499C10 /* unchecked.png in Resources */, + 18247F5C11D924A00022009F /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */, + 53A7B2750E311095003A40F3 /* MyTableViewController.m in Sources */, + 53743DB80E5A3E33006E6D4D /* CustomCell.m in Sources */, + 53743E2D0E5A475E006E6D4D /* DetailViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 539DD9CB0E5A538B00748D45 /* DetailViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 539DD9CC0E5A538B00748D45 /* en */, + ); + name = DetailViewController.xib; + sourceTree = ""; + }; + 53EACC050DDA319F00908D73 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53EACC060DDA319F00908D73 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + PRODUCT_NAME = TouchCells; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + PRODUCT_NAME = TouchCells; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphonesimulator4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphonesimulator4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TouchCells" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TouchCells" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TouchCells/en.lproj/DetailViewController.xib b/TouchCells/en.lproj/DetailViewController.xib new file mode 100644 index 0000000..d34add1 --- /dev/null +++ b/TouchCells/en.lproj/DetailViewController.xib @@ -0,0 +1,226 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 292 + {{19, 22}, {22, 23}} + + NO + NO + 4 + NO + + + + 294 + {{49, 22}, {240, 21}} + + NO + YES + NO + + + 1 + MCAwIDAAA + + + 1 + 1.000000e+01 + + + {320, 460} + + + 3 + MQA + + 2 + + + NO + + + + + YES + + + itemTitle + + + + 88 + + + + view + + + + 89 + + + + checkedImage + + + + 90 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 61 + + + YES + + + + + + + 64 + + + + + 81 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 61.IBEditorWindowLastContentRect + 61.IBPluginDependency + 61.IBViewEditorWindowController.showingLayoutRectangles + 64.IBPluginDependency + 81.IBPluginDependency + + + YES + DetailViewController + UIResponder + {{0, 535}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 90 + + + + YES + + DetailViewController + UIViewController + + YES + + YES + checkedImage + itemTitle + + + YES + UIImageView + UILabel + + + + IBProjectSource + DetailViewController.h + + + + + 0 + ../TouchCells.xcodeproj + 3 + + diff --git a/TouchCells/en.lproj/MainWindow.xib b/TouchCells/en.lproj/MainWindow.xib new file mode 100644 index 0000000..b0ee954 --- /dev/null +++ b/TouchCells/en.lproj/MainWindow.xib @@ -0,0 +1,349 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + DetailViewController + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + MyTableViewController + + + 274 + {320, 416} + + NO + YES + NO + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + TouchCells + + + + + + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + delegate + + + + 57 + + + + dataSource + + + + 58 + + + + navController + + + + 74 + + + + + YES + + 0 + + YES + + + + + + 2 + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 60 + + + YES + + + DetailViewController + + + 70 + + + YES + + + + + + + 72 + + + + + 55 + + + YES + + + + + MyTableViewController + + + 56 + + + + + 75 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 55.CustomClassName + 55.IBEditorWindowLastContentRect + 55.IBPluginDependency + 56.IBPluginDependency + 60.CustomClassName + 60.IBEditorWindowLastContentRect + 60.IBPluginDependency + 60.IBViewEditorWindowController.showingLayoutRectangles + 70.IBEditorWindowLastContentRect + 70.IBPluginDependency + 72.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyTableViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + DetailViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 85 + + + + YES + + AppDelegate + NSObject + + YES + + YES + navController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + DetailViewController + UIViewController + + YES + + YES + checkedImage + itemTitle + + + YES + UIImageView + UILabel + + + + IBProjectSource + DetailViewController.h + + + + MyTableViewController + UITableViewController + + IBProjectSource + MyTableViewController.h + + + + + 0 + ../TouchCells.xcodeproj + 3 + + diff --git a/TouchCells/images/Default.png b/TouchCells/images/Default.png new file mode 100644 index 0000000..9ba0913 Binary files /dev/null and b/TouchCells/images/Default.png differ diff --git a/TouchCells/images/Icon-72.png b/TouchCells/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TouchCells/images/Icon-72.png differ diff --git a/TouchCells/images/Icon-Small-50.png b/TouchCells/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TouchCells/images/Icon-Small-50.png differ diff --git a/TouchCells/images/Icon-Small.png b/TouchCells/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TouchCells/images/Icon-Small.png differ diff --git a/TouchCells/images/Icon-Small@2x.png b/TouchCells/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TouchCells/images/Icon-Small@2x.png differ diff --git a/TouchCells/images/Icon.png b/TouchCells/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TouchCells/images/Icon.png differ diff --git a/TouchCells/images/Icon@2x.png b/TouchCells/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TouchCells/images/Icon@2x.png differ diff --git a/TouchCells/images/checked.png b/TouchCells/images/checked.png new file mode 100644 index 0000000..716d993 Binary files /dev/null and b/TouchCells/images/checked.png differ diff --git a/TouchCells/images/iTunesArtwork b/TouchCells/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TouchCells/images/iTunesArtwork differ diff --git a/TouchCells/images/unchecked.png b/TouchCells/images/unchecked.png new file mode 100644 index 0000000..95d9323 Binary files /dev/null and b/TouchCells/images/unchecked.png differ diff --git a/TouchCells/main.m b/TouchCells/main.m new file mode 100755 index 0000000..b460855 --- /dev/null +++ b/TouchCells/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/TouchCells/tableData.plist b/TouchCells/tableData.plist new file mode 100755 index 0000000..aece749 --- /dev/null +++ b/TouchCells/tableData.plist @@ -0,0 +1,43 @@ + + + + + + + text + Mac Pro + checked + + + + text + Mac Mini + checked + + + + text + iMac + checked + + + + text + MacBook + checked + + + + text + MacBook Pro + checked + + + + text + MacBook Air + checked + + + + diff --git a/TransWeb.zip b/TransWeb.zip new file mode 100644 index 0000000..2233c57 Binary files /dev/null and b/TransWeb.zip differ diff --git a/TransWeb/AppDelegate.h b/TransWeb/AppDelegate.h new file mode 100755 index 0000000..387900c --- /dev/null +++ b/TransWeb/AppDelegate.h @@ -0,0 +1,59 @@ +/* + File: AppDelegate.h + Abstract: The application delegate class used for installing our navigation controller. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *myNavController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *myNavController; + +@end diff --git a/TransWeb/AppDelegate.m b/TransWeb/AppDelegate.m new file mode 100755 index 0000000..f447413 --- /dev/null +++ b/TransWeb/AppDelegate.m @@ -0,0 +1,70 @@ +/* + File: AppDelegate.m + Abstract: The application delegate class used for installing our navigation controller. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" + +@implementation AppDelegate; + +@synthesize window, myNavController; + +- (void)dealloc +{ + [myNavController release]; + [window release]; + + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // create window and set up table view controller + [window addSubview:myNavController.view]; + + [window makeKeyAndVisible]; +} + +@end diff --git a/TransWeb/Info.plist b/TransWeb/Info.plist new file mode 100755 index 0000000..3120bd5 --- /dev/null +++ b/TransWeb/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon-72.png + Icon@2x.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.4 + NSMainNibFile + MainWindow + LSRequiresIPhoneOS + + + diff --git a/TransWeb/MyViewController.h b/TransWeb/MyViewController.h new file mode 100644 index 0000000..fd5bfd7 --- /dev/null +++ b/TransWeb/MyViewController.h @@ -0,0 +1,57 @@ +/* + File: MyViewController.h + Abstract: The main view controller of this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface MyViewController : UIViewController +{ + UIWebView *webView; +} + +@property (nonatomic, retain) IBOutlet UIWebView *webView; + +@end diff --git a/TransWeb/MyViewController.m b/TransWeb/MyViewController.m new file mode 100644 index 0000000..5572b97 --- /dev/null +++ b/TransWeb/MyViewController.m @@ -0,0 +1,80 @@ +/* + File: MyViewController.m + Abstract: The main view controller of this app. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MyViewController.h" + +@implementation MyViewController + +@synthesize webView; + +- (void)viewDidLoad +{ + NSString *path = [[NSBundle mainBundle] pathForResource:@"webViewContent" ofType:@"html"]; + NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:path]; + + NSString *htmlString = [[NSString alloc] initWithData: + [readHandle readDataToEndOfFile] encoding:NSUTF8StringEncoding]; + + // to make html content transparent to its parent view - + // 1) set the webview's backgroundColor property to [UIColor clearColor] + // 2) use the content in the html: + // 3) opaque property set to NO + // + webView.opaque = NO; + webView.backgroundColor = [UIColor clearColor]; + [self.webView loadHTMLString:htmlString baseURL:nil]; + [htmlString release]; +} + +- (void)dealloc +{ + [webView release]; + [super dealloc]; +} + +@end + diff --git a/TransWeb/Prefix.pch b/TransWeb/Prefix.pch new file mode 100755 index 0000000..a17209c --- /dev/null +++ b/TransWeb/Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/TransWeb/ReadMe.txt b/TransWeb/ReadMe.txt new file mode 100644 index 0000000..7ed8f8d --- /dev/null +++ b/TransWeb/ReadMe.txt @@ -0,0 +1,37 @@ +TransWeb + +Demonstrates how to implement UIWebView with a transparent background. + +To achieve this you need to make the HTML body's background color transparent by doing the following - +1) set the UIWebView's backgroundColor property to [UIColor clearColor] +2) use the UIWebView's content in the html: +3) the UIWebView's opaque property set to NO + + +Build Requirements +iOS 4.0 SDK + + +Runtime Requirements +iPhone OS 3.2 or later + + +Using the Sample +Launch the TransWeb project using Xcode. +To run in the simulator, set the Active SDK to Simulator. To run on a device, set the Active SDK to the appropriate Device setting. When launched scroll vertically through the web content and observe the transparent background image. + + +Packaging List +main.m - Main source file for this sample. +AppDelegate.h/.m - The application's delegate to setup its window and view controller content. +MyViewController.h/.m - The main view controller controlling the web view. + + +Changes from Previous Versions +1.4 - Updated iTunesArtwork. +1.3 - Added iPhone OS 3.2 for deployment SDK. Updated artwork. Upgraded project to build with the iOS 4 SDK. +1.1 - Corrected UIWebView warning of "Turning off phone number detection is not supported on iPhone OS versions prior 3.0." +1.0 - First release. + + +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/TransWeb/TransWeb.xcodeproj/project.pbxproj b/TransWeb/TransWeb.xcodeproj/project.pbxproj new file mode 100755 index 0000000..1d406f6 --- /dev/null +++ b/TransWeb/TransWeb.xcodeproj/project.pbxproj @@ -0,0 +1,338 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 53095FF40D9C4D1A00F143AD /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF00D9C4D1A00F143AD /* MyViewController.m */; }; + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53095FF30D9C4D1A00F143AD /* AppDelegate.m */; }; + 5398EE8B0F08ABCE00DE34AD /* webViewContent.html in Resources */ = {isa = PBXBuildFile; fileRef = 5398EE890F08ABCE00DE34AD /* webViewContent.html */; }; + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EACC050DDA319F00908D73 /* MainWindow.xib */; }; + CB6C7C4A11D4237F00AC7FA8 /* Background.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4111D4237F00AC7FA8 /* Background.png */; }; + CB6C7C4B11D4237F00AC7FA8 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4211D4237F00AC7FA8 /* Default.png */; }; + CB6C7C4C11D4237F00AC7FA8 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4311D4237F00AC7FA8 /* Icon-72.png */; }; + CB6C7C4D11D4237F00AC7FA8 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4411D4237F00AC7FA8 /* Icon-Small-50.png */; }; + CB6C7C4E11D4237F00AC7FA8 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4511D4237F00AC7FA8 /* Icon-Small.png */; }; + CB6C7C4F11D4237F00AC7FA8 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4611D4237F00AC7FA8 /* Icon-Small@2x.png */; }; + CB6C7C5011D4237F00AC7FA8 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4711D4237F00AC7FA8 /* Icon.png */; }; + CB6C7C5111D4237F00AC7FA8 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7C4811D4237F00AC7FA8 /* Icon@2x.png */; }; + CB6C7D0B11D541B600AC7FA8 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D0A11D541B600AC7FA8 /* iTunesArtwork */; }; + CB8F293611D1760C00E84C56 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = CB8F293511D1760C00E84C56 /* ReadMe.txt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* TransWeb.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TransWeb.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 53095FEF0D9C4D0500F143AD /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 53095FF00D9C4D1A00F143AD /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 53095FF10D9C4D1A00F143AD /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5309602D0D9C4E0800F143AD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 5398EE8A0F08ABCE00DE34AD /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = en; path = en.lproj/webViewContent.html; sourceTree = ""; }; + 53EACC060DDA319F00908D73 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CB6C7C4111D4237F00AC7FA8 /* Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Background.png; sourceTree = ""; }; + CB6C7C4211D4237F00AC7FA8 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + CB6C7C4311D4237F00AC7FA8 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + CB6C7C4411D4237F00AC7FA8 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + CB6C7C4511D4237F00AC7FA8 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + CB6C7C4611D4237F00AC7FA8 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + CB6C7C4711D4237F00AC7FA8 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + CB6C7C4811D4237F00AC7FA8 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + CB6C7D0A11D541B600AC7FA8 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = SOURCE_ROOT; }; + CB8F293511D1760C00E84C56 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* TransWeb.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + CB8F293511D1760C00E84C56 /* ReadMe.txt */, + CBFA1F17110F9E0100721ED2 /* Classes */, + 53AF8AEC0D9C50B700726DBA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + CB6C7C4011D4237F00AC7FA8 /* images */, + 5398EE890F08ABCE00DE34AD /* webViewContent.html */, + 8D1107310486CEB800E47090 /* Info.plist */, + 53EACC050DDA319F00908D73 /* MainWindow.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5309602D0D9C4E0800F143AD /* QuartzCore.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53AF8AEC0D9C50B700726DBA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 53095FEF0D9C4D0500F143AD /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + CB6C7C4011D4237F00AC7FA8 /* images */ = { + isa = PBXGroup; + children = ( + CB6C7D0A11D541B600AC7FA8 /* iTunesArtwork */, + CB6C7C4111D4237F00AC7FA8 /* Background.png */, + CB6C7C4211D4237F00AC7FA8 /* Default.png */, + CB6C7C4311D4237F00AC7FA8 /* Icon-72.png */, + CB6C7C4411D4237F00AC7FA8 /* Icon-Small-50.png */, + CB6C7C4511D4237F00AC7FA8 /* Icon-Small.png */, + CB6C7C4611D4237F00AC7FA8 /* Icon-Small@2x.png */, + CB6C7C4711D4237F00AC7FA8 /* Icon.png */, + CB6C7C4811D4237F00AC7FA8 /* Icon@2x.png */, + ); + path = images; + sourceTree = ""; + }; + CBFA1F17110F9E0100721ED2 /* Classes */ = { + isa = PBXGroup; + children = ( + 53095FF20D9C4D1A00F143AD /* AppDelegate.h */, + 53095FF30D9C4D1A00F143AD /* AppDelegate.m */, + 53095FF10D9C4D1A00F143AD /* MyViewController.h */, + 53095FF00D9C4D1A00F143AD /* MyViewController.m */, + ); + name = Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* TransWeb */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TransWeb" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TransWeb; + productName = IBTest; + productReference = 1D6058910D05DD3D006BFB54 /* TransWeb.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TransWeb" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* TransWeb */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53EACC070DDA319F00908D73 /* MainWindow.xib in Resources */, + 5398EE8B0F08ABCE00DE34AD /* webViewContent.html in Resources */, + CB8F293611D1760C00E84C56 /* ReadMe.txt in Resources */, + CB6C7C4A11D4237F00AC7FA8 /* Background.png in Resources */, + CB6C7C4B11D4237F00AC7FA8 /* Default.png in Resources */, + CB6C7C4C11D4237F00AC7FA8 /* Icon-72.png in Resources */, + CB6C7C4D11D4237F00AC7FA8 /* Icon-Small-50.png in Resources */, + CB6C7C4E11D4237F00AC7FA8 /* Icon-Small.png in Resources */, + CB6C7C4F11D4237F00AC7FA8 /* Icon-Small@2x.png in Resources */, + CB6C7C5011D4237F00AC7FA8 /* Icon.png in Resources */, + CB6C7C5111D4237F00AC7FA8 /* Icon@2x.png in Resources */, + CB6C7D0B11D541B600AC7FA8 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 53095FF40D9C4D1A00F143AD /* MyViewController.m in Sources */, + 53095FF50D9C4D1A00F143AD /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5398EE890F08ABCE00DE34AD /* webViewContent.html */ = { + isa = PBXVariantGroup; + children = ( + 5398EE8A0F08ABCE00DE34AD /* en */, + ); + name = webViewContent.html; + sourceTree = ""; + }; + 53EACC050DDA319F00908D73 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 53EACC060DDA319F00908D73 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = TransWeb; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + PREBINDING = NO; + PRODUCT_NAME = TransWeb; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TransWeb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TransWeb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/TransWeb/en.lproj/MainWindow.xib b/TransWeb/en.lproj/MainWindow.xib new file mode 100644 index 0000000..1a5745a --- /dev/null +++ b/TransWeb/en.lproj/MainWindow.xib @@ -0,0 +1,629 @@ + + + + 512 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 1292 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + YES + + + + + + + 256 + {0, 0} + NO + YES + YES + + 1 + MC4wNTk1Mzg0NTAwOSAwLjQyODMxMzY0MjcgMC42NDI4NTcxMzQzAA + + + + YES + + + + 274 + + YES + + + 274 + {320, 416} + + NO + NO + 0.8380281925201416 + 4 + NO + + NSImage + Background.png + + + + + 292 + {320, 416} + + + 1 + MSAxIDEgMAA + + NO + YES + YES + YES + 1 + YES + + + {320, 416} + + + 3 + MQA + + 2 + + + NO + + + + Transparent UIWebView + + + + + + + + + + YES + + + window + + + + 52 + + + + delegate + + + + 53 + + + + myNavController + + + + 60 + + + + webView + + + + 63 + + + + + YES + + 0 + + + + + + 2 + + + + + -1 + + + File's Owner + + + 3 + + + AppDelegate + + + -2 + + + + + 55 + + + YES + + + + + + + 57 + + + + + 50 + + + YES + + + + + + + 54 + + + YES + + + + + + + 59 + + + + + 61 + + + + + 62 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.UIWindow.visibleAtLaunch + 3.CustomClassName + 3.IBPluginDependency + 50.CustomClassName + 50.IBEditorWindowLastContentRect + 50.IBPluginDependency + 54.IBPluginDependency + 55.IBEditorWindowLastContentRect + 55.IBPluginDependency + 57.IBPluginDependency + 61.IBPluginDependency + 62.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{97, 415}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyViewController + {{0, 515}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{329, 495}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 63 + + + + YES + + AppDelegate + NSObject + + YES + + YES + myNavController + window + + + YES + UINavigationController + UIWindow + + + + IBProjectSource + AppDelegate.h + + + + MyViewController + UIViewController + + webView + UIWebView + + + IBProjectSource + MyViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWebView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWebView.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../TransWeb.xcodeproj + 3 + 3.1 + + diff --git a/TransWeb/en.lproj/webViewContent.html b/TransWeb/en.lproj/webViewContent.html new file mode 100644 index 0000000..ccf9540 --- /dev/null +++ b/TransWeb/en.lproj/webViewContent.html @@ -0,0 +1,23 @@ + + + + +

+Lake Don Pedro +

+ + +

+Located in the Sierra Nevada foothills of California in the Sierra Nevada mountain range, on the way to Yosemite National Park, Highway 120, it contains over 160 miles of shoreline and hundreds of hidden coves and inlets for boating, swimming, fishing, and camping. +

+

+It contains two marinas: Don Pedro on the west and Moccasin Point on the east. +

+

+The reservoir has about 160 miles (260 km) of shoreline, has submerged some 26 miles (42 km) of Tuolumne River bed, and has a surface area of about 13,000 acres. +

+
+

+ \ No newline at end of file diff --git a/TransWeb/iTunesArtwork b/TransWeb/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/TransWeb/iTunesArtwork differ diff --git a/TransWeb/images/Background.png b/TransWeb/images/Background.png new file mode 100644 index 0000000..a855aa0 Binary files /dev/null and b/TransWeb/images/Background.png differ diff --git a/TransWeb/images/Default.png b/TransWeb/images/Default.png new file mode 100644 index 0000000..b483d93 Binary files /dev/null and b/TransWeb/images/Default.png differ diff --git a/TransWeb/images/Icon-72.png b/TransWeb/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/TransWeb/images/Icon-72.png differ diff --git a/TransWeb/images/Icon-Small-50.png b/TransWeb/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/TransWeb/images/Icon-Small-50.png differ diff --git a/TransWeb/images/Icon-Small.png b/TransWeb/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/TransWeb/images/Icon-Small.png differ diff --git a/TransWeb/images/Icon-Small@2x.png b/TransWeb/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/TransWeb/images/Icon-Small@2x.png differ diff --git a/TransWeb/images/Icon.png b/TransWeb/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/TransWeb/images/Icon.png differ diff --git a/TransWeb/images/Icon@2x.png b/TransWeb/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/TransWeb/images/Icon@2x.png differ diff --git a/TransWeb/main.m b/TransWeb/main.m new file mode 100755 index 0000000..c8ec2e8 --- /dev/null +++ b/TransWeb/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Main source file to this sample application. + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/WeatherMap.zip b/WeatherMap.zip new file mode 100644 index 0000000..d75c546 Binary files /dev/null and b/WeatherMap.zip differ diff --git a/WeatherMap/Classes/AppDelegate.h b/WeatherMap/Classes/AppDelegate.h new file mode 100644 index 0000000..602a5a0 --- /dev/null +++ b/WeatherMap/Classes/AppDelegate.h @@ -0,0 +1,64 @@ +/* + File: AppDelegate.h + Abstract: Displays the application window and manages the WeatherServer and MapViewController. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class WeatherServer; +@class MapViewController; + +@interface AppDelegate : NSObject +{ + WeatherServer *weatherServer; + MapViewController *mapViewController; + UIWindow *window; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet WeatherServer *weatherServer; +@property (nonatomic, retain) IBOutlet MapViewController *mapViewController; + +@end + diff --git a/WeatherMap/Classes/AppDelegate.m b/WeatherMap/Classes/AppDelegate.m new file mode 100644 index 0000000..17f4b7f --- /dev/null +++ b/WeatherMap/Classes/AppDelegate.m @@ -0,0 +1,73 @@ +/* + File: AppDelegate.m + Abstract: Displays the application window and manages the WeatherServer and MapViewController. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MapViewController.h" +#import "WeatherServer.h" +#import "WeatherItem.h" + +@implementation AppDelegate + +@synthesize window, weatherServer, mapViewController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + [window addSubview:mapViewController.view]; + [window makeKeyAndVisible]; + mapViewController.weatherServer = weatherServer; + [mapViewController mapView:mapViewController.mapView regionDidChangeAnimated:NO]; +} + +- (void)dealloc +{ + [window release]; + [super dealloc]; +} + +@end + diff --git a/WeatherMap/Classes/MapViewController.h b/WeatherMap/Classes/MapViewController.h new file mode 100644 index 0000000..6af1b05 --- /dev/null +++ b/WeatherMap/Classes/MapViewController.h @@ -0,0 +1,64 @@ +/* + File: MapViewController.h + Abstract: Controls the MKMapView and leverages the WeatherServer class to display each weather location. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@class WeatherServer; + +@interface MapViewController : UIViewController +{ + UINavigationBar *titleBar; + WeatherServer *weatherServer; + MKMapView *mapView; +} + +@property (nonatomic, retain) IBOutlet UINavigationBar *titleBar; +@property (nonatomic, retain) IBOutlet MKMapView *mapView; +@property (nonatomic, retain) IBOutlet WeatherServer *weatherServer; + +@end diff --git a/WeatherMap/Classes/MapViewController.m b/WeatherMap/Classes/MapViewController.m new file mode 100644 index 0000000..5e5aef9 --- /dev/null +++ b/WeatherMap/Classes/MapViewController.m @@ -0,0 +1,111 @@ +/* + File: MapViewController.m + Abstract: Controls the MKMapView and leverages the WeatherServer class to display each weather location. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MapViewController.h" +#import "WeatherServer.h" +#import "WeatherItem.h" +#import "WeatherAnnotationView.h" + + +@implementation MapViewController + +@synthesize titleBar, mapView, weatherServer; + +- (void)viewDidLoad +{ + // go to North America + MKCoordinateRegion newRegion; + newRegion.center.latitude = 37.37; + newRegion.center.longitude = -96.24; + newRegion.span.latitudeDelta = 28.49; + newRegion.span.longitudeDelta = 31.025; + + [self.mapView setRegion:newRegion animated:NO]; +} + +- (void)viewDidUnload +{ + self.titleBar = nil; + self.mapView = nil; +} + +- (void)dealloc +{ + [titleBar release]; + [mapView release]; + [super dealloc]; +} + + +#pragma mark Map View Delegate methods + +- (void)mapView:(MKMapView *)map regionDidChangeAnimated:(BOOL)animated +{ + NSArray *oldAnnotations = mapView.annotations; + [mapView removeAnnotations:oldAnnotations]; + + NSArray *weatherItems = [weatherServer weatherItemsForMapRegion:mapView.region maximumCount:4]; + [mapView addAnnotations:weatherItems]; +} + +- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id )annotation +{ + static NSString *AnnotationViewID = @"annotationViewID"; + + WeatherAnnotationView *annotationView = + (WeatherAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID]; + if (annotationView == nil) + { + annotationView = [[[WeatherAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease]; + } + + annotationView.annotation = annotation; + + return annotationView; +} + +@end diff --git a/WeatherMap/Classes/WeatherAnnotationView.h b/WeatherMap/Classes/WeatherAnnotationView.h new file mode 100644 index 0000000..3750756 --- /dev/null +++ b/WeatherMap/Classes/WeatherAnnotationView.h @@ -0,0 +1,54 @@ +/* + File: WeatherAnnotationView.h + Abstract: The UIView or MKAnnotationView for drawing each weather location's data. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface WeatherAnnotationView : MKAnnotationView +{ } + +@end \ No newline at end of file diff --git a/WeatherMap/Classes/WeatherAnnotationView.m b/WeatherMap/Classes/WeatherAnnotationView.m new file mode 100644 index 0000000..3dc48cc --- /dev/null +++ b/WeatherMap/Classes/WeatherAnnotationView.m @@ -0,0 +1,141 @@ +/* + File: WeatherAnnotationView.m + Abstract: The UIView or MKAnnotationView for drawing each weather location's data. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "WeatherAnnotationView.h" +#import "WeatherItem.h" + + +@implementation WeatherAnnotationView + +- (id)initWithAnnotation:(id )annotation reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; + if (self != nil) + { + CGRect frame = self.frame; + frame.size = CGSizeMake(60.0, 85.0); + self.frame = frame; + self.backgroundColor = [UIColor clearColor]; + self.centerOffset = CGPointMake(30.0, 42.0); + } + return self; +} + +- (void)setAnnotation:(id )annotation +{ + [super setAnnotation:annotation]; + + // this annotation view has custom drawing code. So when we reuse an annotation view + // (through MapView's delegate "dequeueReusableAnnoationViewWithIdentifier" which returns non-nil) + // we need to have it redraw the new annotation data. + // + // for any other custom annotation view which has just contains a simple image, this won't be needed + // + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)rect +{ + WeatherItem *weatherItem = (WeatherItem *)self.annotation; + if (weatherItem != nil) + { + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetLineWidth(context, 1); + + // draw the gray pointed shape: + CGMutablePathRef path = CGPathCreateMutable(); + CGPathMoveToPoint(path, NULL, 14.0, 0.0); + CGPathAddLineToPoint(path, NULL, 0.0, 0.0); + CGPathAddLineToPoint(path, NULL, 55.0, 50.0); + CGContextAddPath(context, path); + CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor); + CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor); + CGContextDrawPath(context, kCGPathFillStroke); + CGPathRelease(path); + + // draw the cyan rounded box + path = CGPathCreateMutable(); + CGPathMoveToPoint(path, NULL, 15.0, 0.5); + CGPathAddArcToPoint(path, NULL, 59.5, 00.5, 59.5, 5.0, 5.0); + CGPathAddArcToPoint(path, NULL, 59.5, 69.5, 55.0, 69.5, 5.0); + CGPathAddArcToPoint(path, NULL, 10.5, 69.5, 10.5, 64.0, 5.0); + CGPathAddArcToPoint(path, NULL, 10.5, 00.5, 15.0, 0.5, 5.0); + CGContextAddPath(context, path); + CGContextSetFillColorWithColor(context, [UIColor cyanColor].CGColor); + CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); + CGContextDrawPath(context, kCGPathFillStroke); + CGPathRelease(path); + + NSInteger high = [weatherItem.high integerValue]; + NSInteger low = [weatherItem.low integerValue]; + + // draw the temperature string and weather graphic + NSString *temperature = [NSString stringWithFormat:@"%@\n%d / %d", weatherItem.place, high, low]; + [[UIColor blackColor] set]; + [temperature drawInRect:CGRectMake(15.0, 5.0, 50.0, 40.0) withFont:[UIFont systemFontOfSize:11.0]]; + NSString *imageName = nil; + switch ([weatherItem.condition integerValue]) + { + case Sunny: + imageName = @"sunny.png"; + break; + case PartlyCloudy: + imageName = @"partly_cloudy.png"; + break; + case Cloudy: + imageName = @"cloudy.png"; + break; + default: + imageName = @"partly_cloudy.png"; + break; + } + [[UIImage imageNamed:imageName] drawInRect:CGRectMake(12.5, 28.0, 45.0, 45.0)]; + } +} + +@end diff --git a/WeatherMap/Classes/WeatherItem.h b/WeatherMap/Classes/WeatherItem.h new file mode 100644 index 0000000..444f48b --- /dev/null +++ b/WeatherMap/Classes/WeatherItem.h @@ -0,0 +1,83 @@ +/* + File: WeatherItem.h + Abstract: The weather object representing each location on the map. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +enum WeatherConditions +{ + Sunny = 0, + PartlyCloudy, + Cloudy, + Showers, + Thunderstorms, + Snow +}; + +@interface WeatherItem : NSManagedObject +{ + NSString *place; + NSNumber *low; + NSNumber *high; + NSNumber *condition; + NSNumber *latitude; + NSNumber *longitude; + + CLLocationCoordinate2D coordinate; +} + +@property (nonatomic, retain) NSString *place; +@property (nonatomic, retain) NSNumber *low; +@property (nonatomic, retain) NSNumber *high; +@property (nonatomic, retain) NSNumber *condition; +@property (nonatomic, retain) NSNumber *latitude; +@property (nonatomic, retain) NSNumber *longitude; + +@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; + +@end diff --git a/WeatherMap/Classes/WeatherItem.m b/WeatherMap/Classes/WeatherItem.m new file mode 100644 index 0000000..aca1597 --- /dev/null +++ b/WeatherMap/Classes/WeatherItem.m @@ -0,0 +1,62 @@ +/* + File: WeatherItem.m + Abstract: The weather object representing each location on the map. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "WeatherItem.h" + +@implementation WeatherItem + +@dynamic place, low, high, condition, longitude, latitude; + +- (CLLocationCoordinate2D)coordinate +{ + coordinate.latitude = [self.latitude doubleValue]; + coordinate.longitude = [self.longitude doubleValue]; + return coordinate; +} + +@end diff --git a/WeatherMap/Classes/WeatherServer.h b/WeatherMap/Classes/WeatherServer.h new file mode 100644 index 0000000..a043cfc --- /dev/null +++ b/WeatherMap/Classes/WeatherServer.h @@ -0,0 +1,63 @@ +/* + File: WeatherServer.h + Abstract: Manages and serves all weather locations backed by Core Data. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@interface WeatherServer : NSObject +{ + NSManagedObjectContext *managedObjectContext; + NSPersistentStoreCoordinator *persistentStoreCoordinator; +} + +@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; +@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; + +- (NSArray *)weatherItemsForMapRegion:(MKCoordinateRegion)region maximumCount:(NSInteger)maxCount; + +@end diff --git a/WeatherMap/Classes/WeatherServer.m b/WeatherMap/Classes/WeatherServer.m new file mode 100644 index 0000000..09b13f9 --- /dev/null +++ b/WeatherMap/Classes/WeatherServer.m @@ -0,0 +1,210 @@ +/* + File: WeatherServer.m + Abstract: Manages and serves all weather locations backed by Core Data. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "WeatherServer.h" +#import "WeatherItem.h" + + +@implementation WeatherServer + +- (void)dealloc +{ + [managedObjectContext release]; + [persistentStoreCoordinator release]; + [super dealloc]; +} + +// Returns the managed object context for the application. +// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. +// +- (NSManagedObjectContext *)managedObjectContext +{ + if (managedObjectContext == nil) + { + managedObjectContext = [[NSManagedObjectContext alloc] init]; + [managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; + + NSError *error = nil; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + [fetchRequest setEntity:[NSEntityDescription entityForName:@"WeatherItem" inManagedObjectContext:self.managedObjectContext]]; + NSArray *fetchedItems = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + if (fetchedItems.count == 0) + { + // fill in the new WeatherMap.sqlite found in the application's Documents directory + NSManagedObjectContext *moc = self.managedObjectContext; + NSEntityDescription *ent = [NSEntityDescription entityForName:@"WeatherItem" inManagedObjectContext:moc]; + WeatherItem *item = nil; + + item = [[WeatherItem alloc] initWithEntity:ent insertIntoManagedObjectContext:moc]; + item.place = @"S.F."; + item.latitude = [NSNumber numberWithDouble:37.779941]; + item.longitude = [NSNumber numberWithDouble:-122.417908]; + item.high = [NSNumber numberWithInteger:80]; + item.low = [NSNumber numberWithInteger:50]; + item.condition = [NSNumber numberWithInteger:Sunny]; + [item release]; // release the item - the context itself retains the necessary data + + item = [[WeatherItem alloc] initWithEntity:ent insertIntoManagedObjectContext:moc]; + item.place = @"Denver"; + item.latitude = [NSNumber numberWithDouble:39.752601]; + item.longitude = [NSNumber numberWithDouble:-104.982605]; + item.high = [NSNumber numberWithInteger:40]; + item.low = [NSNumber numberWithInteger:30]; + item.condition = [NSNumber numberWithInteger:Snow]; + [item release]; + + item = [[WeatherItem alloc] initWithEntity:ent insertIntoManagedObjectContext:moc]; + item.place = @"Chicago"; + item.latitude = [NSNumber numberWithDouble:41.863425]; + item.longitude = [NSNumber numberWithDouble:-87.652359]; + item.high = [NSNumber numberWithInteger:45]; + item.low = [NSNumber numberWithInteger:29]; + item.condition = [NSNumber numberWithInteger:Snow]; + [item release]; + + item = [[WeatherItem alloc] initWithEntity:ent insertIntoManagedObjectContext:moc]; + item.place = @"Seattle"; + item.latitude = [NSNumber numberWithDouble:47.615884]; + item.longitude = [NSNumber numberWithDouble:-122.332764]; + item.high = [NSNumber numberWithInteger:75]; + item.low = [NSNumber numberWithInteger:45]; + item.condition = [NSNumber numberWithInteger:Sunny]; + [item release]; + + NSError *err; + [moc save:&err]; + } + [fetchRequest release]; + } + + return managedObjectContext; +} + +// Returns the persistent store coordinator for the application. +// If the coordinator doesn't already exist, it is created and the application's store added to it. +// +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator +{ + if (persistentStoreCoordinator == nil) + { + // apply a store URL to our persistentStoreCoordinator, which will create a new WeatherMap.sqlite file if necessary + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *weatherMapPath = [[paths lastObject] stringByAppendingPathComponent:@"WeatherMap.sqlite"]; + NSURL *storeUrl = [NSURL fileURLWithPath:weatherMapPath]; + + NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil]; + persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; + + NSError *error = nil; + if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. + + Typical reasons for an error here include: + * The persistent store is not accessible + * The schema for the persistent store is incompatible with current managed object model + Check the error message to determine what the actual problem was. + */ + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + } + } + + return persistentStoreCoordinator; +} + +- (NSArray *)weatherItemsForMapRegion:(MKCoordinateRegion)region maximumCount:(NSInteger)maxCount +{ + NSMutableArray *weatherItems = [NSMutableArray array]; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + [fetchRequest setEntity:[NSEntityDescription entityForName:@"WeatherItem" inManagedObjectContext:self.managedObjectContext]]; + + NSNumber *latitudeStart = [NSNumber numberWithDouble:region.center.latitude - region.span.latitudeDelta/2.0]; + NSNumber *latitudeStop = [NSNumber numberWithDouble:region.center.latitude + region.span.latitudeDelta/2.0]; + NSNumber *longitudeStart = [NSNumber numberWithDouble:region.center.longitude - region.span.longitudeDelta/2.0]; + NSNumber *longitudeStop = [NSNumber numberWithDouble:region.center.longitude + region.span.longitudeDelta/2.0]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude>%@ AND latitude<%@ AND longitude>%@ AND longitude<%@", latitudeStart, latitudeStop, longitudeStart, longitudeStop]; + [fetchRequest setPredicate:predicate]; + NSMutableArray *sortDescriptors = [NSMutableArray array]; + [sortDescriptors addObject:[[[NSSortDescriptor alloc] initWithKey:@"latitude" ascending:YES] autorelease]]; + [sortDescriptors addObject:[[[NSSortDescriptor alloc] initWithKey:@"longitude" ascending:YES] autorelease]]; + [fetchRequest setSortDescriptors:sortDescriptors]; + [fetchRequest setReturnsObjectsAsFaults:NO]; + [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"latitude", @"longitude", @"place", nil]]; + NSError *error = nil; + NSArray *fetchedItems = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + if (fetchedItems == nil) + { + // an error occurred + NSLog(@"fetch request resulted in an error %@, %@", error, [error userInfo]); + } + else + { + NSInteger countOfFetchedItems = [fetchedItems count]; + if (countOfFetchedItems > maxCount) { + float index = 0, stride = (float)(countOfFetchedItems - 1)/ (float)maxCount; + NSInteger countOfItemsToReturn = 0; + while (countOfItemsToReturn < maxCount) + { + [weatherItems addObject:[fetchedItems objectAtIndex:(NSInteger)index]]; + index += stride; + countOfItemsToReturn++; + } + } + else + { + [weatherItems addObjectsFromArray:fetchedItems]; + } + } + [fetchRequest release]; + return weatherItems; +} + +@end diff --git a/WeatherMap/ReadMe.txt b/WeatherMap/ReadMe.txt new file mode 100644 index 0000000..494ac8f --- /dev/null +++ b/WeatherMap/ReadMe.txt @@ -0,0 +1,50 @@ +WeatherMap + +=========================================================================== +ABSTRACT +Demonstrates the use of the MapKit framework, displaying a map view with custom MKAnnotationViews. An annotation object on a map is any object that conforms to the MKAnnotation protocol and is displayed on the screen as a MKAnnotationView. Through the use of the MKAnnotation protocol and MKAnnotationView, this application identifies four major cities in North America with fictitious weather information. + +=========================================================================== +DISCUSSION + +These cities and their weather data are stored on disk using Core Data. Maps can potentially have dozens or hundreds of annotations, which is why the use of Core Data is demonstrated here. Core Data is a rich and sophisticated object graph management framework capable of dealing with large volumes of data. + +Important: +The MapKit framework uses Google services to provide map data. Use of this class and the associated interfaces binds you to the Google Maps/Google Earth API terms of service. You can find these terms of service mentioned in the header section of "MKMapView.h". + +=========================================================================== +BUILD REQUIREMENTS + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST + +AppDelegate +Configures and displays the application window and navigation controller. + +MapViewController +Controls the MKMapView and leverages the WeatherServer class to display each weather location. + +WeatherAnnotationView +The UIView or MKAnnotationView for drawing each weather location's data. + +WeatherItem +The weather object representing each location on the map. + +WeatherServer +Manages and serves all weather locations backed by Core Data. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS + +1.1 Updated for iOS 4.0. +1.0 Initial version published. + +=========================================================================== +Copyright (C) 2010 Apple Inc. All rights reserved. diff --git a/WeatherMap/WeatherMap-Info.plist b/WeatherMap/WeatherMap-Info.plist new file mode 100644 index 0000000..79eaac3 --- /dev/null +++ b/WeatherMap/WeatherMap-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon-72.png + Icon@2x.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.samplecode.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/WeatherMap/WeatherMap.sqlite b/WeatherMap/WeatherMap.sqlite new file mode 100644 index 0000000..d0fdfab Binary files /dev/null and b/WeatherMap/WeatherMap.sqlite differ diff --git a/WeatherMap/WeatherMap.xcdatamodel/elements b/WeatherMap/WeatherMap.xcdatamodel/elements new file mode 100644 index 0000000..dd90d12 Binary files /dev/null and b/WeatherMap/WeatherMap.xcdatamodel/elements differ diff --git a/WeatherMap/WeatherMap.xcdatamodel/layout b/WeatherMap/WeatherMap.xcdatamodel/layout new file mode 100644 index 0000000..002e175 Binary files /dev/null and b/WeatherMap/WeatherMap.xcdatamodel/layout differ diff --git a/WeatherMap/WeatherMap.xcodeproj/project.pbxproj b/WeatherMap/WeatherMap.xcodeproj/project.pbxproj new file mode 100755 index 0000000..c92ebb3 --- /dev/null +++ b/WeatherMap/WeatherMap.xcodeproj/project.pbxproj @@ -0,0 +1,360 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 28C3AD8A0F43EF2300507BA6 /* WeatherMap.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 28C3AD890F43EF2300507BA6 /* WeatherMap.xcdatamodel */; }; + 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D801B30F44B63D00FB423F /* CoreData.framework */; }; + 304C01F7103B5B10008B3893 /* WeatherAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 304C01F6103B5B10008B3893 /* WeatherAnnotationView.m */; }; + 304CFF661039F987008B3893 /* WeatherItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 304CFF651039F987008B3893 /* WeatherItem.m */; }; + 304CFF8E1039FCE8008B3893 /* WeatherServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 304CFF8D1039FCE8008B3893 /* WeatherServer.m */; }; + 304CFF94103A0971008B3893 /* MapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 304CFF92103A0971008B3893 /* MapViewController.m */; }; + 304CFF97103A09C6008B3893 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304CFF96103A09C6008B3893 /* MapKit.framework */; }; + 5356154E10C9CA4700F000BF /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5356154A10C9CA4700F000BF /* MainWindow.xib */; }; + 5356154F10C9CA4700F000BF /* MapViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5356154C10C9CA4700F000BF /* MapViewController.xib */; }; + CB6C7D2711D5435A00AC7FA8 /* cloudy.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D1E11D5435A00AC7FA8 /* cloudy.png */; }; + CB6C7D2811D5435A00AC7FA8 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D1F11D5435A00AC7FA8 /* Icon-72.png */; }; + CB6C7D2911D5435A00AC7FA8 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2011D5435A00AC7FA8 /* Icon-Small-50.png */; }; + CB6C7D2A11D5435A00AC7FA8 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2111D5435A00AC7FA8 /* Icon-Small.png */; }; + CB6C7D2B11D5435A00AC7FA8 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2211D5435A00AC7FA8 /* Icon-Small@2x.png */; }; + CB6C7D2C11D5435A00AC7FA8 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2311D5435A00AC7FA8 /* Icon.png */; }; + CB6C7D2D11D5435A00AC7FA8 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2411D5435A00AC7FA8 /* Icon@2x.png */; }; + CB6C7D2E11D5435A00AC7FA8 /* partly_cloudy.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2511D5435A00AC7FA8 /* partly_cloudy.png */; }; + CB6C7D2F11D5435A00AC7FA8 /* sunny.png in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D2611D5435A00AC7FA8 /* sunny.png */; }; + CB6C7D3111D5436500AC7FA8 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = CB6C7D3011D5436500AC7FA8 /* iTunesArtwork */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Classes/AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Classes/AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* WeatherMap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WeatherMap.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28C3AD890F43EF2300507BA6 /* WeatherMap.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = WeatherMap.xcdatamodel; sourceTree = ""; }; + 28D801B30F44B63D00FB423F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ../main.m; sourceTree = ""; }; + 304C01F5103B5B10008B3893 /* WeatherAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeatherAnnotationView.h; path = Classes/WeatherAnnotationView.h; sourceTree = ""; }; + 304C01F6103B5B10008B3893 /* WeatherAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WeatherAnnotationView.m; path = Classes/WeatherAnnotationView.m; sourceTree = ""; }; + 304CFF641039F987008B3893 /* WeatherItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeatherItem.h; path = Classes/WeatherItem.h; sourceTree = ""; }; + 304CFF651039F987008B3893 /* WeatherItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WeatherItem.m; path = Classes/WeatherItem.m; sourceTree = ""; }; + 304CFF8C1039FCE8008B3893 /* WeatherServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeatherServer.h; path = Classes/WeatherServer.h; sourceTree = ""; }; + 304CFF8D1039FCE8008B3893 /* WeatherServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WeatherServer.m; path = Classes/WeatherServer.m; sourceTree = ""; }; + 304CFF91103A0971008B3893 /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapViewController.h; path = Classes/MapViewController.h; sourceTree = ""; }; + 304CFF92103A0971008B3893 /* MapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MapViewController.m; path = Classes/MapViewController.m; sourceTree = ""; }; + 304CFF96103A09C6008B3893 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 308ACF30106C1C060042E5C1 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* WeatherMap_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeatherMap_Prefix.pch; path = ../WeatherMap_Prefix.pch; sourceTree = ""; }; + 5356154B10C9CA4700F000BF /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 5356154D10C9CA4700F000BF /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MapViewController.xib; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* WeatherMap-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "WeatherMap-Info.plist"; sourceTree = ""; }; + CB6C7D1E11D5435A00AC7FA8 /* cloudy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloudy.png; sourceTree = ""; }; + CB6C7D1F11D5435A00AC7FA8 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + CB6C7D2011D5435A00AC7FA8 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + CB6C7D2111D5435A00AC7FA8 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + CB6C7D2211D5435A00AC7FA8 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + CB6C7D2311D5435A00AC7FA8 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + CB6C7D2411D5435A00AC7FA8 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + CB6C7D2511D5435A00AC7FA8 /* partly_cloudy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = partly_cloudy.png; sourceTree = ""; }; + CB6C7D2611D5435A00AC7FA8 /* sunny.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = sunny.png; sourceTree = ""; }; + CB6C7D3011D5436500AC7FA8 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */, + 304CFF97103A09C6008B3893 /* MapKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* WeatherMap_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* WeatherMap.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 308ACF30106C1C060042E5C1 /* ReadMe.txt */, + CB6C7D1A11D5430700AC7FA8 /* Classes */, + 080E96DDFE201D6D7F000001 /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + CB6C7D1D11D5435A00AC7FA8 /* images */, + 28C3AD890F43EF2300507BA6 /* WeatherMap.xcdatamodel */, + 5356154A10C9CA4700F000BF /* MainWindow.xib */, + 5356154C10C9CA4700F000BF /* MapViewController.xib */, + 8D1107310486CEB800E47090 /* WeatherMap-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + 28D801B30F44B63D00FB423F /* CoreData.framework */, + 304CFF96103A09C6008B3893 /* MapKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CB6C7D1A11D5430700AC7FA8 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 304CFF91103A0971008B3893 /* MapViewController.h */, + 304CFF92103A0971008B3893 /* MapViewController.m */, + 304C01F5103B5B10008B3893 /* WeatherAnnotationView.h */, + 304C01F6103B5B10008B3893 /* WeatherAnnotationView.m */, + 304CFF8C1039FCE8008B3893 /* WeatherServer.h */, + 304CFF8D1039FCE8008B3893 /* WeatherServer.m */, + 304CFF641039F987008B3893 /* WeatherItem.h */, + 304CFF651039F987008B3893 /* WeatherItem.m */, + ); + name = Classes; + sourceTree = ""; + }; + CB6C7D1D11D5435A00AC7FA8 /* images */ = { + isa = PBXGroup; + children = ( + CB6C7D3011D5436500AC7FA8 /* iTunesArtwork */, + CB6C7D1E11D5435A00AC7FA8 /* cloudy.png */, + CB6C7D1F11D5435A00AC7FA8 /* Icon-72.png */, + CB6C7D2011D5435A00AC7FA8 /* Icon-Small-50.png */, + CB6C7D2111D5435A00AC7FA8 /* Icon-Small.png */, + CB6C7D2211D5435A00AC7FA8 /* Icon-Small@2x.png */, + CB6C7D2311D5435A00AC7FA8 /* Icon.png */, + CB6C7D2411D5435A00AC7FA8 /* Icon@2x.png */, + CB6C7D2511D5435A00AC7FA8 /* partly_cloudy.png */, + CB6C7D2611D5435A00AC7FA8 /* sunny.png */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* WeatherMap */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "WeatherMap" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WeatherMap; + productName = WeatherMap; + productReference = 1D6058910D05DD3D006BFB54 /* WeatherMap.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WeatherMap" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* WeatherMap */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5356154E10C9CA4700F000BF /* MainWindow.xib in Resources */, + 5356154F10C9CA4700F000BF /* MapViewController.xib in Resources */, + CB6C7D2711D5435A00AC7FA8 /* cloudy.png in Resources */, + CB6C7D2811D5435A00AC7FA8 /* Icon-72.png in Resources */, + CB6C7D2911D5435A00AC7FA8 /* Icon-Small-50.png in Resources */, + CB6C7D2A11D5435A00AC7FA8 /* Icon-Small.png in Resources */, + CB6C7D2B11D5435A00AC7FA8 /* Icon-Small@2x.png in Resources */, + CB6C7D2C11D5435A00AC7FA8 /* Icon.png in Resources */, + CB6C7D2D11D5435A00AC7FA8 /* Icon@2x.png in Resources */, + CB6C7D2E11D5435A00AC7FA8 /* partly_cloudy.png in Resources */, + CB6C7D2F11D5435A00AC7FA8 /* sunny.png in Resources */, + CB6C7D3111D5436500AC7FA8 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 28C3AD8A0F43EF2300507BA6 /* WeatherMap.xcdatamodel in Sources */, + 304CFF661039F987008B3893 /* WeatherItem.m in Sources */, + 304CFF8E1039FCE8008B3893 /* WeatherServer.m in Sources */, + 304CFF94103A0971008B3893 /* MapViewController.m in Sources */, + 304C01F7103B5B10008B3893 /* WeatherAnnotationView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5356154A10C9CA4700F000BF /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 5356154B10C9CA4700F000BF /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 5356154C10C9CA4700F000BF /* MapViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 5356154D10C9CA4700F000BF /* en */, + ); + name = MapViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = WeatherMap_Prefix.pch; + INFOPLIST_FILE = "WeatherMap-Info.plist"; + PRODUCT_NAME = WeatherMap; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = WeatherMap_Prefix.pch; + INFOPLIST_FILE = "WeatherMap-Info.plist"; + PRODUCT_NAME = WeatherMap; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "WeatherMap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WeatherMap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/WeatherMap/WeatherMap_Prefix.pch b/WeatherMap/WeatherMap_Prefix.pch new file mode 100644 index 0000000..6797dae --- /dev/null +++ b/WeatherMap/WeatherMap_Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the 'WeatherMap' target in the 'WeatherMap' project +// +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + + +#ifdef __OBJC__ + #import + #import + #import +#endif diff --git a/WeatherMap/en.lproj/MainWindow.xib b/WeatherMap/en.lproj/MainWindow.xib new file mode 100644 index 0000000..2416614 --- /dev/null +++ b/WeatherMap/en.lproj/MainWindow.xib @@ -0,0 +1,491 @@ + + + + 784 + 10A433 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + MapViewController + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 14 + + + + weatherServer + + + + 18 + + + + mapViewController + + + + 21 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + WeatherMap App Delegate + + + -2 + + + + + 12 + + + YES + + + + + 17 + + + + + 19 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 17.CustomClassName + 17.IBPluginDependency + 19.CustomClassName + 19.IBEditorWindowLastContentRect + 19.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + WeatherServer + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MapViewController + {{375, 665}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 21 + + + + YES + + AppDelegate + NSObject + + YES + + YES + mapViewController + weatherServer + window + + + YES + MapViewController + WeatherServer + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + AppDelegate + NSObject + + saveAction: + id + + + viewController + UIViewController + + + IBUserSource + + + + + MapViewController + UIViewController + + YES + + YES + mapView + titleBar + + + YES + MKMapView + UINavigationBar + + + + IBProjectSource + Classes/MapViewController.h + + + + WeatherServer + NSObject + + IBProjectSource + Classes/WeatherServer.h + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + WeatherMap.xcodeproj + 3 + 3.1 + + diff --git a/WeatherMap/en.lproj/MapViewController.xib b/WeatherMap/en.lproj/MapViewController.xib new file mode 100644 index 0000000..3c62bfb --- /dev/null +++ b/WeatherMap/en.lproj/MapViewController.xib @@ -0,0 +1,476 @@ + + + + 768 + 10A433 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 290 + {320, 44} + + NO + NO + + YES + + + Weather Map + + + + + + 274 + {{0, 44}, {320, 416}} + + NO + YES + 4 + YES + + + {320, 460} + + + 3 + MQA + + 2 + + + + + + + + YES + + + view + + + + 3 + + + + mapView + + + + 7 + + + + titleBar + + + + 8 + + + + delegate + + + + 9 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + + 5 + + + + + 6 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + 6.IBPluginDependency + + + YES + MapViewController + UIResponder + {{556, 412}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 9 + + + + YES + + MapViewController + UIViewController + + YES + + YES + mapView + titleBar + weatherServer + + + YES + MKMapView + UINavigationBar + WeatherServer + + + + IBProjectSource + Classes/MapViewController.h + + + + WeatherServer + NSObject + + IBProjectSource + Classes/WeatherServer.h + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../WeatherMap.xcodeproj + 3 + 3.1 + + diff --git a/WeatherMap/iTunesArtwork b/WeatherMap/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/WeatherMap/iTunesArtwork differ diff --git a/WeatherMap/images/Icon-72.png b/WeatherMap/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/WeatherMap/images/Icon-72.png differ diff --git a/WeatherMap/images/Icon-Small-50.png b/WeatherMap/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/WeatherMap/images/Icon-Small-50.png differ diff --git a/WeatherMap/images/Icon-Small.png b/WeatherMap/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/WeatherMap/images/Icon-Small.png differ diff --git a/WeatherMap/images/Icon-Small@2x.png b/WeatherMap/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/WeatherMap/images/Icon-Small@2x.png differ diff --git a/WeatherMap/images/Icon.png b/WeatherMap/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/WeatherMap/images/Icon.png differ diff --git a/WeatherMap/images/Icon@2x.png b/WeatherMap/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/WeatherMap/images/Icon@2x.png differ diff --git a/WeatherMap/images/cloudy.png b/WeatherMap/images/cloudy.png new file mode 100644 index 0000000..3fe205a Binary files /dev/null and b/WeatherMap/images/cloudy.png differ diff --git a/WeatherMap/images/partly_cloudy.png b/WeatherMap/images/partly_cloudy.png new file mode 100644 index 0000000..a1730bc Binary files /dev/null and b/WeatherMap/images/partly_cloudy.png differ diff --git a/WeatherMap/images/sunny.png b/WeatherMap/images/sunny.png new file mode 100644 index 0000000..505c6e8 Binary files /dev/null and b/WeatherMap/images/sunny.png differ diff --git a/WeatherMap/main.m b/WeatherMap/main.m new file mode 100644 index 0000000..79d19a9 --- /dev/null +++ b/WeatherMap/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: Main source file for this sample. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/WiTap.zip b/WiTap.zip new file mode 100644 index 0000000..fb0b1e9 Binary files /dev/null and b/WiTap.zip differ diff --git a/WiTap/AppController.h b/WiTap/AppController.h new file mode 100644 index 0000000..869fdb1 --- /dev/null +++ b/WiTap/AppController.h @@ -0,0 +1,69 @@ +/* + File: AppController.h + Abstract: UIApplication's delegate class, the central controller of the application. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TapView.h" +#import "BrowserViewController.h" +#import "Picker.h" +#import "TCPServer.h" + +@interface AppController : NSObject +{ + UIWindow *_window; + Picker *_picker; + TCPServer *_server; + NSInputStream *_inStream; + NSOutputStream *_outStream; + BOOL _inReady; + BOOL _outReady; +} + +- (void) activateView:(TapView*)view; +- (void) deactivateView:(TapView*)view; + +@end diff --git a/WiTap/AppController.m b/WiTap/AppController.m new file mode 100644 index 0000000..382386f --- /dev/null +++ b/WiTap/AppController.m @@ -0,0 +1,338 @@ +/* + File: AppController.m + Abstract: UIApplication's delegate class, the central controller of the application. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppController.h" +#import "Picker.h" + +#define kNumPads 3 + +// The Bonjour application protocol, which must: +// 1) be no longer than 14 characters +// 2) contain only lower-case letters, digits, and hyphens +// 3) begin and end with lower-case letter or digit +// It should also be descriptive and human-readable +// See the following for more information: +// http://developer.apple.com/networking/bonjour/faq.html +#define kGameIdentifier @"witap" + + +@interface AppController () +- (void) setup; +- (void) presentPicker:(NSString *)name; +@end + + +#pragma mark - +@implementation AppController + +- (void) _showAlert:(NSString *)title +{ + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:@"Check your networking configuration." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [alertView show]; + [alertView release]; +} + +- (void) applicationDidFinishLaunching:(UIApplication *)application +{ + CGRect rect; + UIView* view; + NSUInteger x, y; + + //Create a full-screen window + _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + [_window setBackgroundColor:[UIColor darkGrayColor]]; + + //Create the tap views and add them to the view controller's view + rect = [[UIScreen mainScreen] applicationFrame]; + for(y = 0; y < kNumPads; ++y) { + for(x = 0; x < kNumPads; ++x) { + view = [[TapView alloc] initWithFrame:CGRectMake(rect.origin.x + x * rect.size.width / (float)kNumPads, rect.origin.y + y * rect.size.height / (float)kNumPads, rect.size.width / (float)kNumPads, rect.size.height / (float)kNumPads)]; + [view setMultipleTouchEnabled:NO]; + [view setBackgroundColor:[UIColor colorWithHue:((y * kNumPads + x) / (float)(kNumPads * kNumPads)) saturation:0.75 brightness:0.75 alpha:1.0]]; + [view setTag:(y * kNumPads + x + 1)]; + [_window addSubview:view]; + [view release]; + } + } + + //Show the window + [_window makeKeyAndVisible]; + + //Create and advertise a new game and discover other availble games + [self setup]; +} + +- (void) dealloc +{ + [_inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [_inStream release]; + + [_outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [_outStream release]; + + [_server release]; + + [_picker release]; + + [_window release]; + + [super dealloc]; +} + +- (void) setup { + [_server release]; + _server = nil; + + [_inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [_inStream release]; + _inStream = nil; + _inReady = NO; + + [_outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [_outStream release]; + _outStream = nil; + _outReady = NO; + + _server = [TCPServer new]; + [_server setDelegate:self]; + NSError *error = nil; + if(_server == nil || ![_server start:&error]) { + if (error == nil) { + NSLog(@"Failed creating server: Server instance is nil"); + } else { + NSLog(@"Failed creating server: %@", error); + } + [self _showAlert:@"Failed creating server"]; + return; + } + + //Start advertising to clients, passing nil for the name to tell Bonjour to pick use default name + if(![_server enableBonjourWithDomain:@"local" applicationProtocol:[TCPServer bonjourTypeFromIdentifier:kGameIdentifier] name:nil]) { + [self _showAlert:@"Failed advertising server"]; + return; + } + + [self presentPicker:nil]; +} + +// Make sure to let the user know what name is being used for Bonjour advertisement. +// This way, other players can browse for and connect to this game. +// Note that this may be called while the alert is already being displayed, as +// Bonjour may detect a name conflict and rename dynamically. +- (void) presentPicker:(NSString *)name { + if (!_picker) { + _picker = [[Picker alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] type:[TCPServer bonjourTypeFromIdentifier:kGameIdentifier]]; + _picker.delegate = self; + } + + _picker.gameName = name; + + if (!_picker.superview) { + [_window addSubview:_picker]; + } +} + +- (void) destroyPicker { + [_picker removeFromSuperview]; + [_picker release]; + _picker = nil; +} + +// If we display an error or an alert that the remote disconnected, handle dismissal and return to setup +- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + [self setup]; +} + +- (void) send:(const uint8_t)message +{ + if (_outStream && [_outStream hasSpaceAvailable]) + if([_outStream write:(const uint8_t *)&message maxLength:sizeof(const uint8_t)] == -1) + [self _showAlert:@"Failed sending data to peer"]; +} + +- (void) activateView:(TapView *)view +{ + [self send:[view tag] | 0x80]; +} + +- (void) deactivateView:(TapView *)view +{ + [self send:[view tag] & 0x7f]; +} + +- (void) openStreams +{ + _inStream.delegate = self; + [_inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [_inStream open]; + _outStream.delegate = self; + [_outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [_outStream open]; +} + +- (void) browserViewController:(BrowserViewController *)bvc didResolveInstance:(NSNetService *)netService +{ + if (!netService) { + [self setup]; + return; + } + + // note the following method returns _inStream and _outStream with a retain count that the caller must eventually release + if (![netService getInputStream:&_inStream outputStream:&_outStream]) { + [self _showAlert:@"Failed connecting to server"]; + return; + } + + [self openStreams]; +} + +@end + + +#pragma mark - +@implementation AppController (NSStreamDelegate) + +- (void) stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode +{ + UIAlertView *alertView; + switch(eventCode) { + case NSStreamEventOpenCompleted: + { + [self destroyPicker]; + + [_server release]; + _server = nil; + + if (stream == _inStream) + _inReady = YES; + else + _outReady = YES; + + if (_inReady && _outReady) { + alertView = [[UIAlertView alloc] initWithTitle:@"Game started!" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil]; + [alertView show]; + [alertView release]; + } + break; + } + case NSStreamEventHasBytesAvailable: + { + if (stream == _inStream) { + uint8_t b; + int len = 0; + len = [_inStream read:&b maxLength:sizeof(uint8_t)]; + if(len <= 0) { + if ([stream streamStatus] != NSStreamStatusAtEnd) + [self _showAlert:@"Failed reading data from peer"]; + } else { + //We received a remote tap update, forward it to the appropriate view + if(b & 0x80) + [(TapView *)[_window viewWithTag:b & 0x7f] touchDown:YES]; + else + [(TapView *)[_window viewWithTag:b] touchUp:YES]; + } + } + break; + } + case NSStreamEventErrorOccurred: + { + NSLog(@"%s", _cmd); + [self _showAlert:@"Error encountered on stream!"]; + break; + } + + case NSStreamEventEndEncountered: + { + NSArray *array = [_window subviews]; + TapView *view; + UIAlertView *alertView; + + NSLog(@"%s", _cmd); + + //Notify all tap views + for(view in array) + [view touchUp:YES]; + + alertView = [[UIAlertView alloc] initWithTitle:@"Peer Disconnected!" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:@"Continue", nil]; + [alertView show]; + [alertView release]; + + break; + } + } +} + +@end + + +#pragma mark - +@implementation AppController (TCPServerDelegate) + +- (void) serverDidEnableBonjour:(TCPServer *)server withName:(NSString *)string +{ + NSLog(@"%s", _cmd); + [self presentPicker:string]; +} + +- (void)didAcceptConnectionForServer:(TCPServer *)server inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr +{ + if (_inStream || _outStream || server != _server) + return; + + [_server release]; + _server = nil; + + _inStream = istr; + [_inStream retain]; + _outStream = ostr; + [_outStream retain]; + + [self openStreams]; +} + +@end diff --git a/WiTap/Info.plist b/WiTap/Info.plist new file mode 100644 index 0000000..8bcba94 --- /dev/null +++ b/WiTap/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + LSRequiresIPhoneOS + + UIRequiresPersistentWiFi + + CFBundleVersion + 1.8 + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + + diff --git a/WiTap/Networking/BrowserViewController.h b/WiTap/Networking/BrowserViewController.h new file mode 100644 index 0000000..8c4ff69 --- /dev/null +++ b/WiTap/Networking/BrowserViewController.h @@ -0,0 +1,89 @@ +/* + File: BrowserViewController.h + Abstract: View controller for the service instance list. + This object manages a NSNetServiceBrowser configured to look for Bonjour services. + It has an array of NSNetService objects that are displayed in a table view. + When the service browser reports that it has discovered a service, the corresponding NSNetService is added to the array. + When a service goes away, the corresponding NSNetService is removed from the array. + Selecting an item in the table view asynchronously resolves the corresponding net service. + When that resolution completes, the delegate is called with the corresponding NSNetService. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@class BrowserViewController; + +@protocol BrowserViewControllerDelegate +@required +// This method will be invoked when the user selects one of the service instances from the list. +// The ref parameter will be the selected (already resolved) instance or nil if the user taps the 'Cancel' button (if shown). +- (void) browserViewController:(BrowserViewController *)bvc didResolveInstance:(NSNetService *)ref; +@end + +@interface BrowserViewController : UITableViewController { + +@private + id _delegate; + NSString *_searchingForServicesString; + NSString *_ownName; + NSNetService *_ownEntry; + BOOL _showDisclosureIndicators; + NSMutableArray *_services; + NSNetServiceBrowser *_netServiceBrowser; + NSNetService *_currentResolve; + NSTimer *_timer; + BOOL _needsActivityIndicator; + BOOL _initialWaitOver; +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, copy) NSString *searchingForServicesString; +@property (nonatomic, copy) NSString *ownName; + +- (id)initWithTitle:(NSString *)title showDisclosureIndicators:(BOOL)showDisclosureIndicators showCancelButton:(BOOL)showCancelButton; +- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain; + +@end diff --git a/WiTap/Networking/BrowserViewController.m b/WiTap/Networking/BrowserViewController.m new file mode 100644 index 0000000..ed2ff26 --- /dev/null +++ b/WiTap/Networking/BrowserViewController.m @@ -0,0 +1,400 @@ +/* + File: BrowserViewController.m + Abstract: View controller for the service instance list. + This object manages a NSNetServiceBrowser configured to look for Bonjour services. + It has an array of NSNetService objects that are displayed in a table view. + When the service browser reports that it has discovered a service, the corresponding NSNetService is added to the array. + When a service goes away, the corresponding NSNetService is removed from the array. + Selecting an item in the table view asynchronously resolves the corresponding net service. + When that resolution completes, the delegate is called with the corresponding NSNetService. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "BrowserViewController.h" + +#define kProgressIndicatorSize 20.0 + +// A category on NSNetService that's used to sort NSNetService objects by their name. +@interface NSNetService (BrowserViewControllerAdditions) +- (NSComparisonResult) localizedCaseInsensitiveCompareByName:(NSNetService *)aService; +@end + +@implementation NSNetService (BrowserViewControllerAdditions) +- (NSComparisonResult) localizedCaseInsensitiveCompareByName:(NSNetService *)aService { + return [[self name] localizedCaseInsensitiveCompare:[aService name]]; +} +@end + + +@interface BrowserViewController() +@property (nonatomic, retain, readwrite) NSNetService *ownEntry; +@property (nonatomic, assign, readwrite) BOOL showDisclosureIndicators; +@property (nonatomic, retain, readwrite) NSMutableArray *services; +@property (nonatomic, retain, readwrite) NSNetServiceBrowser *netServiceBrowser; +@property (nonatomic, retain, readwrite) NSNetService *currentResolve; +@property (nonatomic, retain, readwrite) NSTimer *timer; +@property (nonatomic, assign, readwrite) BOOL needsActivityIndicator; +@property (nonatomic, assign, readwrite) BOOL initialWaitOver; + +- (void)stopCurrentResolve; +- (void)initialWaitOver:(NSTimer *)timer; +@end + +@implementation BrowserViewController + +@synthesize delegate = _delegate; +@synthesize ownEntry = _ownEntry; +@synthesize showDisclosureIndicators = _showDisclosureIndicators; +@synthesize currentResolve = _currentResolve; +@synthesize netServiceBrowser = _netServiceBrowser; +@synthesize services = _services; +@synthesize needsActivityIndicator = _needsActivityIndicator; +@dynamic timer; +@synthesize initialWaitOver = _initialWaitOver; + + +- (id)initWithTitle:(NSString *)title showDisclosureIndicators:(BOOL)show showCancelButton:(BOOL)showCancelButton { + + if ((self = [super initWithStyle:UITableViewStylePlain])) { + self.title = title; + _services = [[NSMutableArray alloc] init]; + self.showDisclosureIndicators = show; + + if (showCancelButton) { + // add Cancel button as the nav bar's custom right view + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction)]; + self.navigationItem.rightBarButtonItem = addButton; + [addButton release]; + } + + // Make sure we have a chance to discover devices before showing the user that nothing was found (yet) + [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(initialWaitOver:) userInfo:nil repeats:NO]; + } + + return self; +} + +- (NSString *)searchingForServicesString { + return _searchingForServicesString; +} + +// Holds the string that's displayed in the table view during service discovery. +- (void)setSearchingForServicesString:(NSString *)searchingForServicesString { + if (_searchingForServicesString != searchingForServicesString) { + [_searchingForServicesString release]; + _searchingForServicesString = [searchingForServicesString copy]; + + // If there are no services, reload the table to ensure that searchingForServicesString appears. + if ([self.services count] == 0) { + [self.tableView reloadData]; + } + } +} + +- (NSString *)ownName { + return _ownName; +} + +// Holds the string that's displayed in the table view during service discovery. +- (void)setOwnName:(NSString *)name { + if (_ownName != name) { + _ownName = [name copy]; + + if (self.ownEntry) + [self.services addObject:self.ownEntry]; + + NSNetService* service; + + for (service in self.services) { + if ([service.name isEqual:name]) { + self.ownEntry = service; + [_services removeObject:service]; + break; + } + } + + [self.tableView reloadData]; + } +} + +// Creates an NSNetServiceBrowser that searches for services of a particular type in a particular domain. +// If a service is currently being resolved, stop resolving it and stop the service browser from +// discovering other services. +- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain { + + [self stopCurrentResolve]; + [self.netServiceBrowser stop]; + [self.services removeAllObjects]; + + NSNetServiceBrowser *aNetServiceBrowser = [[NSNetServiceBrowser alloc] init]; + if(!aNetServiceBrowser) { + // The NSNetServiceBrowser couldn't be allocated and initialized. + return NO; + } + + aNetServiceBrowser.delegate = self; + self.netServiceBrowser = aNetServiceBrowser; + [aNetServiceBrowser release]; + [self.netServiceBrowser searchForServicesOfType:type inDomain:domain]; + + [self.tableView reloadData]; + return YES; +} + +- (NSTimer *)timer { + return _timer; +} + +// When this is called, invalidate the existing timer before releasing it. +- (void)setTimer:(NSTimer *)newTimer { + [_timer invalidate]; + [newTimer retain]; + [_timer release]; + _timer = newTimer; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // If there are no services and searchingForServicesString is set, show one row to tell the user. + NSUInteger count = [self.services count]; + if (count == 0 && self.searchingForServicesString && self.initialWaitOver) + return 1; + + return count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *tableCellIdentifier = @"UITableViewCell"; + UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableCellIdentifier] autorelease]; + } + + NSUInteger count = [self.services count]; + if (count == 0 && self.searchingForServicesString) { + // If there are no services and searchingForServicesString is set, show one row explaining that to the user. + cell.textLabel.text = self.searchingForServicesString; + cell.textLabel.textColor = [UIColor colorWithWhite:0.5 alpha:0.5]; + cell.accessoryType = UITableViewCellAccessoryNone; + // Make sure to get rid of the activity indicator that may be showing if we were resolving cell zero but + // then got didRemoveService callbacks for all services (e.g. the network connection went down). + if (cell.accessoryView) + cell.accessoryView = nil; + return cell; + } + + // Set up the text for the cell + NSNetService *service = [self.services objectAtIndex:indexPath.row]; + cell.textLabel.text = [service name]; + cell.textLabel.textColor = [UIColor blackColor]; + cell.accessoryType = self.showDisclosureIndicators ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + // Note that the underlying array could have changed, and we want to show the activity indicator on the correct cell + if (self.needsActivityIndicator && self.currentResolve == service) { + if (!cell.accessoryView) { + CGRect frame = CGRectMake(0.0, 0.0, kProgressIndicatorSize, kProgressIndicatorSize); + UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithFrame:frame]; + [spinner startAnimating]; + spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; + [spinner sizeToFit]; + spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | + UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleTopMargin | + UIViewAutoresizingFlexibleBottomMargin); + cell.accessoryView = spinner; + [spinner release]; + } + } else if (cell.accessoryView) { + cell.accessoryView = nil; + } + + return cell; +} + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // Ignore the selection if there are no services as the searchingForServicesString cell + // may be visible and tapping it would do nothing + if ([self.services count] == 0) + return nil; + + return indexPath; +} + +- (void)stopCurrentResolve { + + self.needsActivityIndicator = NO; + self.timer = nil; + + [self.currentResolve stop]; + self.currentResolve = nil; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // If another resolve was running, stop it & remove the activity indicator from that cell + if (self.currentResolve) { + // Get the indexPath for the active resolve cell + NSIndexPath* indexPath = [NSIndexPath indexPathForRow:[self.services indexOfObject:self.currentResolve] inSection:0]; + + // Stop the current resolve, which will also set self.needsActivityIndicator + [self stopCurrentResolve]; + + // If we found the indexPath for the row, reload that cell to remove the activity indicator + if (indexPath.row != NSNotFound) + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; + } + + // Then set the current resolve to the service corresponding to the tapped cell + self.currentResolve = [self.services objectAtIndex:indexPath.row]; + [self.currentResolve setDelegate:self]; + + // Attempt to resolve the service. A value of 0.0 sets an unlimited time to resolve it. The user can + // choose to cancel the resolve by selecting another service in the table view. + [self.currentResolve resolveWithTimeout:0.0]; + + // Make sure we give the user some feedback that the resolve is happening. + // We will be called back asynchronously, so we don't want the user to think we're just stuck. + // We delay showing this activity indicator in case the service is resolved quickly. + self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showWaiting:) userInfo:self.currentResolve repeats:NO]; +} + +// If necessary, sets up state to show an activity indicator to let the user know that a resolve is occuring. +- (void)showWaiting:(NSTimer *)timer { + if (timer == self.timer) { + NSNetService* service = (NSNetService*)[self.timer userInfo]; + if (self.currentResolve == service) { + self.needsActivityIndicator = YES; + + NSIndexPath* indexPath = [NSIndexPath indexPathForRow:[self.services indexOfObject:self.currentResolve] inSection:0]; + if (indexPath.row != NSNotFound) { + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; + // Deselect the row since the activity indicator shows the user something is happening. + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + } + } + } +} + +- (void)initialWaitOver:(NSTimer *)timer { + self.initialWaitOver= YES; + if (![self.services count]) + [self.tableView reloadData]; +} + +- (void)sortAndUpdateUI { + // Sort the services by name. + [self.services sortUsingSelector:@selector(localizedCaseInsensitiveCompareByName:)]; + [self.tableView reloadData]; +} + +- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing { + // If a service went away, stop resolving it if it's currently being resolved, + // remove it from the list and update the table view if no more events are queued. + + if (self.currentResolve && [service isEqual:self.currentResolve]) { + [self stopCurrentResolve]; + } + [self.services removeObject:service]; + if (self.ownEntry == service) + self.ownEntry = nil; + + // If moreComing is NO, it means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI. + // When moreComing is set, we don't update the UI so that it doesn't 'flash'. + if (!moreComing) { + [self sortAndUpdateUI]; + } +} + +- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing { + // If a service came online, add it to the list and update the table view if no more events are queued. + if ([service.name isEqual:self.ownName]) + self.ownEntry = service; + else + [self.services addObject:service]; + + // If moreComing is NO, it means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI. + // When moreComing is set, we don't update the UI so that it doesn't 'flash'. + if (!moreComing) { + [self sortAndUpdateUI]; + } +} + +// This should never be called, since we resolve with a timeout of 0.0, which means indefinite +- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict { + [self stopCurrentResolve]; + [self.tableView reloadData]; +} + +- (void)netServiceDidResolveAddress:(NSNetService *)service { + assert(service == self.currentResolve); + + [service retain]; + [self stopCurrentResolve]; + + [self.delegate browserViewController:self didResolveInstance:service]; + [service release]; +} + +- (void)cancelAction { + [self.delegate browserViewController:self didResolveInstance:nil]; +} + +- (void)dealloc { + // Cleanup any running resolve and free memory + [self stopCurrentResolve]; + self.services = nil; + [self.netServiceBrowser stop]; + self.netServiceBrowser = nil; + [_searchingForServicesString release]; + [_ownName release]; + [_ownEntry release]; + + [super dealloc]; +} + +@end diff --git a/WiTap/Networking/TCPServer.h b/WiTap/Networking/TCPServer.h new file mode 100644 index 0000000..1ef83ec --- /dev/null +++ b/WiTap/Networking/TCPServer.h @@ -0,0 +1,87 @@ +/* + File: TCPServer.h + Abstract: A TCP server that listens on an arbitrary port. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@class TCPServer; + +NSString * const TCPServerErrorDomain; + +typedef enum { + kTCPServerCouldNotBindToIPv4Address = 1, + kTCPServerCouldNotBindToIPv6Address = 2, + kTCPServerNoSocketsAvailable = 3, +} TCPServerErrorCode; + + +@protocol TCPServerDelegate +@optional +- (void) serverDidEnableBonjour:(TCPServer*)server withName:(NSString*)name; +- (void) server:(TCPServer*)server didNotEnableBonjour:(NSDictionary *)errorDict; +- (void) didAcceptConnectionForServer:(TCPServer*)server inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr; +@end + + +@interface TCPServer : NSObject { +@private + id _delegate; + uint16_t _port; + uint32_t protocolFamily; + CFSocketRef witap_socket; + NSNetService* _netService; +} + +- (BOOL)start:(NSError **)error; +- (BOOL)stop; +- (BOOL) enableBonjourWithDomain:(NSString*)domain applicationProtocol:(NSString*)protocol name:(NSString*)name; //Pass "nil" for the default local domain - Pass only the application protocol for "protocol" e.g. "myApp" +- (void) disableBonjour; + +@property(assign) id delegate; + ++ (NSString*) bonjourTypeFromIdentifier:(NSString*)identifier; + +@end diff --git a/WiTap/Networking/TCPServer.m b/WiTap/Networking/TCPServer.m new file mode 100644 index 0000000..00f80a6 --- /dev/null +++ b/WiTap/Networking/TCPServer.m @@ -0,0 +1,278 @@ +/* + File: TCPServer.m + Abstract: A TCP server that listens on an arbitrary port. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include +#include +#include +#include + +#import "TCPServer.h" + +NSString * const TCPServerErrorDomain = @"TCPServerErrorDomain"; + +@interface TCPServer () +@property(nonatomic,retain) NSNetService* netService; +@property(assign) uint16_t port; +@end + +@implementation TCPServer + +@synthesize delegate=_delegate, netService=_netService, port=_port; + +- (id)init { + return self; +} + +- (void)dealloc { + [self stop]; + [super dealloc]; +} + +- (void)handleNewConnectionFromAddress:(NSData *)addr inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr { + // if the delegate implements the delegate method, call it + if (self.delegate && [self.delegate respondsToSelector:@selector(didAcceptConnectionForServer:inputStream:outputStream:)]) { + [self.delegate didAcceptConnectionForServer:self inputStream:istr outputStream:ostr]; + } +} + +// This function is called by CFSocket when a new connection comes in. +// We gather some data here, and convert the function call to a method +// invocation on TCPServer. +static void TCPServerAcceptCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { + TCPServer *server = (TCPServer *)info; + if (kCFSocketAcceptCallBack == type) { + // for an AcceptCallBack, the data parameter is a pointer to a CFSocketNativeHandle + CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle *)data; + uint8_t name[SOCK_MAXADDRLEN]; + socklen_t namelen = sizeof(name); + NSData *peer = nil; + if (0 == getpeername(nativeSocketHandle, (struct sockaddr *)name, &namelen)) { + peer = [NSData dataWithBytes:name length:namelen]; + } + CFReadStreamRef readStream = NULL; + CFWriteStreamRef writeStream = NULL; + CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &readStream, &writeStream); + if (readStream && writeStream) { + CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); + CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); + [server handleNewConnectionFromAddress:peer inputStream:(NSInputStream *)readStream outputStream:(NSOutputStream *)writeStream]; + } else { + // on any failure, need to destroy the CFSocketNativeHandle + // since we are not going to use it any more + close(nativeSocketHandle); + } + if (readStream) CFRelease(readStream); + if (writeStream) CFRelease(writeStream); + } +} + +- (BOOL)start:(NSError **)error { + + CFSocketContext socketCtxt = {0, self, NULL, NULL, NULL}; + + // Start by trying to do everything with IPv6. This will work for both IPv4 and IPv6 clients + // via the miracle of mapped IPv4 addresses. + + witap_socket = CFSocketCreate(kCFAllocatorDefault, PF_INET6, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)&TCPServerAcceptCallBack, &socketCtxt); + + if (witap_socket != NULL) // the socket was created successfully + { + protocolFamily = PF_INET6; + } else // there was an error creating the IPv6 socket - could be running under iOS 3.x + { + witap_socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)&TCPServerAcceptCallBack, &socketCtxt); + if (witap_socket != NULL) + { + protocolFamily = PF_INET; + } + } + + if (NULL == witap_socket) { + if (error) *error = [[NSError alloc] initWithDomain:TCPServerErrorDomain code:kTCPServerNoSocketsAvailable userInfo:nil]; + if (witap_socket) CFRelease(witap_socket); + witap_socket = NULL; + return NO; + } + + + int yes = 1; + setsockopt(CFSocketGetNative(witap_socket), SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)); + + // set up the IP endpoint; use port 0, so the kernel will choose an arbitrary port for us, which will be advertised using Bonjour + if (protocolFamily == PF_INET6) + { + struct sockaddr_in6 addr6; + memset(&addr6, 0, sizeof(addr6)); + addr6.sin6_len = sizeof(addr6); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = 0; + addr6.sin6_flowinfo = 0; + addr6.sin6_addr = in6addr_any; + NSData *address6 = [NSData dataWithBytes:&addr6 length:sizeof(addr6)]; + + if (kCFSocketSuccess != CFSocketSetAddress(witap_socket, (CFDataRef)address6)) { + if (error) *error = [[NSError alloc] initWithDomain:TCPServerErrorDomain code:kTCPServerCouldNotBindToIPv6Address userInfo:nil]; + if (witap_socket) CFRelease(witap_socket); + witap_socket = NULL; + return NO; + } + + // now that the binding was successful, we get the port number + // -- we will need it for the NSNetService + NSData *addr = [(NSData *)CFSocketCopyAddress(witap_socket) autorelease]; + memcpy(&addr6, [addr bytes], [addr length]); + self.port = ntohs(addr6.sin6_port); + + } else { + struct sockaddr_in addr4; + memset(&addr4, 0, sizeof(addr4)); + addr4.sin_len = sizeof(addr4); + addr4.sin_family = AF_INET; + addr4.sin_port = 0; + addr4.sin_addr.s_addr = htonl(INADDR_ANY); + NSData *address4 = [NSData dataWithBytes:&addr4 length:sizeof(addr4)]; + + if (kCFSocketSuccess != CFSocketSetAddress(witap_socket, (CFDataRef)address4)) { + if (error) *error = [[NSError alloc] initWithDomain:TCPServerErrorDomain code:kTCPServerCouldNotBindToIPv4Address userInfo:nil]; + if (witap_socket) CFRelease(witap_socket); + witap_socket = NULL; + return NO; + } + + // now that the binding was successful, we get the port number + // -- we will need it for the NSNetService + NSData *addr = [(NSData *)CFSocketCopyAddress(witap_socket) autorelease]; + memcpy(&addr4, [addr bytes], [addr length]); + self.port = ntohs(addr4.sin_port); + } + + // set up the run loop sources for the sockets + CFRunLoopRef cfrl = CFRunLoopGetCurrent(); + CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, witap_socket, 0); + CFRunLoopAddSource(cfrl, source, kCFRunLoopCommonModes); + CFRelease(source); + + return YES; +} + +- (BOOL)stop { + [self disableBonjour]; + + if (witap_socket) { + CFSocketInvalidate(witap_socket); + CFRelease(witap_socket); + witap_socket = NULL; + } + + + return YES; +} + +- (BOOL) enableBonjourWithDomain:(NSString*)domain applicationProtocol:(NSString*)protocol name:(NSString*)name +{ + if(![domain length]) + domain = @""; //Will use default Bonjour registration doamins, typically just ".local" + if(![name length]) + name = @""; //Will use default Bonjour name, e.g. the name assigned to the device in iTunes + + if(!protocol || ![protocol length] || witap_socket == NULL) + return NO; + + + self.netService = [[NSNetService alloc] initWithDomain:domain type:protocol name:name port:self.port]; + if(self.netService == nil) + return NO; + + [self.netService scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [self.netService publish]; + [self.netService setDelegate:self]; + + return YES; +} + +/* + Bonjour will not allow conflicting service instance names (in the same domain), and may have automatically renamed + the service if there was a conflict. We pass the name back to the delegate so that the name can be displayed to + the user. + See http://developer.apple.com/networking/bonjour/faq.html for more information. + */ + +- (void)netServiceDidPublish:(NSNetService *)sender +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(serverDidEnableBonjour:withName:)]) + [self.delegate serverDidEnableBonjour:self withName:sender.name]; +} + +- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(server:didNotEnableBonjour:)]) + [self.delegate server:self didNotEnableBonjour:errorDict]; +} + +- (void) disableBonjour +{ + if (self.netService) { + NSLog(@"about to call NetService:stop"); + [self.netService stop]; + [self.netService removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + self.netService = nil; + } +} + +- (NSString*) description +{ + return [NSString stringWithFormat:@"<%@ = 0x%08X | port %d | netService = %@>", [self class], (long)self, self.port, self.netService]; +} + ++ (NSString*) bonjourTypeFromIdentifier:(NSString*)identifier { + if (![identifier length]) + return nil; + + return [NSString stringWithFormat:@"_%@._tcp.", identifier]; +} + +@end diff --git a/WiTap/Picker.h b/WiTap/Picker.h new file mode 100644 index 0000000..cd80bcb --- /dev/null +++ b/WiTap/Picker.h @@ -0,0 +1,64 @@ +/* + File: Picker.h + Abstract: A view that displays both the currently advertised game name and a list of other games + available on the local network - discovered & displayed by BrowserViewController. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "BrowserViewController.h" + +@interface Picker : UIView { + +@private + UILabel *_gameNameLabel; + BrowserViewController *_bvc; +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, copy) NSString *gameName; + +- (id)initWithFrame:(CGRect)frame type:(NSString *)type; + +@end diff --git a/WiTap/Picker.m b/WiTap/Picker.m new file mode 100644 index 0000000..0cfe6af --- /dev/null +++ b/WiTap/Picker.m @@ -0,0 +1,161 @@ +/* + File: Picker.m + Abstract: A view that displays both the currently advertised game name and a list of other games + available on the local network - discovered & displayed by BrowserViewController. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Picker.h" + +#define kOffset 5.0 + +@interface Picker () +@property (nonatomic, retain, readwrite) BrowserViewController *bvc; +@property (nonatomic, retain, readwrite) UILabel *gameNameLabel; +@end + +@implementation Picker + +@synthesize bvc = _bvc; +@synthesize gameNameLabel = _gameNameLabel; + +- (id)initWithFrame:(CGRect)frame type:(NSString*)type { + if ((self = [super initWithFrame:frame])) { + // add autorelease to the NSNetServiceBrowser to release the browser once the connection has been + // established. An active browser can cause a delay in sending data. + // + self.bvc = [[[BrowserViewController alloc] initWithTitle:nil showDisclosureIndicators:NO showCancelButton:NO]autorelease]; + [self.bvc searchForServicesOfType:type inDomain:@"local"]; + + self.opaque = YES; + self.backgroundColor = [UIColor blackColor]; + + UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg.png"]]; + [self addSubview:img]; + [img release]; + + CGFloat runningY = kOffset; + CGFloat width = self.bounds.size.width - 2 * kOffset; + + UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero]; + [label setTextAlignment:UITextAlignmentCenter]; + [label setFont:[UIFont boldSystemFontOfSize:15.0]]; + [label setTextColor:[UIColor whiteColor]]; + [label setShadowColor:[UIColor colorWithWhite:0.0 alpha:0.75]]; + [label setShadowOffset:CGSizeMake(1,1)]; + [label setBackgroundColor:[UIColor clearColor]]; + label.text = @"Waiting for another player to join game:"; + label.numberOfLines = 1; + [label sizeToFit]; + label.frame = CGRectMake(kOffset, runningY, width, label.frame.size.height); + [self addSubview:label]; + + runningY += label.bounds.size.height; + [label release]; + + self.gameNameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + [self.gameNameLabel setTextAlignment:UITextAlignmentCenter]; + [self.gameNameLabel setFont:[UIFont boldSystemFontOfSize:24.0]]; + [self.gameNameLabel setLineBreakMode:UILineBreakModeTailTruncation]; + [self.gameNameLabel setTextColor:[UIColor whiteColor]]; + [self.gameNameLabel setShadowColor:[UIColor colorWithWhite:0.0 alpha:0.75]]; + [self.gameNameLabel setShadowOffset:CGSizeMake(1,1)]; + [self.gameNameLabel setBackgroundColor:[UIColor clearColor]]; + [self.gameNameLabel setText:@"Default Name"]; + [self.gameNameLabel sizeToFit]; + [self.gameNameLabel setFrame:CGRectMake(kOffset, runningY, width, self.gameNameLabel.frame.size.height)]; + [self.gameNameLabel setText:@""]; + [self addSubview:self.gameNameLabel]; + + runningY += self.gameNameLabel.bounds.size.height + kOffset * 2; + + label = [[UILabel alloc] initWithFrame:CGRectZero]; + [label setTextAlignment:UITextAlignmentCenter]; + [label setFont:[UIFont boldSystemFontOfSize:15.0]]; + [label setTextColor:[UIColor whiteColor]]; + [label setShadowColor:[UIColor colorWithWhite:0.0 alpha:0.75]]; + [label setShadowOffset:CGSizeMake(1,1)]; + [label setBackgroundColor:[UIColor clearColor]]; + label.text = @"Or, join a different game:"; + label.numberOfLines = 1; + [label sizeToFit]; + label.frame = CGRectMake(kOffset, runningY, width, label.frame.size.height); + [self addSubview:label]; + + runningY += label.bounds.size.height + 2; + + [self.bvc.view setFrame:CGRectMake(0, runningY, self.bounds.size.width, self.bounds.size.height - runningY)]; + [self addSubview:self.bvc.view]; + + } + + return self; +} + +- (void)dealloc { + // Cleanup any running resolve and free memory + [self.bvc release]; + [self.gameNameLabel release]; + + [super dealloc]; +} + +- (id)delegate { + return self.bvc.delegate; +} + +- (void)setDelegate:(id)delegate { + [self.bvc setDelegate:delegate]; +} + +- (NSString *)gameName { + return self.gameNameLabel.text; +} + +- (void)setGameName:(NSString *)string { + [self.gameNameLabel setText:string]; + [self.bvc setOwnName:string]; +} + +@end diff --git a/WiTap/Prefix.pch b/WiTap/Prefix.pch new file mode 100644 index 0000000..4cf6a74 --- /dev/null +++ b/WiTap/Prefix.pch @@ -0,0 +1,3 @@ +#ifdef __OBJC__ + #import +#endif diff --git a/WiTap/ReadMe.txt b/WiTap/ReadMe.txt new file mode 100644 index 0000000..3cb6df9 --- /dev/null +++ b/WiTap/ReadMe.txt @@ -0,0 +1,87 @@ +WiTap + +================================================================================ +DESCRIPTION: + +The WiTap sample application demonstrates how to achieve network communication between applications. Using Bonjour, the application both advertises itself on the local network and displays a list of other instances of this application on the network. + +Simply build the sample using Xcode and run it in the simulator or on the device. Wait for another player to connect or select a game to connect to. Once connected, tap one or more colored pads on a device to see them highlighted simultaneously on the remote device. + +This sample also demonstrates peer to peer connectivity over Bluetooth, available in iOS 3.0 and later on supported hardware: Bonjour will automatically advertise and discover instances of this application over Bluetooth, and when an instance is resolved, Bonjour will automatically use Bluetooth to connect the two applications. + +Checking for the presence of networking is beyond the scope of this sample. + +=========================================================================== +BUILD REQUIREMENTS: + +Mac OS X 10.6.4, iOS 4.1 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iOS 3.1.3 or later + +=========================================================================== +PACKAGING LIST: + +AppController.h +AppController.m +UIApplication's delegate class, the central controller of the application. + +TapView.h +TapView.m +UIView subclass that can highlight itself when locally or remotely tapped. + +Picker.h +Picker.m +A view that displays both the currently advertised game name and a list of other games +available on the local network (discovered & displayed by BrowserViewController). + +Networking/TCPServer.h +Networking/TCPServer.m +A TCP server that listens on an arbitrary port. + +Networking/BrowserViewController.h +Networking/BrowserViewController.m +View controller for the service instance list. +This object manages a NSNetServiceBrowser configured to look for Bonjour services. +It has an array of NSNetService objects that are displayed in a table view. +When the service browser reports that it has discovered a service, the corresponding NSNetService is added to the array. +When a service goes away, the corresponding NSNetService is removed from the array. +Selecting an item in the table view asynchronously resolves the corresponding net service. +When that resolution completes, the delegate is called with the corresponding net service. + +main.m +The main file for the WiTap application. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.8 +- Upgraded project to build with the iOS 4.1 SDK +- Implemented an autorelease to the NSNetServiceBrowser object to release the browser once the connection is established. An active browser can cause a delay in sending packets - +- Upgraded for IPv6 as default, creates IPv4 socket is unable to create IPv6 socket. +- fixed logic bug in handleEvent to check for read method failure. + +Version 1.7 +- Fixed table selection and cell update bugs, and added support for handling stream errors. + +Version 1.6 +- Upgraded for 3.0 SDK due to deprecated APIs; in "cellForRowAtIndexPath" it now uses UITableViewCell's initWithStyle. + +Version 1.5 +- Updated for and tested with iPhone OS 2.0. First public release. + +Version 1.4 +- Updated for Beta 7. +- Code clean up. +- Improved Bonjour support. + +Version 1.3 +- Updated for Beta 4. +- Added code signing. + +Version 1.2 +- Added icon. + +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/WiTap/TapView.h b/WiTap/TapView.h new file mode 100644 index 0000000..ecff4de --- /dev/null +++ b/WiTap/TapView.h @@ -0,0 +1,59 @@ +/* + File: TapView.h + Abstract: UIView subclass that can highlight itself when locally or remotely tapped. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface TapView : UIView +{ + BOOL localTouch; + BOOL remoteTouch; +} + +- (void) touchDown:(BOOL)remote; +- (void) touchUp:(BOOL)remote; + +@end diff --git a/WiTap/TapView.m b/WiTap/TapView.m new file mode 100644 index 0000000..a2b87d4 --- /dev/null +++ b/WiTap/TapView.m @@ -0,0 +1,108 @@ +/* + File: TapView.m + Abstract: UIView subclass that can highlight itself when locally or remotely tapped. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppController.h" + +#define kActivationInset 10 + +@implementation TapView + +- (void) touchDown:(BOOL)remote +{ + // set "tap down" visual state if necessary + if(!localTouch && !remoteTouch) + self.frame=CGRectInset(self.frame, kActivationInset, kActivationInset); + + if (remote) + remoteTouch = YES; + else + localTouch = YES; +} + +- (void) touchUp:(BOOL)remote +{ + BOOL wasDown = localTouch || remoteTouch; + + if (remote) + remoteTouch = NO; + else + localTouch = NO; + + BOOL isDown = localTouch || remoteTouch; + + // run "tap up" visual animation if necessary + if(wasDown != isDown) { + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:0.1]; + self.frame = CGRectInset(self.frame, -kActivationInset, -kActivationInset); + [UIView commitAnimations]; + } +} + +- (void) localTouchUp +{ + [self touchUp:NO]; + [(AppController*)[[UIApplication sharedApplication] delegate] deactivateView:self]; +} + +- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event +{ + [self touchDown:NO]; + [(AppController*)[[UIApplication sharedApplication] delegate] activateView:self]; +} + +- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event +{ + [self localTouchUp]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self localTouchUp]; +} + +@end diff --git a/WiTap/WiTap.xcodeproj/project.pbxproj b/WiTap/WiTap.xcodeproj/project.pbxproj new file mode 100755 index 0000000..9cc1c8c --- /dev/null +++ b/WiTap/WiTap.xcodeproj/project.pbxproj @@ -0,0 +1,335 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 188D407F0D6D2F160076AE1E /* TapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 188D407D0D6D2F160076AE1E /* TapView.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 2B9195C511E66BE90007EFA5 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B9195C411E66BE90007EFA5 /* CoreGraphics.framework */; }; + 2B9195C711E66BE90007EFA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B9195C611E66BE90007EFA5 /* Foundation.framework */; }; + 2B9195C911E66BE90007EFA5 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B9195C811E66BE90007EFA5 /* SystemConfiguration.framework */; }; + 2B9195CB11E66BE90007EFA5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B9195CA11E66BE90007EFA5 /* UIKit.framework */; }; + 2B91971F11E6744A0007EFA5 /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971611E6744A0007EFA5 /* bg.png */; }; + 2B91972011E6744A0007EFA5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971711E6744A0007EFA5 /* Default.png */; }; + 2B91972111E6744A0007EFA5 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971811E6744A0007EFA5 /* Icon-72.png */; }; + 2B91972211E6744A0007EFA5 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971911E6744A0007EFA5 /* Icon-Small-50.png */; }; + 2B91972311E6744A0007EFA5 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971A11E6744A0007EFA5 /* Icon-Small.png */; }; + 2B91972411E6744A0007EFA5 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971B11E6744A0007EFA5 /* Icon-Small@2x.png */; }; + 2B91972511E6744A0007EFA5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971C11E6744A0007EFA5 /* Icon.png */; }; + 2B91972611E6744A0007EFA5 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971D11E6744A0007EFA5 /* Icon@2x.png */; }; + 2B91972711E6744A0007EFA5 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 2B91971E11E6744A0007EFA5 /* iTunesArtwork */; }; + 2D500B1C0D5A766900DBA0E3 /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D500B1B0D5A766900DBA0E3 /* AppController.m */; }; + 2D500FA20D5A86A600DBA0E3 /* TCPServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D500F920D5A86A600DBA0E3 /* TCPServer.m */; }; + 4A50295F0DF7068E00D72A3B /* BrowserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A50295E0DF7068E00D72A3B /* BrowserViewController.m */; }; + 4AFB75470DF7691E00DCF235 /* Picker.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AFB75460DF7691E00DCF235 /* Picker.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 188D407D0D6D2F160076AE1E /* TapView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TapView.m; sourceTree = ""; }; + 188D407E0D6D2F160076AE1E /* TapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TapView.h; sourceTree = ""; }; + 1BFA8F9A0DA6BA0400E6B5C8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* WiTap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WiTap.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B9195C411E66BE90007EFA5 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2B9195C611E66BE90007EFA5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2B9195C811E66BE90007EFA5 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 2B9195CA11E66BE90007EFA5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2B91971611E6744A0007EFA5 /* bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bg.png; path = Images/bg.png; sourceTree = ""; }; + 2B91971711E6744A0007EFA5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Images/Default.png; sourceTree = ""; }; + 2B91971811E6744A0007EFA5 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Images/Icon-72.png"; sourceTree = ""; }; + 2B91971911E6744A0007EFA5 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Images/Icon-Small-50.png"; sourceTree = ""; }; + 2B91971A11E6744A0007EFA5 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Images/Icon-Small.png"; sourceTree = ""; }; + 2B91971B11E6744A0007EFA5 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "Images/Icon-Small@2x.png"; sourceTree = ""; }; + 2B91971C11E6744A0007EFA5 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = ""; }; + 2B91971D11E6744A0007EFA5 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Images/Icon@2x.png"; sourceTree = ""; }; + 2B91971E11E6744A0007EFA5 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = Images/iTunesArtwork; sourceTree = ""; }; + 2B91972911E675710007EFA5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2D500B1A0D5A766900DBA0E3 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = ""; }; + 2D500B1B0D5A766900DBA0E3 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = ""; }; + 2D500F910D5A86A600DBA0E3 /* TCPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TCPServer.h; path = Networking/TCPServer.h; sourceTree = ""; }; + 2D500F920D5A86A600DBA0E3 /* TCPServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TCPServer.m; path = Networking/TCPServer.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 4A50295D0DF7068E00D72A3B /* BrowserViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserViewController.h; path = Networking/BrowserViewController.h; sourceTree = ""; }; + 4A50295E0DF7068E00D72A3B /* BrowserViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserViewController.m; path = Networking/BrowserViewController.m; sourceTree = ""; }; + 4AFB75450DF7691E00DCF235 /* Picker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Picker.h; sourceTree = ""; }; + 4AFB75460DF7691E00DCF235 /* Picker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Picker.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B9195C511E66BE90007EFA5 /* CoreGraphics.framework in Frameworks */, + 2B9195C711E66BE90007EFA5 /* Foundation.framework in Frameworks */, + 2B9195C911E66BE90007EFA5 /* SystemConfiguration.framework in Frameworks */, + 2B9195CB11E66BE90007EFA5 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* WiTap.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 1BFA8F9A0DA6BA0400E6B5C8 /* ReadMe.txt */, + 2D500B1D0D5A766B00DBA0E3 /* Classes */, + 2D500B6F0D5A793600DBA0E3 /* Support */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 2B91972911E675710007EFA5 /* Info.plist */, + 2B91971611E6744A0007EFA5 /* bg.png */, + 2B91971711E6744A0007EFA5 /* Default.png */, + 2B91971811E6744A0007EFA5 /* Icon-72.png */, + 2B91971911E6744A0007EFA5 /* Icon-Small-50.png */, + 2B91971A11E6744A0007EFA5 /* Icon-Small.png */, + 2B91971B11E6744A0007EFA5 /* Icon-Small@2x.png */, + 2B91971C11E6744A0007EFA5 /* Icon.png */, + 2B91971D11E6744A0007EFA5 /* Icon@2x.png */, + 2B91971E11E6744A0007EFA5 /* iTunesArtwork */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B9195C411E66BE90007EFA5 /* CoreGraphics.framework */, + 2B9195C611E66BE90007EFA5 /* Foundation.framework */, + 2B9195C811E66BE90007EFA5 /* SystemConfiguration.framework */, + 2B9195CA11E66BE90007EFA5 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2D500B1D0D5A766B00DBA0E3 /* Classes */ = { + isa = PBXGroup; + children = ( + 2D500B1A0D5A766900DBA0E3 /* AppController.h */, + 2D500B1B0D5A766900DBA0E3 /* AppController.m */, + 188D407E0D6D2F160076AE1E /* TapView.h */, + 188D407D0D6D2F160076AE1E /* TapView.m */, + 4AFB75450DF7691E00DCF235 /* Picker.h */, + 4AFB75460DF7691E00DCF235 /* Picker.m */, + ); + name = Classes; + sourceTree = ""; + }; + 2D500B6F0D5A793600DBA0E3 /* Support */ = { + isa = PBXGroup; + children = ( + 4A50295D0DF7068E00D72A3B /* BrowserViewController.h */, + 4A50295E0DF7068E00D72A3B /* BrowserViewController.m */, + 2D500F910D5A86A600DBA0E3 /* TCPServer.h */, + 2D500F920D5A86A600DBA0E3 /* TCPServer.m */, + ); + name = Support; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* WiTap */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "WiTap" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WiTap; + productName = foo; + productReference = 1D6058910D05DD3D006BFB54 /* WiTap.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WiTap" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* WiTap */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B91971F11E6744A0007EFA5 /* bg.png in Resources */, + 2B91972011E6744A0007EFA5 /* Default.png in Resources */, + 2B91972111E6744A0007EFA5 /* Icon-72.png in Resources */, + 2B91972211E6744A0007EFA5 /* Icon-Small-50.png in Resources */, + 2B91972311E6744A0007EFA5 /* Icon-Small.png in Resources */, + 2B91972411E6744A0007EFA5 /* Icon-Small@2x.png in Resources */, + 2B91972511E6744A0007EFA5 /* Icon.png in Resources */, + 2B91972611E6744A0007EFA5 /* Icon@2x.png in Resources */, + 2B91972711E6744A0007EFA5 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2D500B1C0D5A766900DBA0E3 /* AppController.m in Sources */, + 2D500FA20D5A86A600DBA0E3 /* TCPServer.m in Sources */, + 188D407F0D6D2F160076AE1E /* TapView.m in Sources */, + 4A50295F0DF7068E00D72A3B /* BrowserViewController.m in Sources */, + 4AFB75470DF7691E00DCF235 /* Picker.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( + "-framework", + CFNetwork, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator2.0][arch=*]" = ( + "-framework", + CoreServices, + ); + PREBINDING = NO; + PRODUCT_NAME = WiTap; + WARNING_CFLAGS = "-Wall"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + INFOPLIST_FILE = Info.plist; + "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( + "-framework", + CFNetwork, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator2.0][arch=*]" = ( + "-framework", + CoreServices, + ); + PREBINDING = NO; + PRODUCT_NAME = WiTap; + WARNING_CFLAGS = "-Wall"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + SDKROOT = iphoneos4.1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "WiTap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WiTap" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/WiTap/images/Default.png b/WiTap/images/Default.png new file mode 100644 index 0000000..602f3fd Binary files /dev/null and b/WiTap/images/Default.png differ diff --git a/WiTap/images/Icon-72.png b/WiTap/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/WiTap/images/Icon-72.png differ diff --git a/WiTap/images/Icon-Small-50.png b/WiTap/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/WiTap/images/Icon-Small-50.png differ diff --git a/WiTap/images/Icon-Small.png b/WiTap/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/WiTap/images/Icon-Small.png differ diff --git a/WiTap/images/Icon-Small@2x.png b/WiTap/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/WiTap/images/Icon-Small@2x.png differ diff --git a/WiTap/images/Icon.png b/WiTap/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/WiTap/images/Icon.png differ diff --git a/WiTap/images/Icon@2x.png b/WiTap/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/WiTap/images/Icon@2x.png differ diff --git a/WiTap/images/bg.png b/WiTap/images/bg.png new file mode 100644 index 0000000..1cf343a Binary files /dev/null and b/WiTap/images/bg.png differ diff --git a/WiTap/images/iTunesArtwork b/WiTap/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/WiTap/images/iTunesArtwork differ diff --git a/WiTap/main.m b/WiTap/main.m new file mode 100644 index 0000000..b3ea0cb --- /dev/null +++ b/WiTap/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: his file is included for support purposes and isn't necessary for understanding this sample. + Version: 1.8 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + UIApplicationMain(argc, argv, nil, @"AppController"); + [pool release]; + return 0; +} diff --git a/WorldCities.zip b/WorldCities.zip new file mode 100644 index 0000000..238451e Binary files /dev/null and b/WorldCities.zip differ diff --git a/WorldCities/Classes/AppDelegate.h b/WorldCities/Classes/AppDelegate.h new file mode 100644 index 0000000..650ead3 --- /dev/null +++ b/WorldCities/Classes/AppDelegate.h @@ -0,0 +1,62 @@ +/* + File: AppDelegate.h + Abstract: Configures and displays the application window and navigation controller. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@class MapViewController; + +@interface AppDelegate : NSObject +{ + UIWindow *window; + UINavigationController *navigationController; + MapViewController *mapViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet MapViewController *mapViewController; + +@end + diff --git a/WorldCities/Classes/AppDelegate.m b/WorldCities/Classes/AppDelegate.m new file mode 100644 index 0000000..a3e0da9 --- /dev/null +++ b/WorldCities/Classes/AppDelegate.m @@ -0,0 +1,71 @@ +/* + File: AppDelegate.m + Abstract: Configures and displays the application window and navigation controller. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "AppDelegate.h" +#import "MapViewController.h" + +@implementation AppDelegate + +@synthesize window, navigationController, mapViewController; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + [window addSubview:navigationController.view]; + [window makeKeyAndVisible]; +} + +- (void)dealloc +{ + [mapViewController release]; + [navigationController release]; + [window release]; + + [super dealloc]; +} + +@end + diff --git a/WorldCities/Classes/MapViewController.h b/WorldCities/Classes/MapViewController.h new file mode 100644 index 0000000..6494ee3 --- /dev/null +++ b/WorldCities/Classes/MapViewController.h @@ -0,0 +1,66 @@ +/* + File: MapViewController.h + Abstract: Controls the map view, sets the map type, and sets the region according to the selected worldCity. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +#import "WorldCitiesListController.h" + +@interface MapViewController : UIViewController +{ + MKMapView *mapView; + WorldCitiesListController *worldCitiesListController; + UINavigationController *worldCitiesListNavigationController; +} + +@property (nonatomic, retain) IBOutlet MKMapView *mapView; +@property (nonatomic, retain, readonly) WorldCitiesListController *worldCitiesListController; +@property (nonatomic, retain, readonly) UINavigationController *worldCitiesListNavigationController; + +- (IBAction)viewPlacesList; +- (IBAction)setMapType:(id)sender; + +@end diff --git a/WorldCities/Classes/MapViewController.m b/WorldCities/Classes/MapViewController.m new file mode 100644 index 0000000..5e2b2e7 --- /dev/null +++ b/WorldCities/Classes/MapViewController.m @@ -0,0 +1,149 @@ +/* + File: MapViewController.m + Abstract: Controls the map view, sets the map type, and sets the region according to the selected worldCity. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "MapViewController.h" +#import "WorldCity.h" + +@implementation MapViewController + +@synthesize mapView; + +- (WorldCitiesListController *)worldCitiesListController +{ + if (worldCitiesListController == nil) + { + worldCitiesListController = [[WorldCitiesListController alloc] initWithStyle:UITableViewStylePlain]; + worldCitiesListController.delegate = self; + worldCitiesListController.title = @"Choose a city:"; + } + return worldCitiesListController; +} + +- (UINavigationController *)worldCitiesListNavigationController +{ + if (worldCitiesListNavigationController == nil) + { + worldCitiesListNavigationController = [[UINavigationController alloc] initWithRootViewController:self.worldCitiesListController]; + } + return worldCitiesListNavigationController; +} + +- (void)viewDidUnload +{ + self.mapView = nil; +} + +- (void)dealloc +{ + [mapView release]; + [worldCitiesListController release]; + [worldCitiesListNavigationController release]; + + [super dealloc]; +} + +- (IBAction)viewPlacesList +{ + [self.navigationController presentModalViewController:self.worldCitiesListNavigationController animated:YES]; +} + +- (IBAction)setMapType:(id)sender +{ + switch (((UISegmentedControl *)sender).selectedSegmentIndex) + { + case 0: + { + mapView.mapType = MKMapTypeStandard; + break; + } + case 1: + { + mapView.mapType = MKMapTypeSatellite; + break; + } + default: + { + mapView.mapType = MKMapTypeHybrid; + break; + } + } +} + +- (void)animateToWorld:(WorldCity *)worldCity +{ + MKCoordinateRegion current = mapView.region; + MKCoordinateRegion zoomOut = { { (current.center.latitude + worldCity.coordinate.latitude)/2.0 , (current.center.longitude + worldCity.coordinate.longitude)/2.0 }, {90, 90} }; + [mapView setRegion:zoomOut animated:YES]; +} + +- (void)animateToPlace:(WorldCity *)worldCity +{ + MKCoordinateRegion region; + region.center = worldCity.coordinate; + MKCoordinateSpan span = {0.4, 0.4}; + region.span = span; + [mapView setRegion:region animated:YES]; +} + +- (void)worldCitiesListController:(WorldCitiesListController *)controller didChooseWorldCity:(WorldCity *)aPlace +{ + [self.navigationController dismissModalViewControllerAnimated:YES]; + self.title = aPlace.name; + MKCoordinateRegion current = mapView.region; + if (current.span.latitudeDelta < 10) + { + [self performSelector:@selector(animateToWorld:) withObject:aPlace afterDelay:0.3]; + [self performSelector:@selector(animateToPlace:) withObject:aPlace afterDelay:1.7]; + } + else + { + [self performSelector:@selector(animateToPlace:) withObject:aPlace afterDelay:0.3]; + } +} + +@end + diff --git a/WorldCities/Classes/WorldCitiesListController.h b/WorldCities/Classes/WorldCitiesListController.h new file mode 100644 index 0000000..da468f0 --- /dev/null +++ b/WorldCities/Classes/WorldCitiesListController.h @@ -0,0 +1,70 @@ +/* + File: WorldCitiesListController.h + Abstract: Displays the list of WorldCities to be selected for display in the map view. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "WorldCity.h" + +@protocol WorldCitiesListControllerDelegate; + +@interface WorldCitiesListController : UITableViewController +{ + NSMutableArray* cityList; + + id delegate; + BOOL addingNewPlace; +} + +@property (nonatomic, retain) NSMutableArray* cityList; +@property (nonatomic, assign) id delegate; + +@end + +@protocol WorldCitiesListControllerDelegate + +- (void)worldCitiesListController:(WorldCitiesListController *)controller didChooseWorldCity:(WorldCity *)aPlace; + +@end \ No newline at end of file diff --git a/WorldCities/Classes/WorldCitiesListController.m b/WorldCities/Classes/WorldCitiesListController.m new file mode 100644 index 0000000..c488efe --- /dev/null +++ b/WorldCities/Classes/WorldCitiesListController.m @@ -0,0 +1,127 @@ +/* + File: WorldCitiesListController.m + Abstract: n/a + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "WorldCitiesListController.h" +#import "WorldCity.h" + +@implementation WorldCitiesListController + +@synthesize cityList, delegate; + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + // load our data from a plist file inside our app bundle + NSString *path = [[NSBundle mainBundle] pathForResource:@"cityList" ofType:@"plist"]; + NSArray *cities = [NSArray arrayWithContentsOfFile:path]; + + self.cityList = [[[NSMutableArray alloc] initWithCapacity:[cities count]] autorelease]; + + NSDictionary *city; + for (city in cities) + { + WorldCity *newCity = [[WorldCity alloc] init]; + newCity.name = [city objectForKey:@"cityNameKey"]; + newCity.latitude = [city objectForKey:@"latitudeKey"];; + newCity.longitude = [city objectForKey:@"longitudeKey"]; + + [self.cityList addObject:newCity]; + [newCity release]; + } +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [self.tableView reloadData]; +} + + +#pragma mark - +#pragma mark Table view methods + +// Customize the number of rows in the table view. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [self.cityList count]; +} + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString * const kPlacesCellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPlacesCellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kPlacesCellIdentifier] autorelease]; + cell.editingAccessoryType = UITableViewCellAccessoryDetailDisclosureButton; + } + + WorldCity *worldCity = [self.cityList objectAtIndex:indexPath.row]; + cell.textLabel.text = worldCity.name; + cell.detailTextLabel.text = [NSString stringWithFormat:@"%.3f, %.3f", worldCity.coordinate.latitude, worldCity.coordinate.longitude]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [delegate worldCitiesListController:self didChooseWorldCity:[self.cityList objectAtIndex:indexPath.row]]; + [self.navigationController popViewControllerAnimated:YES]; +} + +- (void)dealloc +{ + [cityList release]; + + [super dealloc]; +} + +@end + diff --git a/WorldCities/Classes/WorldCity.h b/WorldCities/Classes/WorldCity.h new file mode 100644 index 0000000..11784cd --- /dev/null +++ b/WorldCities/Classes/WorldCity.h @@ -0,0 +1,67 @@ +/* + File: WorldCity.h + Abstract: Contains the data for a worldCity object. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import + +@interface WorldCity : NSObject +{ + CLLocationCoordinate2D coordinate; + + NSString *name; + NSNumber *latitude; + NSNumber *longitude; +} + +@property (nonatomic, retain) NSString *name; +@property (nonatomic, retain) NSNumber *latitude; +@property (nonatomic, retain) NSNumber *longitude; + +// the coordinate is a derived property based on the properties latitude and longitude. +@property (nonatomic, assign, readonly) CLLocationCoordinate2D coordinate; + +@end diff --git a/WorldCities/Classes/WorldCity.m b/WorldCities/Classes/WorldCity.m new file mode 100644 index 0000000..d34a86b --- /dev/null +++ b/WorldCities/Classes/WorldCity.m @@ -0,0 +1,70 @@ +/* + File: WorldCity.m + Abstract: Contains the data for a worldCity object. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "WorldCity.h" + +@implementation WorldCity + +@synthesize name, latitude, longitude; + +// Implementing this method ensures the Key-Value observers will be notified when the properties +// from which coordinate is derived have changed. +// ++ (NSSet *)keyPathsForValuesAffectingCoordinate +{ + return [NSSet setWithObjects:@"latitude", @"longitude", nil]; +} + +// derive the coordinate property. +- (CLLocationCoordinate2D)coordinate +{ + coordinate.latitude = self.latitude.doubleValue; + coordinate.longitude = self.longitude.doubleValue; + return coordinate; +} + +@end diff --git a/WorldCities/ReadMe.txt b/WorldCities/ReadMe.txt new file mode 100644 index 0000000..08a04a1 --- /dev/null +++ b/WorldCities/ReadMe.txt @@ -0,0 +1,48 @@ +WorldCities + +=========================================================================== +ABSTRACT + +"WorldCities" demonstrates basic use of MapKit, including displaying a map view and setting its region. A list of cities are stored in a plist file loaded at launch time. Each city is represented by a "WorldCity" class which consists of a name, a latitude, and a longitude. The user can select from a pre-defined world cities. When a world cities is selected, the map view animates to a region with the coordinates of the world cities in the center of the view. The user can also choose between map types - Standard, Satellite, and Hybrid - using the segmented control in the toolbar of the main view. + +Important: +The MapKit framework uses Google services to provide map data. Use of this class and the associated interfaces binds you to the Google Maps/Google Earth API terms of service. You can find these terms of service mentioned in the header section of "MKMapView.h". + +=========================================================================== +DISCUSSION + +The MapViewController class and MapViewController.xib encapsulate all the interactions with the map view. These files are a good place to start to see how to set the region and map type of an MKMapView object. + +=========================================================================== +BUILD REQUIREMENTS + +iOS 4.0 SDK + +=========================================================================== +SYSTEM REQUIREMENTS + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST + +AppDelegate +Configures and displays the application window and navigation controller. + +MapViewController +Controls the map view, sets the map type, and sets the region according to the selected place. + +WorldCitiesListController +Displays the list of WorldCities to be selected for display in the map view. + +cityList.plist +Contains the data for a world city object. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS + +1.1 Upgraded project to build with the iOS 4.0 SDK. +1.0 Initial version published. + +=========================================================================== +Copyright (C) 2009-2010 Apple Inc. All rights reserved. diff --git a/WorldCities/WorldCities-Info.plist b/WorldCities/WorldCities-Info.plist new file mode 100644 index 0000000..20fe35d --- /dev/null +++ b/WorldCities/WorldCities-Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/WorldCities/WorldCities.xcodeproj/project.pbxproj b/WorldCities/WorldCities.xcodeproj/project.pbxproj new file mode 100755 index 0000000..d64cdf4 --- /dev/null +++ b/WorldCities/WorldCities.xcodeproj/project.pbxproj @@ -0,0 +1,328 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1821D6B611D2822100418632 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 1821D6B511D2822100418632 /* iTunesArtwork */; }; + 18352ABD11CFFA950089BE2C /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352ABB11CFFA950089BE2C /* Icon-72.png */; }; + 18352ABE11CFFA950089BE2C /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352ABC11CFFA950089BE2C /* Icon-Small-50.png */; }; + 18683A0311CC345D004039C4 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 18683A0211CC345D004039C4 /* Default.png */; }; + 18683A0911CC3462004039C4 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18683A0411CC3462004039C4 /* Icon-Small.png */; }; + 18683A0A11CC3462004039C4 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18683A0511CC3462004039C4 /* Icon-Small@2x.png */; }; + 18683A0B11CC3462004039C4 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18683A0611CC3462004039C4 /* Icon.png */; }; + 18683A0C11CC3462004039C4 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18683A0711CC3462004039C4 /* Icon@2x.png */; }; + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 28C286E10D94DF7D0034E888 /* MapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* MapViewController.m */; }; + 30E5B5CA102780F20022F36A /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E5B5C9102780F20022F36A /* MapKit.framework */; }; + 30E5B5D21027820E0022F36A /* WorldCitiesListController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E5B5D11027820E0022F36A /* WorldCitiesListController.m */; }; + 30E5B606102787F10022F36A /* WorldCity.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E5B605102787F10022F36A /* WorldCity.m */; }; + 30E5B7D01027BDB00022F36A /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E5B7CF1027BDB00022F36A /* CoreData.framework */; }; + 5373D7A010C9CBAA004D6540 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5373D79C10C9CBAA004D6540 /* MainWindow.xib */; }; + 5373D7A110C9CBAA004D6540 /* MapViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5373D79E10C9CBAA004D6540 /* MapViewController.xib */; }; + 53EE133610D969BC00327670 /* cityList.plist in Resources */ = {isa = PBXBuildFile; fileRef = 53EE133510D969BC00327670 /* cityList.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1821D6B511D2822100418632 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 18352ABB11CFFA950089BE2C /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18352ABC11CFFA950089BE2C /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18683A0211CC345D004039C4 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 18683A0411CC3462004039C4 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18683A0511CC3462004039C4 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18683A0611CC3462004039C4 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 18683A0711CC3462004039C4 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* WorldCities.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WorldCities.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* WorldCities_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorldCities_Prefix.pch; path = ../WorldCities_Prefix.pch; sourceTree = ""; }; + 28C286DF0D94DF7D0034E888 /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapViewController.h; sourceTree = ""; }; + 28C286E00D94DF7D0034E888 /* MapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ../main.m; sourceTree = ""; }; + 30E5B5C9102780F20022F36A /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 30E5B5D01027820E0022F36A /* WorldCitiesListController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldCitiesListController.h; sourceTree = ""; }; + 30E5B5D11027820E0022F36A /* WorldCitiesListController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WorldCitiesListController.m; sourceTree = ""; }; + 30E5B604102787F10022F36A /* WorldCity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldCity.h; sourceTree = ""; }; + 30E5B605102787F10022F36A /* WorldCity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WorldCity.m; sourceTree = ""; }; + 30E5B7CF1027BDB00022F36A /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 30E5B8BC10289A100022F36A /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 5373D79D10C9CBAA004D6540 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 5373D79F10C9CBAA004D6540 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MapViewController.xib; sourceTree = ""; }; + 53EE133510D969BC00327670 /* cityList.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = cityList.plist; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* WorldCities-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "WorldCities-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + 30E5B5CA102780F20022F36A /* MapKit.framework in Frameworks */, + 30E5B7D01027BDB00022F36A /* CoreData.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* WorldCities_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 28C286DF0D94DF7D0034E888 /* MapViewController.h */, + 28C286E00D94DF7D0034E888 /* MapViewController.m */, + 30E5B5D01027820E0022F36A /* WorldCitiesListController.h */, + 30E5B5D11027820E0022F36A /* WorldCitiesListController.m */, + 30E5B604102787F10022F36A /* WorldCity.h */, + 30E5B605102787F10022F36A /* WorldCity.m */, + ); + name = Sources; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* WorldCities.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 30E5B8BC10289A100022F36A /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 1821D6B511D2822100418632 /* iTunesArtwork */, + 18352ABB11CFFA950089BE2C /* Icon-72.png */, + 18352ABC11CFFA950089BE2C /* Icon-Small-50.png */, + 18683A0411CC3462004039C4 /* Icon-Small.png */, + 18683A0511CC3462004039C4 /* Icon-Small@2x.png */, + 18683A0611CC3462004039C4 /* Icon.png */, + 18683A0711CC3462004039C4 /* Icon@2x.png */, + 18683A0211CC345D004039C4 /* Default.png */, + 53EE133510D969BC00327670 /* cityList.plist */, + 5373D79C10C9CBAA004D6540 /* MainWindow.xib */, + 5373D79E10C9CBAA004D6540 /* MapViewController.xib */, + 8D1107310486CEB800E47090 /* WorldCities-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + 30E5B5C9102780F20022F36A /* MapKit.framework */, + 30E5B7CF1027BDB00022F36A /* CoreData.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* WorldCities */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "WorldCities" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WorldCities; + productName = Places; + productReference = 1D6058910D05DD3D006BFB54 /* WorldCities.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WorldCities" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* WorldCities */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5373D7A010C9CBAA004D6540 /* MainWindow.xib in Resources */, + 5373D7A110C9CBAA004D6540 /* MapViewController.xib in Resources */, + 53EE133610D969BC00327670 /* cityList.plist in Resources */, + 18683A0311CC345D004039C4 /* Default.png in Resources */, + 18683A0911CC3462004039C4 /* Icon-Small.png in Resources */, + 18683A0A11CC3462004039C4 /* Icon-Small@2x.png in Resources */, + 18683A0B11CC3462004039C4 /* Icon.png in Resources */, + 18683A0C11CC3462004039C4 /* Icon@2x.png in Resources */, + 18352ABD11CFFA950089BE2C /* Icon-72.png in Resources */, + 18352ABE11CFFA950089BE2C /* Icon-Small-50.png in Resources */, + 1821D6B611D2822100418632 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 28C286E10D94DF7D0034E888 /* MapViewController.m in Sources */, + 30E5B5D21027820E0022F36A /* WorldCitiesListController.m in Sources */, + 30E5B606102787F10022F36A /* WorldCity.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5373D79C10C9CBAA004D6540 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 5373D79D10C9CBAA004D6540 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 5373D79E10C9CBAA004D6540 /* MapViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 5373D79F10C9CBAA004D6540 /* en */, + ); + name = MapViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = WorldCities_Prefix.pch; + INFOPLIST_FILE = "WorldCities-Info.plist"; + PRODUCT_NAME = WorldCities; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = WorldCities_Prefix.pch; + INFOPLIST_FILE = "WorldCities-Info.plist"; + PRODUCT_NAME = WorldCities; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "WorldCities" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WorldCities" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/WorldCities/WorldCities_Prefix.pch b/WorldCities/WorldCities_Prefix.pch new file mode 100644 index 0000000..d317880 --- /dev/null +++ b/WorldCities/WorldCities_Prefix.pch @@ -0,0 +1,60 @@ +/* + File: WorldCities_Prefix.pch + Abstract: Prefix header for all source files of the 'Places' target in the 'Places' project + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + + +#ifdef __OBJC__ + #import + #import + #import +#endif diff --git a/WorldCities/cityList.plist b/WorldCities/cityList.plist new file mode 100755 index 0000000..78fb1f9 --- /dev/null +++ b/WorldCities/cityList.plist @@ -0,0 +1,63 @@ + + + + + + + cityNameKey + Sydney + latitudeKey + -33.860 + longitudeKey + 151.211 + + + cityNameKey + San Francisco + latitudeKey + 37.779 + longitudeKey + -122.419 + + + cityNameKey + Paris + latitudeKey + 48.857 + longitudeKey + 2.351 + + + cityNameKey + Mumbai + latitudeKey + 18.975 + longitudeKey + 72.826 + + + cityNameKey + Moscow + latitudeKey + 55.752 + longitudeKey + 37.618 + + + cityNameKey + Johannesburg + latitudeKey + -26.204 + longitudeKey + 28.046 + + + cityNameKey + Groveland + latitudeKey + 37.849917 + longitudeKey + -120.231628 + + + diff --git a/WorldCities/en.lproj/MainWindow.xib b/WorldCities/en.lproj/MainWindow.xib new file mode 100644 index 0000000..8130603 --- /dev/null +++ b/WorldCities/en.lproj/MainWindow.xib @@ -0,0 +1,555 @@ + + + + 768 + 10A433 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + WorldCities + + + MapViewController + + + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + mapViewController + + + + 19 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + + 11 + + + + + 13 + + + YES + + + + + + 14 + + + YES + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 11.IBPluginDependency + 13.CustomClassName + 13.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MapViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{673, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 19 + + + + YES + + AppDelegate + NSObject + + YES + + YES + mapViewController + navigationController + window + + + YES + MapViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + AppDelegate + NSObject + + IBUserSource + + + + + MapViewController + UIViewController + + YES + + YES + setMapType: + viewPlacesList + + + YES + id + id + + + + mapView + MKMapView + + + IBProjectSource + Classes/MapViewController.h + + + + MapViewController + UIViewController + + IBUserSource + + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Places.xcodeproj + 3 + 3.1 + + diff --git a/WorldCities/en.lproj/MapViewController.xib b/WorldCities/en.lproj/MapViewController.xib new file mode 100644 index 0000000..4008204 --- /dev/null +++ b/WorldCities/en.lproj/MapViewController.xib @@ -0,0 +1,568 @@ + + + + 768 + 10A433 + 732 + 1038 + 437.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 266 + + YES + + + 292 + {{101, 8}, {207, 30}} + + NO + NO + 2 + 3 + 0 + + YES + Standard + Satellite + Hybrid + + + YES + + + + + + YES + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + {{0, 416}, {320, 44}} + + NO + NO + + YES + + 1 + + 11 + + + + 5 + + + + + + + + + + 274 + {320, 416} + + NO + YES + 4 + YES + + + {320, 460} + + + 3 + MQA + + 2 + + + NO + + + + + YES + + + view + + + + 7 + + + + setMapType: + + + 13 + + 15 + + + + mapView + + + + 16 + + + + viewPlacesList + + + + 18 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + YES + + + + + + + 8 + + + YES + + + + + + + + 10 + + + + + 11 + + + + + 14 + + + YES + + + + + + 13 + + + + + 17 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 13.IBPluginDependency + 17.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 8.IBPluginDependency + + + YES + MapViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{375, 662}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 18 + + + + YES + + MapViewController + UIViewController + + YES + + YES + setMapType: + viewPlacesList + + + YES + id + id + + + + mapView + MKMapView + + + IBProjectSource + Classes/MapViewController.h + + + + MapViewController + UIViewController + + IBUserSource + + + + + + YES + + MKMapView + UIView + + IBFrameworkSource + MapKit.framework/Headers/MKMapView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISegmentedControl + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISegmentedControl.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Places.xcodeproj + 3 + 3.1 + + diff --git a/WorldCities/images/Default.png b/WorldCities/images/Default.png new file mode 100644 index 0000000..b0eec32 Binary files /dev/null and b/WorldCities/images/Default.png differ diff --git a/WorldCities/images/Icon-72.png b/WorldCities/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/WorldCities/images/Icon-72.png differ diff --git a/WorldCities/images/Icon-Small-50.png b/WorldCities/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/WorldCities/images/Icon-Small-50.png differ diff --git a/WorldCities/images/Icon-Small.png b/WorldCities/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/WorldCities/images/Icon-Small.png differ diff --git a/WorldCities/images/Icon-Small@2x.png b/WorldCities/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/WorldCities/images/Icon-Small@2x.png differ diff --git a/WorldCities/images/Icon.png b/WorldCities/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/WorldCities/images/Icon.png differ diff --git a/WorldCities/images/Icon@2x.png b/WorldCities/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/WorldCities/images/Icon@2x.png differ diff --git a/WorldCities/images/iTunesArtwork b/WorldCities/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/WorldCities/images/iTunesArtwork differ diff --git a/WorldCities/main.m b/WorldCities/main.m new file mode 100644 index 0000000..79d19a9 --- /dev/null +++ b/WorldCities/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: Main source file for this sample. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/XMLPerformance.zip b/XMLPerformance.zip new file mode 100644 index 0000000..33684d3 Binary files /dev/null and b/XMLPerformance.zip differ diff --git a/XMLPerformance/Classes/AppDelegate.h b/XMLPerformance/Classes/AppDelegate.h new file mode 100644 index 0000000..bdb1c0c --- /dev/null +++ b/XMLPerformance/Classes/AppDelegate.h @@ -0,0 +1,58 @@ +/* + File: AppDelegate.h + Abstract: Adds the main UITabBarController's view to the application's window. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface AppDelegate : NSObject { + UIWindow *window; + UITabBarController *tabBarController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController; + +@end diff --git a/XMLPerformance/Classes/AppDelegate.m b/XMLPerformance/Classes/AppDelegate.m new file mode 100644 index 0000000..c9d4f37 --- /dev/null +++ b/XMLPerformance/Classes/AppDelegate.m @@ -0,0 +1,72 @@ +/* + File: AppDelegate.m + Abstract: Adds the main UITabBarController's view to the application's window. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "Statistics.h" + +@implementation AppDelegate + +@synthesize window; +@synthesize tabBarController; + +- (void)dealloc { + [tabBarController release]; + [window release]; + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + // Add the tab bar controller's current view as a subview of the window + [window addSubview:tabBarController.view]; +} + +- (void)applicationWillTerminate:(UIApplication *)application { + CloseStatisticsDatabase(); +} + +@end + diff --git a/XMLPerformance/Classes/CocoaXMLParser.h b/XMLPerformance/Classes/CocoaXMLParser.h new file mode 100644 index 0000000..d49d130 --- /dev/null +++ b/XMLPerformance/Classes/CocoaXMLParser.h @@ -0,0 +1,78 @@ +/* + File: CocoaXMLParser.h + Abstract: Subclass of iTunesRSSParser that uses the Foundation framework's NSXMLParser for parsing the XML data. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "iTunesRSSParser.h" + +@class Song; + +@interface CocoaXMLParser : iTunesRSSParser +{ + NSMutableString *currentString; + Song *currentSong; + BOOL storingCharacters; + NSDateFormatter *parseFormatter; + NSMutableData *xmlData; + BOOL done; + NSURLConnection *rssConnection; + // The number of parsed songs is tracked so that the autorelease pool for the parsing thread can be periodically + // emptied to keep the memory footprint under control. + NSUInteger countOfParsedSongs; + NSAutoreleasePool *downloadAndParsePool; +} + +@property (nonatomic, retain) NSMutableString *currentString; +@property (nonatomic, retain) Song *currentSong; +@property (nonatomic, retain) NSDateFormatter *parseFormatter; +@property (nonatomic, retain) NSMutableData *xmlData; +@property (nonatomic, retain) NSURLConnection *rssConnection; +// The autorelease pool property is assign because autorelease pools cannot be retained. +@property (nonatomic, assign) NSAutoreleasePool *downloadAndParsePool; + +- (void)downloadAndParse:(NSURL *)url; + +@end diff --git a/XMLPerformance/Classes/CocoaXMLParser.m b/XMLPerformance/Classes/CocoaXMLParser.m new file mode 100644 index 0000000..5ce053c --- /dev/null +++ b/XMLPerformance/Classes/CocoaXMLParser.m @@ -0,0 +1,199 @@ +/* + File: CocoaXMLParser.m + Abstract: Subclass of iTunesRSSParser that uses the Foundation framework's NSXMLParser for parsing the XML data. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "CocoaXMLParser.h" +#import "Song.h" + +@implementation CocoaXMLParser + ++ (NSString *)parserName { + return @"NSXMLParser"; +} + ++ (XMLParserType)parserType { + return XMLParserTypeNSXMLParser; +} + +@synthesize currentString, currentSong, parseFormatter, xmlData, rssConnection, downloadAndParsePool; + +- (void)downloadAndParse:(NSURL *)url { + self.downloadAndParsePool = [[NSAutoreleasePool alloc] init]; + done = NO; + self.parseFormatter = [[[NSDateFormatter alloc] init] autorelease]; + [parseFormatter setDateStyle:NSDateFormatterLongStyle]; + [parseFormatter setTimeStyle:NSDateFormatterNoStyle]; + // necessary because iTunes RSS feed is not localized, so if the device region has been set to other than US + // the date formatter must be set to US locale in order to parse the dates + [parseFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"US"] autorelease]]; + self.xmlData = [NSMutableData data]; + [[NSURLCache sharedURLCache] removeAllCachedResponses]; + NSURLRequest *theRequest = [NSURLRequest requestWithURL:url]; + // create the connection with the request and start loading the data + rssConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; + [self performSelectorOnMainThread:@selector(downloadStarted) withObject:nil waitUntilDone:NO]; + if (rssConnection != nil) { + do { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; + } while (!done); + } + self.rssConnection = nil; + self.parseFormatter = nil; + self.currentSong = nil; + [downloadAndParsePool release]; + self.downloadAndParsePool = nil; +} + +#pragma mark NSURLConnection Delegate methods + +/* + Disable caching so that each time we run this app we are starting with a clean slate. You may not want to do this in your application. + */ +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { + return nil; +} + +// Forward errors to the delegate. +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + done = YES; + [self performSelectorOnMainThread:@selector(parseError:) withObject:error waitUntilDone:NO]; +} + +// Called when a chunk of data has been downloaded. +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + // Append the downloaded chunk of data. + [xmlData appendData:data]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + [self performSelectorOnMainThread:@selector(downloadEnded) withObject:nil waitUntilDone:NO]; + NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData]; + parser.delegate = self; + self.currentString = [NSMutableString string]; + NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; + [parser parse]; + NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start; + [self performSelectorOnMainThread:@selector(addToParseDuration:) withObject:[NSNumber numberWithDouble:duration] waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(parseEnded) withObject:nil waitUntilDone:NO]; + [parser release]; + self.currentString = nil; + self.xmlData = nil; + // Set the condition which ends the run loop. + done = YES; +} + +#pragma mark Parsing support methods + +static const NSUInteger kAutoreleasePoolPurgeFrequency = 20; + +- (void)finishedCurrentSong { + [self performSelectorOnMainThread:@selector(parsedSong:) withObject:currentSong waitUntilDone:NO]; + // performSelectorOnMainThread: will retain the object until the selector has been performed + // setting the local reference to nil ensures that the local reference will be released + self.currentSong = nil; + countOfParsedSongs++; + // Periodically purge the autorelease pool. The frequency of this action may need to be tuned according to the + // size of the objects being parsed. The goal is to keep the autorelease pool from growing too large, but + // taking this action too frequently would be wasteful and reduce performance. + if (countOfParsedSongs == kAutoreleasePoolPurgeFrequency) { + [downloadAndParsePool release]; + self.downloadAndParsePool = [[NSAutoreleasePool alloc] init]; + countOfParsedSongs = 0; + } +} + +#pragma mark NSXMLParser Parsing Callbacks + +// Constants for the XML element names that will be considered during the parse. +// Declaring these as static constants reduces the number of objects created during the run +// and is less prone to programmer error. +static NSString *kName_Item = @"item"; +static NSString *kName_Title = @"title"; +static NSString *kName_Category = @"category"; +static NSString *kName_Artist = @"itms:artist"; +static NSString *kName_Album = @"itms:album"; +static NSString *kName_ReleaseDate = @"itms:releasedate"; + +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *) qualifiedName attributes:(NSDictionary *)attributeDict { + if ([elementName isEqualToString:kName_Item]) { + self.currentSong = [[[Song alloc] init] autorelease]; + } else if ([elementName isEqualToString:kName_Title] || [elementName isEqualToString:kName_Category] || [elementName isEqualToString:kName_Artist] || [elementName isEqualToString:kName_Album] || [elementName isEqualToString:kName_ReleaseDate]) { + [currentString setString:@""]; + storingCharacters = YES; + } +} + +- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { + if ([elementName isEqualToString:kName_Item]) { + [self finishedCurrentSong]; + } else if ([elementName isEqualToString:kName_Title]) { + currentSong.title = currentString; + } else if ([elementName isEqualToString:kName_Category]) { + currentSong.category = currentString; + } else if ([elementName isEqualToString:kName_Artist]) { + currentSong.artist = currentString; + } else if ([elementName isEqualToString:kName_Album]) { + currentSong.album = currentString; + } else if ([elementName isEqualToString:kName_ReleaseDate]) { + currentSong.releaseDate = [parseFormatter dateFromString:currentString]; + } + storingCharacters = NO; +} + +- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { + if (storingCharacters) [currentString appendString:string]; +} + +/* + A production application should include robust error handling as part of its parsing implementation. + The specifics of how errors are handled depends on the application. + */ +- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { + // Handle errors as appropriate for your application. +} + + +@end diff --git a/XMLPerformance/Classes/DetailController.h b/XMLPerformance/Classes/DetailController.h new file mode 100644 index 0000000..a1bb6bf --- /dev/null +++ b/XMLPerformance/Classes/DetailController.h @@ -0,0 +1,60 @@ +/* + File: DetailController.h + Abstract: Displays details of a single parsed song. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class Song; + +@interface DetailController : UITableViewController { + NSDateFormatter *dateFormatter; + Song *song; +} + +@property (nonatomic, retain) Song *song; +@property (nonatomic, readonly, retain) NSDateFormatter *dateFormatter; + +@end diff --git a/XMLPerformance/Classes/DetailController.m b/XMLPerformance/Classes/DetailController.m new file mode 100644 index 0000000..fd802f2 --- /dev/null +++ b/XMLPerformance/Classes/DetailController.m @@ -0,0 +1,112 @@ +/* + File: DetailController.m + Abstract: Displays details of a single parsed song. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "DetailController.h" +#import "Song.h" + +@implementation DetailController + +@synthesize song, dateFormatter; + +- (void)dealloc { + [dateFormatter release]; + [song release]; + [super dealloc]; +} + +- (NSDateFormatter *)dateFormatter { + if (dateFormatter == nil) { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; + } + return dateFormatter; +} + +// When the view appears, update the title and table contents. +- (void)viewWillAppear:(BOOL)animated { + self.title = song.title; + [self.tableView reloadData]; +} + +- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section { + return 4; +} + +- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kCellIdentifier = @"SongDetailCell"; + UITableViewCell *cell = (UITableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kCellIdentifier] autorelease]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + switch (indexPath.row) { + case 0: { + cell.textLabel.text = NSLocalizedString(@"album", @"album label"); + cell.detailTextLabel.text = song.album; + } break; + case 1: { + cell.textLabel.text = NSLocalizedString(@"artist", @"artist label"); + cell.detailTextLabel.text = song.artist; + } break; + case 2: { + cell.textLabel.text = NSLocalizedString(@"category", @"category label"); + cell.detailTextLabel.text = song.category; + } break; + case 3: { + cell.textLabel.text = NSLocalizedString(@"released", @"released label"); + cell.detailTextLabel.text = [self.dateFormatter stringFromDate:song.releaseDate]; + } break; + } + return cell; +} + +- (NSString *)tableView:(UITableView *)tv titleForHeaderInSection:(NSInteger)section { + return NSLocalizedString(@"Song details:", @"Song details label"); +} + +@end diff --git a/XMLPerformance/Classes/LibXMLParser.h b/XMLPerformance/Classes/LibXMLParser.h new file mode 100644 index 0000000..b11a1b3 --- /dev/null +++ b/XMLPerformance/Classes/LibXMLParser.h @@ -0,0 +1,93 @@ +/* + File: LibXMLParser.h + Abstract: Subclass of iTunesRSSParser that uses libxml2 for parsing the XML data. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import +#import "iTunesRSSParser.h" + +@class Song; + +// This approach to parsing uses NSURLConnection to asychronously retrieve the XML data. libxml's SAX parsing supports chunked parsing, with no requirement for the chunks to be discrete blocks of well formed XML. The primary purpose of this class is to start the download, configure the parser with a set of C callback functions, and pass downloaded data to it. In addition, the class maintains a number of state variables for the parsing. +@interface LibXMLParser : iTunesRSSParser { +@private + // Reference to the libxml parser context + xmlParserCtxtPtr context; + NSURLConnection *rssConnection; + // Overall state of the parser, used to exit the run loop. + BOOL done; + // State variable used to determine whether or not to ignore a given XML element + BOOL parsingASong; + // The following state variables deal with getting character data from XML elements. This is a potentially expensive + // operation. The character data in a given element may be delivered over the course of multiple callbacks, so that + // data must be appended to a buffer. The optimal way of doing this is to use a C string buffer that grows exponentially. + // When all the characters have been delivered, an NSString is constructed and the buffer is reset. + BOOL storingCharacters; + NSMutableData *characterBuffer; + // A reference to the current song the parser is working with. + Song *currentSong; + // The number of parsed songs is tracked so that the autorelease pool for the parsing thread can be periodically + // emptied to keep the memory footprint under control. + NSUInteger countOfParsedSongs; + NSAutoreleasePool *downloadAndParsePool; + NSDateFormatter *parseFormatter; +} + +@property BOOL storingCharacters; +@property (nonatomic, retain) NSMutableData *characterBuffer; +@property BOOL done; +@property BOOL parsingASong; +@property NSUInteger countOfParsedSongs; +@property (nonatomic, retain) Song *currentSong; +@property (nonatomic, retain) NSURLConnection *rssConnection; +@property (nonatomic, retain) NSDateFormatter *parseFormatter; +// The autorelease pool property is assign because autorelease pools cannot be retained. +@property (nonatomic, assign) NSAutoreleasePool *downloadAndParsePool; + +- (void)downloadAndParse:(NSURL *)url; +- (void)finishedCurrentSong; + +@end diff --git a/XMLPerformance/Classes/LibXMLParser.m b/XMLPerformance/Classes/LibXMLParser.m new file mode 100644 index 0000000..9b58c1e --- /dev/null +++ b/XMLPerformance/Classes/LibXMLParser.m @@ -0,0 +1,313 @@ +/* + File: LibXMLParser.m + Abstract: Subclass of iTunesRSSParser that uses libxml2 for parsing the XML data. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "LibXMLParser.h" +#import "Song.h" +#import + +// Function prototypes for SAX callbacks. This sample implements a minimal subset of SAX callbacks. +// Depending on your application's needs, you might want to implement more callbacks. +static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes); +static void endElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI); +static void charactersFoundSAX(void * ctx, const xmlChar * ch, int len); +static void errorEncounteredSAX(void * ctx, const char * msg, ...); + +// Forward reference. The structure is defined in full at the end of the file. +static xmlSAXHandler simpleSAXHandlerStruct; + +@implementation LibXMLParser + +@synthesize rssConnection, done, parsingASong, storingCharacters, currentSong, countOfParsedSongs, characterBuffer, parseFormatter, downloadAndParsePool; + ++ (NSString *)parserName { + return @"libxml2"; +} + ++ (XMLParserType)parserType { + return XMLParserTypeLibXMLParser; +} + +/* +This method is called on a secondary thread by the superclass. We have asynchronous work to do here with downloading and parsing data, so we will need a run loop to prevent the thread from exiting before we are finished. +*/ +- (void)downloadAndParse:(NSURL *)url { + self.downloadAndParsePool = [[NSAutoreleasePool alloc] init]; + done = NO; + self.parseFormatter = [[[NSDateFormatter alloc] init] autorelease]; + [parseFormatter setDateStyle:NSDateFormatterLongStyle]; + [parseFormatter setTimeStyle:NSDateFormatterNoStyle]; + // necessary because iTunes RSS feed is not localized, so if the device region has been set to other than US + // the date formatter must be set to US locale in order to parse the dates + [parseFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"US"] autorelease]]; + self.characterBuffer = [NSMutableData data]; + [[NSURLCache sharedURLCache] removeAllCachedResponses]; + NSURLRequest *theRequest = [NSURLRequest requestWithURL:url]; + // create the connection with the request and start loading the data + rssConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; + // This creates a context for "push" parsing in which chunks of data that are not "well balanced" can be passed + // to the context for streaming parsing. The handler structure defined above will be used for all the parsing. + // The second argument, self, will be passed as user data to each of the SAX handlers. The last three arguments + // are left blank to avoid creating a tree in memory. + context = xmlCreatePushParserCtxt(&simpleSAXHandlerStruct, self, NULL, 0, NULL); + [self performSelectorOnMainThread:@selector(downloadStarted) withObject:nil waitUntilDone:NO]; + if (rssConnection != nil) { + do { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; + } while (!done); + } + // Release resources used only in this thread. + xmlFreeParserCtxt(context); + self.characterBuffer = nil; + self.parseFormatter = nil; + self.rssConnection = nil; + self.currentSong = nil; + [downloadAndParsePool release]; + self.downloadAndParsePool = nil; +} + +#pragma mark NSURLConnection Delegate methods + +/* +Disable caching so that each time we run this app we are starting with a clean slate. You may not want to do this in your application. +*/ +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { + return nil; +} + +// Forward errors to the delegate. +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + done = YES; + [self performSelectorOnMainThread:@selector(parseError:) withObject:error waitUntilDone:NO]; +} + +// Called when a chunk of data has been downloaded. +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; + // Process the downloaded chunk of data. + xmlParseChunk(context, (const char *)[data bytes], [data length], 0); + NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start; + [self performSelectorOnMainThread:@selector(addToParseDuration:) withObject:[NSNumber numberWithDouble:duration] waitUntilDone:NO]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + [self performSelectorOnMainThread:@selector(downloadEnded) withObject:nil waitUntilDone:NO]; + NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; + // Signal the context that parsing is complete by passing "1" as the last parameter. + xmlParseChunk(context, NULL, 0, 1); + NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start; + [self performSelectorOnMainThread:@selector(addToParseDuration:) withObject:[NSNumber numberWithDouble:duration] waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(parseEnded) withObject:nil waitUntilDone:NO]; + // Set the condition which ends the run loop. + done = YES; +} + +#pragma mark Parsing support methods + +static const NSUInteger kAutoreleasePoolPurgeFrequency = 20; + +- (void)finishedCurrentSong { + [self performSelectorOnMainThread:@selector(parsedSong:) withObject:currentSong waitUntilDone:NO]; + // performSelectorOnMainThread: will retain the object until the selector has been performed + // setting the local reference to nil ensures that the local reference will be released + self.currentSong = nil; + countOfParsedSongs++; + // Periodically purge the autorelease pool. The frequency of this action may need to be tuned according to the + // size of the objects being parsed. The goal is to keep the autorelease pool from growing too large, but + // taking this action too frequently would be wasteful and reduce performance. + if (countOfParsedSongs == kAutoreleasePoolPurgeFrequency) { + [downloadAndParsePool release]; + self.downloadAndParsePool = [[NSAutoreleasePool alloc] init]; + countOfParsedSongs = 0; + } +} + +/* + Character data is appended to a buffer until the current element ends. + */ +- (void)appendCharacters:(const char *)charactersFound length:(NSInteger)length { + [characterBuffer appendBytes:charactersFound length:length]; +} + +- (NSString *)currentString { + // Create a string with the character data using UTF-8 encoding. UTF-8 is the default XML data encoding. + NSString *currentString = [[[NSString alloc] initWithData:characterBuffer encoding:NSUTF8StringEncoding] autorelease]; + [characterBuffer setLength:0]; + return currentString; +} + +@end + +#pragma mark SAX Parsing Callbacks + +// The following constants are the XML element names and their string lengths for parsing comparison. +// The lengths include the null terminator, to ensure exact matches. +static const char *kName_Item = "item"; +static const NSUInteger kLength_Item = 5; +static const char *kName_Title = "title"; +static const NSUInteger kLength_Title = 6; +static const char *kName_Category = "category"; +static const NSUInteger kLength_Category = 9; +static const char *kName_Itms = "itms"; +static const NSUInteger kLength_Itms = 5; +static const char *kName_Artist = "artist"; +static const NSUInteger kLength_Artist = 7; +static const char *kName_Album = "album"; +static const NSUInteger kLength_Album = 6; +static const char *kName_ReleaseDate = "releasedate"; +static const NSUInteger kLength_ReleaseDate = 12; + +/* + This callback is invoked when the parser finds the beginning of a node in the XML. For this application, + out parsing needs are relatively modest - we need only match the node name. An "item" node is a record of + data about a song. In that case we create a new Song object. The other nodes of interest are several of the + child nodes of the Song currently being parsed. For those nodes we want to accumulate the character data + in a buffer. Some of the child nodes use a namespace prefix. + */ +static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, + int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes) { + LibXMLParser *parser = (LibXMLParser *)ctx; + // The second parameter to strncmp is the name of the element, which we known from the XML schema of the feed. + // The third parameter to strncmp is the number of characters in the element name, plus 1 for the null terminator. + if (prefix == NULL && !strncmp((const char *)localname, kName_Item, kLength_Item)) { + Song *newSong = [[Song alloc] init]; + parser.currentSong = newSong; + [newSong release]; + parser.parsingASong = YES; + } else if (parser.parsingASong && ( (prefix == NULL && (!strncmp((const char *)localname, kName_Title, kLength_Title) || !strncmp((const char *)localname, kName_Category, kLength_Category))) || ((prefix != NULL && !strncmp((const char *)prefix, kName_Itms, kLength_Itms)) && (!strncmp((const char *)localname, kName_Artist, kLength_Artist) || !strncmp((const char *)localname, kName_Album, kLength_Album) || !strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate))) )) { + parser.storingCharacters = YES; + } +} + +/* + This callback is invoked when the parse reaches the end of a node. At that point we finish processing that node, + if it is of interest to us. For "item" nodes, that means we have completed parsing a Song object. We pass the song + to a method in the superclass which will eventually deliver it to the delegate. For the other nodes we + care about, this means we have all the character data. The next step is to create an NSString using the buffer + contents and store that with the current Song object. + */ +static void endElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI) { + LibXMLParser *parser = (LibXMLParser *)ctx; + if (parser.parsingASong == NO) return; + if (prefix == NULL) { + if (!strncmp((const char *)localname, kName_Item, kLength_Item)) { + [parser finishedCurrentSong]; + parser.parsingASong = NO; + } else if (!strncmp((const char *)localname, kName_Title, kLength_Title)) { + parser.currentSong.title = [parser currentString]; + } else if (!strncmp((const char *)localname, kName_Category, kLength_Category)) { + parser.currentSong.category = [parser currentString]; + } + } else if (!strncmp((const char *)prefix, kName_Itms, kLength_Itms)) { + if (!strncmp((const char *)localname, kName_Artist, kLength_Artist)) { + parser.currentSong.artist = [parser currentString]; + } else if (!strncmp((const char *)localname, kName_Album, kLength_Album)) { + parser.currentSong.album = [parser currentString]; + } else if (!strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate)) { + NSString *dateString = [parser currentString]; + parser.currentSong.releaseDate = [parser.parseFormatter dateFromString:dateString]; + } + } + parser.storingCharacters = NO; +} + +/* + This callback is invoked when the parser encounters character data inside a node. The parser class determines how to use the character data. +*/ +static void charactersFoundSAX(void *ctx, const xmlChar *ch, int len) { + LibXMLParser *parser = (LibXMLParser *)ctx; + // A state variable, "storingCharacters", is set when nodes of interest begin and end. + // This determines whether character data is handled or ignored. + if (parser.storingCharacters == NO) return; + [parser appendCharacters:(const char *)ch length:len]; +} + +/* + A production application should include robust error handling as part of its parsing implementation. + The specifics of how errors are handled depends on the application. + */ +static void errorEncounteredSAX(void *ctx, const char *msg, ...) { + // Handle errors as appropriate for your application. + NSCAssert(NO, @"Unhandled error encountered during SAX parse."); +} + +// The handler struct has positions for a large number of callback functions. If NULL is supplied at a given position, +// that callback functionality won't be used. Refer to libxml documentation at http://www.xmlsoft.org for more information +// about the SAX callbacks. +static xmlSAXHandler simpleSAXHandlerStruct = { + NULL, /* internalSubset */ + NULL, /* isStandalone */ + NULL, /* hasInternalSubset */ + NULL, /* hasExternalSubset */ + NULL, /* resolveEntity */ + NULL, /* getEntity */ + NULL, /* entityDecl */ + NULL, /* notationDecl */ + NULL, /* attributeDecl */ + NULL, /* elementDecl */ + NULL, /* unparsedEntityDecl */ + NULL, /* setDocumentLocator */ + NULL, /* startDocument */ + NULL, /* endDocument */ + NULL, /* startElement*/ + NULL, /* endElement */ + NULL, /* reference */ + charactersFoundSAX, /* characters */ + NULL, /* ignorableWhitespace */ + NULL, /* processingInstruction */ + NULL, /* comment */ + NULL, /* warning */ + errorEncounteredSAX, /* error */ + NULL, /* fatalError //: unused error() get all the errors */ + NULL, /* getParameterEntity */ + NULL, /* cdataBlock */ + NULL, /* externalSubset */ + XML_SAX2_MAGIC, // + NULL, + startElementSAX, /* startElementNs */ + endElementSAX, /* endElementNs */ + NULL, /* serror */ +}; diff --git a/XMLPerformance/Classes/ParserChoiceViewController.h b/XMLPerformance/Classes/ParserChoiceViewController.h new file mode 100644 index 0000000..eda092f --- /dev/null +++ b/XMLPerformance/Classes/ParserChoiceViewController.h @@ -0,0 +1,66 @@ +/* + File: ParserChoiceViewController.h + Abstract: Provides an interface for choosing and running one of the two available parsers. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class SongsViewController; + +@interface ParserChoiceViewController : UIViewController { + UINavigationController *songsNavigationController; + SongsViewController *songsViewController; + NSIndexPath *parserSelection; + UIButton *startButton; +} + +@property (nonatomic, retain) IBOutlet UIButton *startButton; +@property (nonatomic, retain, readonly) UINavigationController *songsNavigationController; +@property (nonatomic, retain, readonly) SongsViewController *songsViewController; +@property (nonatomic, retain) NSIndexPath *parserSelection; + +- (IBAction)startParser; + +@end diff --git a/XMLPerformance/Classes/ParserChoiceViewController.m b/XMLPerformance/Classes/ParserChoiceViewController.m new file mode 100644 index 0000000..999d32c --- /dev/null +++ b/XMLPerformance/Classes/ParserChoiceViewController.m @@ -0,0 +1,116 @@ +/* + File: ParserChoiceViewController.m + Abstract: Provides an interface for choosing and running one of the two available parsers. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "ParserChoiceViewController.h" +#import "SongsViewController.h" +#import "LibXMLParser.h" +#import "CocoaXMLParser.h" + +@implementation ParserChoiceViewController + +@synthesize parserSelection, startButton; + +- (void)dealloc { + [songsNavigationController release]; + [songsViewController release]; + [parserSelection release]; + [startButton release]; + [super dealloc]; +} + +- (void)viewDidLoad { + // Set the background for the main view to match the table view. + self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; + // Set an initial selection. + self.parserSelection = [NSIndexPath indexPathForRow:0 inSection:0]; +} + +- (void)viewDidUnload { + self.startButton = nil; +} + +- (SongsViewController *)songsViewController { + if (songsViewController == nil) { + songsViewController = [[SongsViewController alloc] initWithStyle:UITableViewStylePlain]; + } + return songsViewController; +} + +- (UINavigationController *)songsNavigationController { + if (songsNavigationController == nil) { + songsNavigationController = [[UINavigationController alloc] initWithRootViewController:self.songsViewController]; + } + return songsNavigationController; +} + +- (IBAction)startParser { + [self.navigationController presentModalViewController:self.songsNavigationController animated:YES]; + [self.songsViewController parseWithParserType:self.parserSelection.row]; +} + +- (NSUInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSUInteger)section { + return 2; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString * const kCellIdentifier = @"MyCell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease]; + } + cell.textLabel.text = (indexPath.row == 0) ? [CocoaXMLParser parserName] : [LibXMLParser parserName]; + cell.accessoryType = ([indexPath isEqual:parserSelection]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + self.parserSelection = indexPath; + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [tableView reloadData]; +} + +@end diff --git a/XMLPerformance/Classes/Song.h b/XMLPerformance/Classes/Song.h new file mode 100644 index 0000000..206521c --- /dev/null +++ b/XMLPerformance/Classes/Song.h @@ -0,0 +1,64 @@ +/* + File: Song.h + Abstract: Contains the parsed information about a song. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface Song : NSObject { + NSString *title; + NSString *artist; + NSString *album; + NSDate *releaseDate; + NSString *category; +} + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *artist; +@property (nonatomic, copy) NSString *album; +@property (nonatomic, copy) NSDate *releaseDate; +@property (nonatomic, copy) NSString *category; + +@end diff --git a/XMLPerformance/Classes/Song.m b/XMLPerformance/Classes/Song.m new file mode 100644 index 0000000..9284d9c --- /dev/null +++ b/XMLPerformance/Classes/Song.m @@ -0,0 +1,63 @@ +/* + File: Song.m + Abstract: Contains the parsed information about a song. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "Song.h" + +@implementation Song + +@synthesize title, artist, album, releaseDate, category; + +- (void)dealloc { + [title release]; + [artist release]; + [album release]; + [releaseDate release]; + [category release]; + [super dealloc]; +} + +@end diff --git a/XMLPerformance/Classes/SongsViewController.h b/XMLPerformance/Classes/SongsViewController.h new file mode 100644 index 0000000..a04f97a --- /dev/null +++ b/XMLPerformance/Classes/SongsViewController.h @@ -0,0 +1,69 @@ +/* + File: SongsViewController.h + Abstract: Creates and runs an instance of the parser type chosen by the user, and displays the parsed songs in a table. Selecting a row in the table navigates to a detail view for that song. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "iTunesRSSParser.h" + +@class DetailController; + +@interface SongsViewController : UITableViewController { + NSMutableArray *songs; + DetailController *detailController; + iTunesRSSParser *parser; +} + +@property (nonatomic, retain) NSMutableArray *songs; +@property (nonatomic, retain, readonly) DetailController *detailController; +@property (nonatomic, retain) iTunesRSSParser *parser; + +// Called by the ParserChoiceViewController based on the selected parser type. +- (void)parseWithParserType:(XMLParserType)parserType; + +// When the parsing is finished, the user can return to the ParserChoiceViewController by touching the button associated with this action. +- (IBAction)returnToParserChoices; + +@end diff --git a/XMLPerformance/Classes/SongsViewController.m b/XMLPerformance/Classes/SongsViewController.m new file mode 100644 index 0000000..0d3c4ab --- /dev/null +++ b/XMLPerformance/Classes/SongsViewController.m @@ -0,0 +1,163 @@ +/* + File: SongsViewController.m + Abstract: Creates and runs an instance of the parser type chosen by the user, and displays the parsed songs in a table. Selecting a row in the table navigates to a detail view for that song. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "SongsViewController.h" +#import "DetailController.h" +#import "Song.h" +#import "LibXMLParser.h" +#import "CocoaXMLParser.h" + +@implementation SongsViewController + +@synthesize songs, parser; + +- (void)dealloc { + [songs release]; + [detailController release]; + [parser release]; + [super dealloc]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + UIBarButtonItem *doneItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(returnToParserChoices)] autorelease]; + self.navigationItem.rightBarButtonItem = doneItem; +} + +- (DetailController *)detailController { + if (detailController == nil) { + detailController = [[DetailController alloc] initWithStyle:UITableViewStyleGrouped]; + } + return detailController; +} + +- (void)viewWillAppear:(BOOL)animated { + NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow]; + if (selectedRowIndexPath != nil) { + [self.tableView deselectRowAtIndexPath:selectedRowIndexPath animated:NO]; + } +} + +// This method will be called repeatedly - once each time the user choses to parse. +- (void)parseWithParserType:(XMLParserType)parserType { + self.navigationItem.rightBarButtonItem.enabled = NO; + // Reset the title + self.title = NSLocalizedString(@"Getting Top Songs...", @"Waiting for first results label"); + // Allocate the array for song storage, or empty the results of previous parses + if (songs == nil) { + self.songs = [NSMutableArray array]; + } else { + [songs removeAllObjects]; + [self.tableView reloadData]; + } + // Determine the Class for the parser + Class parserClass = nil; + switch (parserType) { + case XMLParserTypeLibXMLParser: { + parserClass = [LibXMLParser class]; + } break; + case XMLParserTypeNSXMLParser: { + parserClass = [CocoaXMLParser class]; + } break; + default: { + NSAssert1(NO, @"Unknown parser type %d", parserType); + } break; + } + // Create the parser, set its delegate, and start it. + self.parser = [[[parserClass alloc] init] autorelease]; + parser.delegate = self; + [parser start]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [songs count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kCellIdentifier = @"MyCell"; + UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease]; + cell.textLabel.font = [UIFont boldSystemFontOfSize:14.0]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + cell.textLabel.text = [[songs objectAtIndex:indexPath.row] title]; + return cell; +} + +- (void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + self.detailController.song = [songs objectAtIndex:indexPath.row]; + [self.navigationController pushViewController:self.detailController animated:YES]; +} + +- (IBAction)returnToParserChoices { + [self dismissModalViewControllerAnimated:YES]; +} + +#pragma mark Implementation + +- (void)parserDidEndParsingData:(iTunesRSSParser *)parser { + self.title = [NSString stringWithFormat:NSLocalizedString(@"Top %d Songs", @"Top Songs format"), [songs count]]; + [self.tableView reloadData]; + self.navigationItem.rightBarButtonItem.enabled = YES; + self.parser = nil; +} + +- (void)parser:(iTunesRSSParser *)parser didParseSongs:(NSArray *)parsedSongs { + [songs addObjectsFromArray:parsedSongs]; + // Three scroll view properties are checked to keep the user interface smooth during parse. When new objects are delivered by the parser, the table view is reloaded to display them. If the table is reloaded while the user is scrolling, this can result in eratic behavior. dragging, tracking, and decelerating can be checked for this purpose. When the parser finishes, reloadData will be called in parserDidEndParsingData:, guaranteeing that all data will ultimately be displayed even if reloadData is not called in this method because of user interaction. + if (!self.tableView.dragging && !self.tableView.tracking && !self.tableView.decelerating) { + self.title = [NSString stringWithFormat:NSLocalizedString(@"Top %d Songs", @"Top Songs format"), [songs count]]; + [self.tableView reloadData]; + } +} + +- (void)parser:(iTunesRSSParser *)parser didFailWithError:(NSError *)error { + // handle errors as appropriate to your application... +} + +@end diff --git a/XMLPerformance/Classes/Statistics.h b/XMLPerformance/Classes/Statistics.h new file mode 100644 index 0000000..d99c3f2 --- /dev/null +++ b/XMLPerformance/Classes/Statistics.h @@ -0,0 +1,76 @@ +/* + File: Statistics.h + Abstract: Collection of C functions for database storage of parser performance metrics. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import "iTunesRSSParser.h" + +/* +These functions encapsulate all interactions with a SQLite database used to store the amount of time taken to download +and parse XML data. The measurements are stored by parser type, and aggregate queries retrieve the mean measurements, again +by parser type. +*/ + +// Close the database. This should be called when the application terminates. +void CloseStatisticsDatabase(void); + +// Queries: + +// Retrieve the number of measurements available for a parser of a given type. +NSUInteger NumberOfRunsForParserType(XMLParserType type); +// Retrieve the average number of seconds from starting the download to finishing the download for a parser of a given type. +double MeanDownloadTimeForParserType(XMLParserType type); +// Retrieve the average number of seconds spent in parsing code for a parser of a given type. +double MeanParseTimeForParserType(XMLParserType type); +// Retrieve the average number of seconds from starting the download to finishing the parse for a parser of a given type. +double MeanTotalTimeForParserType(XMLParserType type); +// Delete all stored measurements. +void ResetStatisticsDatabase(void); + +// Store a measurement to the database. +void WriteStatisticToDatabase(XMLParserType type, double downloadDuration, double parseDuration, double totalDuration); + + diff --git a/XMLPerformance/Classes/Statistics.m b/XMLPerformance/Classes/Statistics.m new file mode 100644 index 0000000..1e33385 --- /dev/null +++ b/XMLPerformance/Classes/Statistics.m @@ -0,0 +1,277 @@ +/* + File: Statistics.m + Abstract: Collection of C functions for database storage of parser performance metrics. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "Statistics.h" +// This includes the header for the SQLite library. +#import + +static sqlite3 *database = NULL; +static sqlite3_stmt *insert_statement = NULL; +static sqlite3_stmt *count_statement = NULL; +static sqlite3_stmt *mean_download_time_statement = NULL; +static sqlite3_stmt *mean_parse_time_statement = NULL; +static sqlite3_stmt *mean_download_and_parse_time_statement = NULL; +static sqlite3_stmt *reset_statement = NULL; + +// Returns a reference to the database, creating and opening if necessary. +sqlite3 *Database(void) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + if (database == NULL) { + // First, test for existence. + BOOL success; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"stats.sqlite"]; + if ([fileManager fileExistsAtPath:writableDBPath] == NO) { + // The writable database does not exist, so copy the default to the appropriate location. + NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:@"stats" ofType:@"sqlite"]; + success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; + if (!success) { + NSCAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); + } + } + // Open the database. The database was prepared outside the application. + if (sqlite3_open([writableDBPath UTF8String], &database) != SQLITE_OK) { + // Even though the open failed, call close to properly clean up resources. + sqlite3_close(database); + database = NULL; + NSCAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database)); + // Additional error handling, as appropriate... + } + } + return database; +} + +// Close the database. This should be called when the application terminates. +void CloseStatisticsDatabase() { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + // Finalize (delete) all of the SQLite compiled queries. + if (insert_statement != NULL) { + sqlite3_finalize(insert_statement); + // reassign the pointer to NULL so that it will be correctly reinitialized if needed later. This pattern repeats for the rest of the statements below. + insert_statement = NULL; + } + if (count_statement != NULL) { + sqlite3_finalize(count_statement); + count_statement = NULL; + } + if (mean_download_time_statement != NULL) { + sqlite3_finalize(mean_download_time_statement); + mean_download_time_statement = NULL; + } + if (mean_parse_time_statement != NULL) { + sqlite3_finalize(mean_parse_time_statement); + mean_parse_time_statement = NULL; + } + if (mean_download_and_parse_time_statement != NULL) { + sqlite3_finalize(mean_download_and_parse_time_statement); + mean_download_and_parse_time_statement = NULL; + } + if (reset_statement != NULL) { + sqlite3_finalize(reset_statement); + reset_statement = NULL; + } + if (database == NULL) return; + // Close the database. + if (sqlite3_close(database) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to close database with message '%s'.", sqlite3_errmsg(database)); + } + database = NULL; +} + +// Retrieve the number of measurements available for a parser of a given type. +NSUInteger NumberOfRunsForParserType(XMLParserType type) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + sqlite3 *db = Database(); + if (count_statement == NULL) { + // Prepare (compile) the SQL statement. + static const char *sql = "SELECT COUNT(*) FROM statistic WHERE parser_type = ?"; + if (sqlite3_prepare_v2(db, sql, -1, &count_statement, NULL) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); + } + } + // Bind the parser type to the statement. + if (sqlite3_bind_int(count_statement, 1, type) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + // Execute the query. + int success = sqlite3_step(count_statement); + NSUInteger numberOfRuns = 0; + if (success == SQLITE_ROW) { + // Store the value of the first and only column for return. + numberOfRuns = sqlite3_column_int(count_statement, 0); + } else { + NSCAssert1(0, @"Error: failed to execute query with message '%s'.", sqlite3_errmsg(db)); + } + // Reset the query for the next use. + sqlite3_reset(count_statement); + return numberOfRuns; +} + +// Retrieve the average number of seconds from starting the download to finishing the download for a parser of a given type. +double MeanDownloadTimeForParserType(XMLParserType type) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + sqlite3 *db = Database(); + if (mean_download_time_statement == NULL) { + static const char *sql = "SELECT AVG(download_duration) FROM statistic WHERE parser_type = ?"; + if (sqlite3_prepare_v2(db, sql, -1, &mean_download_time_statement, NULL) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); + } + } + if (sqlite3_bind_int(mean_download_time_statement, 1, type) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + int success = sqlite3_step(mean_download_time_statement); + double meanValue = 0; + if (success == SQLITE_ROW) { + meanValue = sqlite3_column_double(mean_download_time_statement, 0); + } else { + NSCAssert1(0, @"Error: failed to execute query with message '%s'.", sqlite3_errmsg(db)); + } + // Reset the query for the next use. + sqlite3_reset(mean_download_time_statement); + return meanValue; +} + +// Retrieve the average number of seconds spent in parsing code for a parser of a given type. +double MeanParseTimeForParserType(XMLParserType type) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + sqlite3 *db = Database(); + if (mean_parse_time_statement == NULL) { + static const char *sql = "SELECT AVG(parse_duration) FROM statistic WHERE parser_type = ?"; + if (sqlite3_prepare_v2(db, sql, -1, &mean_parse_time_statement, NULL) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); + } + } + if (sqlite3_bind_int(mean_parse_time_statement, 1, type) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + int success = sqlite3_step(mean_parse_time_statement); + double meanValue = 0; + if (success == SQLITE_ROW) { + meanValue = sqlite3_column_double(mean_parse_time_statement, 0); + } else { + NSCAssert1(0, @"Error: failed to execute query with message '%s'.", sqlite3_errmsg(db)); + } + // Reset the query for the next use. + sqlite3_reset(mean_parse_time_statement); + return meanValue; +} + +// Retrieve the average number of seconds from starting the download to finishing the parse for a parser of a given type. This is the total amount of time the parser needs to do all of its work. +double MeanTotalTimeForParserType(XMLParserType type) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + sqlite3 *db = Database(); + if (mean_download_and_parse_time_statement == NULL) { + static const char *sql = "SELECT AVG(total_duration) FROM statistic WHERE parser_type = ?"; + if (sqlite3_prepare_v2(db, sql, -1, &mean_download_and_parse_time_statement, NULL) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); + } + } + if (sqlite3_bind_int(mean_download_and_parse_time_statement, 1, type) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + int success = sqlite3_step(mean_download_and_parse_time_statement); + double meanValue = 0; + if (success == SQLITE_ROW) { + meanValue = sqlite3_column_double(mean_download_and_parse_time_statement, 0); + } else { + NSCAssert1(0, @"Error: failed to execute query with message '%s'.", sqlite3_errmsg(db)); + } + // Reset the query for the next use. + sqlite3_reset(mean_download_and_parse_time_statement); + return meanValue; +} + +// Delete all stored measurements. You may want to do this after running the application using performance tools, which add considerable overhead and will distort the measurements. This is also the case if you were using the debugger, particularly if you were pausing execution. +void ResetStatisticsDatabase(void) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + sqlite3 *db = Database(); + if (reset_statement == NULL) { + static const char *sql = "DELETE FROM statistic"; + if (sqlite3_prepare_v2(db, sql, -1, &reset_statement, NULL) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); + } + } + int success = sqlite3_step(reset_statement); + if (success == SQLITE_ERROR) { + NSCAssert1(0, @"Error: failed to execute query with message '%s'.", sqlite3_errmsg(db)); + } + // Reset the query for the next use. + sqlite3_reset(reset_statement); +} + +// Store a measurement to the database. +void WriteStatisticToDatabase(XMLParserType type, double downloadDuration, double parseDuration, double totalDuration) { + NSCAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + sqlite3 *db = Database(); + if (insert_statement == NULL) { + static const char *sql = "INSERT INTO statistic (parser_type, download_duration, parse_duration, total_duration) VALUES(?, ?, ?, ?)"; + if (sqlite3_prepare_v2(db, sql, -1, &insert_statement, NULL) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); + } + } + if (sqlite3_bind_int(insert_statement, 1, type) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + if (sqlite3_bind_double(insert_statement, 2, downloadDuration) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + if (sqlite3_bind_double(insert_statement, 3, parseDuration) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + if (sqlite3_bind_double(insert_statement, 4, totalDuration) != SQLITE_OK) { + NSCAssert1(0, @"Error: failed to bind variable with message '%s'.", sqlite3_errmsg(db)); + } + int success = sqlite3_step(insert_statement); + sqlite3_reset(insert_statement); + if (success == SQLITE_ERROR) { + NSCAssert1(0, @"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(db)); + } +} diff --git a/XMLPerformance/Classes/StatsViewController.h b/XMLPerformance/Classes/StatsViewController.h new file mode 100644 index 0000000..df67d38 --- /dev/null +++ b/XMLPerformance/Classes/StatsViewController.h @@ -0,0 +1,60 @@ +/* + File: StatsViewController.h + Abstract: Displays statistics about each parser, including its average time to download the XML data, parse it, and the total average time from beginning the download to completing the parse. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface StatsViewController : UIViewController { + // An outlet to the table is required to reload its contents when appropriate. + UITableView *tableView; +} + +@property (nonatomic, retain) IBOutlet UITableView *tableView; + +// Action method for the button that resets statistics. +- (IBAction)resetStatistics; + +@end diff --git a/XMLPerformance/Classes/StatsViewController.m b/XMLPerformance/Classes/StatsViewController.m new file mode 100644 index 0000000..2a026e0 --- /dev/null +++ b/XMLPerformance/Classes/StatsViewController.m @@ -0,0 +1,125 @@ +/* + File: StatsViewController.m + Abstract: Displays statistics about each parser, including its average time to download the XML data, parse it, and the total average time from beginning the download to completing the parse. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "StatsViewController.h" +#import "Statistics.h" +#import "CocoaXMLParser.h" +#import "LibXMLParser.h" + +@implementation StatsViewController + +@synthesize tableView; + +- (void)dealloc { + [tableView release]; + [super dealloc]; +} + +- (void)viewDidLoad { + // We use a slightly shorter than usual row height so that all the statistics fit on the page without scrolling. + // This should be used cautiously, as it can easily result in a user interface that provides a bad experience. It is + // acceptable here partly because the table does not support any user interaction. + // + // This could also be achieved using the UITableViewDelegate method tableView:heightForRowAtIndexPath: + // However, this comes with a performance penalty, as it is called for each row in the table. Unless the rows + // need to be of varying heights, the rowHeight property should be used. + tableView.allowsSelection = NO; + tableView.rowHeight = 31; +} + +- (void)viewDidUnload { + self.tableView = nil; +} + +- (void)viewWillAppear:(BOOL)animated { + [tableView reloadData]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 2; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return 3; +} + +- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kStatisticsCellID = @"StatisticsCell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kStatisticsCellID]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kStatisticsCellID] autorelease]; + } + switch (indexPath.row) { + case 0: { + cell.textLabel.text = NSLocalizedString(@"Mean Download Time", @"Mean Download Time format"); + cell.detailTextLabel.text = [NSString stringWithFormat:@"%.4fs", MeanDownloadTimeForParserType(indexPath.section)]; + } break; + case 1: { + cell.textLabel.text = NSLocalizedString(@"Mean Parse Time", @"Mean Parse Time format"); + cell.detailTextLabel.text = [NSString stringWithFormat:@"%.4fs", MeanParseTimeForParserType(indexPath.section)]; + } break; + case 2: { + cell.textLabel.text = NSLocalizedString(@"Mean Total Time", @"Mean Total Time format"); + cell.detailTextLabel.text = [NSString stringWithFormat:@"%.4fs", MeanTotalTimeForParserType(indexPath.section)]; + } break; + } + return cell; +} + +- (NSString *)tableView:(UITableView *)tv titleForHeaderInSection:(NSInteger)section { + NSUInteger numberOfRuns = NumberOfRunsForParserType(section); + NSString *parserName = (section == 0) ? [CocoaXMLParser parserName] : [LibXMLParser parserName]; + NSString *format = (numberOfRuns == 1) ? NSLocalizedString(@"%@ (%d run):", @"One Run format") : NSLocalizedString(@"%@ (%d runs):", @"Multiple Runs format"); + return [NSString stringWithFormat:format, parserName, numberOfRuns]; +} + +- (IBAction)resetStatistics { + ResetStatisticsDatabase(); + [tableView reloadData]; +} + +@end diff --git a/XMLPerformance/Classes/iTunesRSSParser.h b/XMLPerformance/Classes/iTunesRSSParser.h new file mode 100644 index 0000000..4eae1ce --- /dev/null +++ b/XMLPerformance/Classes/iTunesRSSParser.h @@ -0,0 +1,111 @@ +/* + File: iTunesRSSParser.h + Abstract: Base class for the two parsers, this class handles interactions with a delegate object (the SongsViewController in this sample) and provides basic functionality common to both parsers. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +typedef enum { + XMLParserTypeAbstract = -1, + XMLParserTypeNSXMLParser = 0, + XMLParserTypeLibXMLParser +} XMLParserType; + +@class iTunesRSSParser, Song; + +// Protocol for the parser to communicate with its delegate. +@protocol iTunesRSSParserDelegate + +@optional +// Called by the parser when parsing is finished. +- (void)parserDidEndParsingData:(iTunesRSSParser *)parser; +// Called by the parser in the case of an error. +- (void)parser:(iTunesRSSParser *)parser didFailWithError:(NSError *)error; +// Called by the parser when one or more songs have been parsed. This method may be called multiple times. +- (void)parser:(iTunesRSSParser *)parser didParseSongs:(NSArray *)parsedSongs; + +@end + + +@interface iTunesRSSParser : NSObject { + id delegate; + NSMutableArray *parsedSongs; + // This time interval is used to measure the overall time the parser takes to download and parse XML. + NSTimeInterval startTimeReference; + NSTimeInterval downloadStartTimeReference; + double parseDuration; + double downloadDuration; + double totalDuration; +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, retain) NSMutableArray *parsedSongs; +@property NSTimeInterval startTimeReference; +@property NSTimeInterval downloadStartTimeReference; +@property double parseDuration; +@property double downloadDuration; +@property double totalDuration; + ++ (NSString *)parserName; ++ (XMLParserType)parserType; + +- (void)start; + +// Subclasses must implement this method. It will be invoked on a secondary thread to keep the application responsive. +// Although NSURLConnection is inherently asynchronous, the parsing can be quite CPU intensive on the device, so +// the user interface can be kept responsive by moving that work off the main thread. This does create additional +// complexity, as any code which interacts with the UI must then do so in a thread-safe manner. +- (void)downloadAndParse:(NSURL *)url; + +// Subclasses should invoke these methods and let the superclass manage communication with the delegate. +// Each of these methods must be invoked on the main thread. +- (void)downloadStarted; +- (void)downloadEnded; +- (void)parseEnded; +- (void)parsedSong:(Song *)song; +- (void)parseError:(NSError *)error; +- (void)addToParseDuration:(NSNumber *)duration; + +@end diff --git a/XMLPerformance/Classes/iTunesRSSParser.m b/XMLPerformance/Classes/iTunesRSSParser.m new file mode 100644 index 0000000..822f979 --- /dev/null +++ b/XMLPerformance/Classes/iTunesRSSParser.m @@ -0,0 +1,135 @@ +/* + File: iTunesRSSParser.m + Abstract: Base class for the two parsers, this class handles interactions with a delegate object (the SongsViewController in this sample) and provides basic functionality common to both parsers. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "iTunesRSSParser.h" +#import "Song.h" +#import "Statistics.h" + +static NSUInteger kCountForNotification = 10; + +@implementation iTunesRSSParser + +@synthesize delegate, parsedSongs, startTimeReference, downloadStartTimeReference, parseDuration, downloadDuration, totalDuration; + ++ (NSString *)parserName { + NSAssert((self != [iTunesRSSParser class]), @"Class method parserName not valid for abstract base class iTunesRSSParser"); + return @"Base Class"; +} + ++ (XMLParserType)parserType { + NSAssert((self != [iTunesRSSParser class]), @"Class method parserType not valid for abstract base class iTunesRSSParser"); + return XMLParserTypeAbstract; +} + +- (void)start { + self.startTimeReference = [NSDate timeIntervalSinceReferenceDate]; + [[NSURLCache sharedURLCache] removeAllCachedResponses]; + self.parsedSongs = [NSMutableArray array]; + NSURL *url = [NSURL URLWithString:@"http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStore.woa/wpa/MRSS/newreleases/limit=300/rss.xml"]; + [NSThread detachNewThreadSelector:@selector(downloadAndParse:) toTarget:self withObject:url]; +} + +- (void)dealloc { + [parsedSongs release]; + [super dealloc]; +} + +- (void)downloadAndParse:(NSURL *)url { + NSAssert([self isMemberOfClass:[iTunesRSSParser class]] == NO, @"Object is of abstract base class iTunesRSSParser"); +} + +- (void)downloadStarted { + NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + self.downloadStartTimeReference = [NSDate timeIntervalSinceReferenceDate]; + [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; +} + +- (void)downloadEnded { + NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - self.downloadStartTimeReference; + downloadDuration += duration; + [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; +} + +- (void)parseEnded { + NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parser:didParseSongs:)] && [parsedSongs count] > 0) { + [self.delegate parser:self didParseSongs:parsedSongs]; + } + [self.parsedSongs removeAllObjects]; + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parserDidEndParsingData:)]) { + [self.delegate parserDidEndParsingData:self]; + } + NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - self.startTimeReference; + totalDuration = duration; + WriteStatisticToDatabase([[self class] parserType], downloadDuration, parseDuration, totalDuration); +} + +- (void)parsedSong:(Song *)song { + NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + [self.parsedSongs addObject:song]; + if (self.parsedSongs.count > kCountForNotification) { + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parser:didParseSongs:)]) { + [self.delegate parser:self didParseSongs:parsedSongs]; + } + [self.parsedSongs removeAllObjects]; + } +} + +- (void)parseError:(NSError *)error { + NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parser:didFailWithError:)]) { + [self.delegate parser:self didFailWithError:error]; + } +} + +- (void)addToParseDuration:(NSNumber *)duration { + NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__); + parseDuration += [duration doubleValue]; +} + +@end diff --git a/XMLPerformance/Images/Default.png b/XMLPerformance/Images/Default.png new file mode 100644 index 0000000..1cbb859 Binary files /dev/null and b/XMLPerformance/Images/Default.png differ diff --git a/XMLPerformance/Images/Icon-72.png b/XMLPerformance/Images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/XMLPerformance/Images/Icon-72.png differ diff --git a/XMLPerformance/Images/Icon-Small-50.png b/XMLPerformance/Images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/XMLPerformance/Images/Icon-Small-50.png differ diff --git a/XMLPerformance/Images/Icon-Small.png b/XMLPerformance/Images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/XMLPerformance/Images/Icon-Small.png differ diff --git a/XMLPerformance/Images/Icon-Small@2x.png b/XMLPerformance/Images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/XMLPerformance/Images/Icon-Small@2x.png differ diff --git a/XMLPerformance/Images/Icon.png b/XMLPerformance/Images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/XMLPerformance/Images/Icon.png differ diff --git a/XMLPerformance/Images/Icon@2x.png b/XMLPerformance/Images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/XMLPerformance/Images/Icon@2x.png differ diff --git a/XMLPerformance/Images/Stat.png b/XMLPerformance/Images/Stat.png new file mode 100644 index 0000000..4ff8d98 Binary files /dev/null and b/XMLPerformance/Images/Stat.png differ diff --git a/XMLPerformance/Images/XML.png b/XMLPerformance/Images/XML.png new file mode 100644 index 0000000..40193f3 Binary files /dev/null and b/XMLPerformance/Images/XML.png differ diff --git a/XMLPerformance/Images/iTunesArtwork b/XMLPerformance/Images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/XMLPerformance/Images/iTunesArtwork differ diff --git a/XMLPerformance/Info.plist b/XMLPerformance/Info.plist new file mode 100644 index 0000000..ad3abcf --- /dev/null +++ b/XMLPerformance/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.3 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/form.template b/XMLPerformance/Metrics/ObjectAlloc.trace/form.template new file mode 100644 index 0000000..8eb4a8b Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/form.template differ diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/instrument_data/EF4DC038-8A17-421A-8050-39DD0980C06F/run_data/1.run.zip b/XMLPerformance/Metrics/ObjectAlloc.trace/instrument_data/EF4DC038-8A17-421A-8050-39DD0980C06F/run_data/1.run.zip new file mode 100644 index 0000000..e604933 Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/instrument_data/EF4DC038-8A17-421A-8050-39DD0980C06F/run_data/1.run.zip differ diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/instrument_data/EF4DC038-8A17-421A-8050-39DD0980C06F/run_data/2.run.zip b/XMLPerformance/Metrics/ObjectAlloc.trace/instrument_data/EF4DC038-8A17-421A-8050-39DD0980C06F/run_data/2.run.zip new file mode 100644 index 0000000..5cfdef6 Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/instrument_data/EF4DC038-8A17-421A-8050-39DD0980C06F/run_data/2.run.zip differ diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/1.run/6C24B9AC-4638-42D4-AF57-315185C86CDF.zip b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/1.run/6C24B9AC-4638-42D4-AF57-315185C86CDF.zip new file mode 100644 index 0000000..596cf1c Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/1.run/6C24B9AC-4638-42D4-AF57-315185C86CDF.zip differ diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/1.run/E2C314E9-B4B5-408C-969B-E2A7E6420802.zip b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/1.run/E2C314E9-B4B5-408C-969B-E2A7E6420802.zip new file mode 100644 index 0000000..8c71f68 Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/1.run/E2C314E9-B4B5-408C-969B-E2A7E6420802.zip differ diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/2.run/568D2A45-161F-488C-A890-76B89983F348.zip b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/2.run/568D2A45-161F-488C-A890-76B89983F348.zip new file mode 100644 index 0000000..a7b9e3b Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/2.run/568D2A45-161F-488C-A890-76B89983F348.zip differ diff --git a/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/2.run/815219BC-D1CE-4B0B-8668-22E1C7A371EC.zip b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/2.run/815219BC-D1CE-4B0B-8668-22E1C7A371EC.zip new file mode 100644 index 0000000..b1f54af Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAlloc.trace/shared_data/2.run/815219BC-D1CE-4B0B-8668-22E1C7A371EC.zip differ diff --git a/XMLPerformance/Metrics/ObjectAllocScreenshot.png b/XMLPerformance/Metrics/ObjectAllocScreenshot.png new file mode 100644 index 0000000..c756eaa Binary files /dev/null and b/XMLPerformance/Metrics/ObjectAllocScreenshot.png differ diff --git a/XMLPerformance/Metrics/StatisticsScreenshot.png b/XMLPerformance/Metrics/StatisticsScreenshot.png new file mode 100644 index 0000000..8a63ff4 Binary files /dev/null and b/XMLPerformance/Metrics/StatisticsScreenshot.png differ diff --git a/XMLPerformance/Prefix.pch b/XMLPerformance/Prefix.pch new file mode 100644 index 0000000..6d8734f --- /dev/null +++ b/XMLPerformance/Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'XMLPerformance' target in the 'XMLPerformance' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/XMLPerformance/ReadMe.txt b/XMLPerformance/ReadMe.txt new file mode 100644 index 0000000..5eea2aa --- /dev/null +++ b/XMLPerformance/ReadMe.txt @@ -0,0 +1,93 @@ +XMLPerformance + +=========================================================================== +ABSTRACT + +This sample explores two approaches to parsing XML, focusing on performance with respect to speed, memory footprint, and user experience. The XML data used is the current "Top 300" songs from the iTunes store. The data itself is not particularly important to the sample - it was chosen because of its simplicity, availability, and because the size (approximately 850KB) is sufficient to demonstrate the performance issues central to the sample. + +=========================================================================== +DETAILED DESCRIPTION + +The iPhone SDK provides two APIs for parsing XML. At the Objective C level, NSXMLParser implements an event-driven approach with a delegate object implementing methods for handling each of the "events" the parser encounters during its single pass over the XML data. Events most commonly of interest are the beginning and ending of elements and character data within elements. The other API in the SDK, the C library "libxml2", has a similar approach known as SAX ("Simple API for XML"). Because it is C, callback functions are used instead of delegate methods, and the parameters are C strings instead of NSString objects. + +This sample allows the user to choose between these two approaches for parsing a simple RSS feed. The feed, iTunes' "Top 300" songs, is parsed into an array of "Song" objects displayed in a table. Details about a song can be viewed by selecting the song. The sample also tracks statistics related to the parse: the amount of time required to download the data, and the amount of time spent parsing the data. These statistics are stored in a SQLite database in the application's Documents directory, and the average (mean) of all runs with each parser can be viewed in a table. + +The process for linking and using libraries is slightly more complex than the same process for frameworks. The primary consideration is making it possible for the compiler to find the header file(s) associated with the library. With a framework, the executable code and header files are packaged together in a way that Xcode understands and placed in locations that Xcode has knowledge of via the SDK. Library header files, on the other hand, are typically found in a different location than the executable itself. Though they are still part of the SDK, it is necessary to specify the location in the project build settings. We use the "Header Search Paths" setting for this purpose. The SDKROOT variable should prefix the path as the location where the SDK is installed or the SDK versions available may differ. For this project, the setting is: + +HEADER_SEARCH_PATHS = $SDKROOT/usr/include/libxml2 + +=========================================================================== +PERFORMANCE + +The focus of this sample is performance. There are three areas of concern: speed, memory, and user experience. For applications dealing with small amounts of XML data, none of these may be significant. In this case, developers should use the API with which they are most comfortable. For most developers, this will be the NSXMLParser API in the Foundation framework. + +For large datasets, developers should test their application with an iPhone or iPod touch and evaluate the application's performance with respect to speed, memory, and user experience. It's important that this be done with a device and not with the iPhone Simulator because the Simulator does not accurately reflect the memory and processor constraints. The techniques implemented in this sample can help the developer improve performance and memory usage, if it's determined that such a need exists. + +Memory: + +NSXMLParser be used with either a NSURL or a NSData. In both cases, all of the XML data is loaded into memory. On iOS, this can be a very significant consideration. The actual parsing will require additional memory, particularly with intermediate objects created and autoreleased. You can create and destroy additional autorelease pools in the course of parsing, and mitigate this somewhat, but you are still managing the memory pool on top of the initial allocation for the XML data itself. + +With libxml, you can parse XML data in chunks. This alleviates the need to have all of the data in memory at one time, possibly resulting in a considerably smaller memory footprint. This could be applied to data downloaded using NSURLConnection. The NSURLConnection delegate method connection:didReceiveData: may be called multiple times during a download, and rather than accumulate the data, it can be immediately passed to the libxml parser. When the parser is finished, the data can be discarded. In addition, libxml callbacks use C strings rather than Objective C objects. In general, the overhead for objects is not significant, but in large numbers, in tight loops, this adds up. In particular, when the character data in an XML element is parsed, that data is delivered as one or more parse "events". For NSXMLParser, these events result as the delegate method parser:foundCharacters:, with an autoreleased NSString as the container for the character data. In libxml, the events call in the registered callback function, passing a pointer to a C string buffer. This offers another opportunity to optimize on memory management. Rather than creating an object with each call of the function, the character data can be accumulated in a separate buffer, until all data for the current XML element has been handled. Only at that point does a NSString object need to be created. + +Speed: + +Speed is obviously important to users, as waiting for long operations to complete is not a good experience. In addition, speed is an indirect reflection of processor load, which is in turn tied to power consumption. Hence, an more rapidly executing code path not only provides a better user experience with the application itself, it consumes less power, leading to longer battery life and a better experience for the overall device. + +User Experience: + +At times CPU and/or IO intensive operations cannot be avoided. A positive user experience can still be provided in these cases by offloading work to separate threads, using NSThread, NSOperation, or lower level threading APIs such as POSIX threads(pthreads). This sample involves both lengthy IO (downloading the XML data) and CPU intensive work (parsing the XML). To keep the interface responsive, this work is done in a secondary thread. Periodically, the secondary thread updates the primary thread with the results of the work it has done. In turn, the user interface displays the new data to the user. If this approach were not used, the user would experience 3 or more seconds in which the application would appear to hang while the data was being downloaded and parsed. + +Metrics: + +This sample includes some screenshots and a sample trace document from Instruments. The first screenshot, "StatisticsScreenshot.png", is captured from the application, showing the statistics that might be seen after running each parser several times. The second, "ObjectAllocScreenshot.png", shows the Instruments window with one run from each parser. The top run is a run with the LibXMLParser. Note the significantly smaller peak memory usage. In addition, the trace document itself, included as a zipped archive, can be opened and examined. + +=========================================================================== +SYSTEM REQUIREMENTS + +Mac OS X 10.6, Xcode 3.2.3, iOS 4.0 + +=========================================================================== +PACKAGING LIST + +AppDelegate +Adds the main UITabBarController's view to the application's window. + +ParserChoiceViewController +Provides an interface for choosing and running one of the two available parsers. + +SongsViewController +Creates and runs an instance of the parser type chosen by the user, and displays the parsed songs in a table. Selecting a row in the table navigates to a detail view for that song. + +DetailViewController +Displays details of a single parsed song. + +Song +Contains the parsed information about a song. + +iTunesRSSParser +Base class for the two parsers, this class handles interactions with a delegate object (the SongsViewController in this sample) and provides basic functionality common to both parsers. + +LibXMLParser +Subclass of iTunesRSSParser that uses libxml2 for parsing the XML data. + +CocoaXMLParser +Subclass of iTunesRSSParser that uses the Foundation framework's NSXMLParser for parsing the XML data. + +StatsViewController +Displays statistics about each parser, including its average time to download the XML data, parse it, and the total average time from beginning the download to completing the parse. + +Statistics +Collection of C functions for database storage of parser performance metrics. These functions manage all interactions with the SQLite database, including both writes to the database and queries for aggregate statistics about the measurements. + +main.m +Launches the application. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS +1.3 Minor updates for iOS 4.0. +1.2 Fixed a memory leak in LibXMLParser implementation of the NSURLConnection delegate method -connectionDidFinishLoading:. Improved autorelease pool management in Cocoa parser. +1.1 Updated user interface for iPhone SDK 3.0 and fixed bug in Xcode build setting for header search paths. +1.0 Initial version published. + +=========================================================================== +Copyright (C) 2010 Apple Inc. All rights reserved. diff --git a/XMLPerformance/XMLPerformance.xcodeproj/project.pbxproj b/XMLPerformance/XMLPerformance.xcodeproj/project.pbxproj new file mode 100644 index 0000000..89ea32e --- /dev/null +++ b/XMLPerformance/XMLPerformance.xcodeproj/project.pbxproj @@ -0,0 +1,414 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 02084C7A11E534E800199A4D /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7011E534E800199A4D /* Default.png */; }; + 02084C7B11E534E800199A4D /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7111E534E800199A4D /* Icon-72.png */; }; + 02084C7C11E534E800199A4D /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7211E534E800199A4D /* Icon-Small-50.png */; }; + 02084C7D11E534E800199A4D /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7311E534E800199A4D /* Icon-Small.png */; }; + 02084C7E11E534E800199A4D /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7411E534E800199A4D /* Icon-Small@2x.png */; }; + 02084C7F11E534E800199A4D /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7511E534E800199A4D /* Icon.png */; }; + 02084C8011E534E800199A4D /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7611E534E800199A4D /* Icon@2x.png */; }; + 02084C8211E534E800199A4D /* Stat.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7811E534E800199A4D /* Stat.png */; }; + 02084C8311E534E800199A4D /* XML.png in Resources */ = {isa = PBXBuildFile; fileRef = 02084C7911E534E800199A4D /* XML.png */; }; + 02084D1811E53ACB00199A4D /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 02084D1711E53ACB00199A4D /* iTunesArtwork */; }; + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28216C970DB411BC00E5133A /* StatsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28216C960DB411BC00E5133A /* StatsViewController.m */; }; + 3097D68B0E392CCC00159D5D /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3097D6870E392CCC00159D5D /* MainWindow.xib */; }; + 3097D68C0E392CCC00159D5D /* StatsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3097D6890E392CCC00159D5D /* StatsView.xib */; }; + 3097D6920E392ED500159D5D /* SongsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D6910E392ED500159D5D /* SongsViewController.m */; }; + 3097D6B40E392FAD00159D5D /* ParserChoiceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D6B30E392FAD00159D5D /* ParserChoiceViewController.m */; }; + 3097D6EF0E3939E700159D5D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3097D6EE0E3939E700159D5D /* CoreGraphics.framework */; }; + 3097D70A0E393EAE00159D5D /* iTunesRSSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D7090E393EAE00159D5D /* iTunesRSSParser.m */; }; + 3097D71B0E39427200159D5D /* Song.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D71A0E39427200159D5D /* Song.m */; }; + 3097D7260E39451800159D5D /* LibXMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D7230E39451800159D5D /* LibXMLParser.m */; }; + 3097D7270E39451800159D5D /* CocoaXMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D7250E39451800159D5D /* CocoaXMLParser.m */; }; + 3097D72A0E39487200159D5D /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3097D7290E39487200159D5D /* libxml2.dylib */; }; + 3097D7390E394B0600159D5D /* DetailController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3097D7380E394B0600159D5D /* DetailController.m */; }; + 309C4B890E844795007F2FBA /* Statistics.m in Sources */ = {isa = PBXBuildFile; fileRef = 309C4B880E844795007F2FBA /* Statistics.m */; }; + 30CB63DE0FBB5A1200E8B09E /* ParserChoiceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 30CB63DC0FBB5A1200E8B09E /* ParserChoiceView.xib */; }; + 30EC989A0E3A507B0042536C /* stats.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 30EC98990E3A507B0042536C /* stats.sqlite */; }; + 30EC98BF0E3A573E0042536C /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 30EC98BE0E3A573E0042536C /* libsqlite3.dylib */; }; + 30F20C520EC3618100F74FAC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30F20C500EC3618100F74FAC /* Localizable.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 02084C7011E534E800199A4D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 02084C7111E534E800199A4D /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 02084C7211E534E800199A4D /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = ""; }; + 02084C7311E534E800199A4D /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = ""; }; + 02084C7411E534E800199A4D /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = ""; }; + 02084C7511E534E800199A4D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 02084C7611E534E800199A4D /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + 02084C7811E534E800199A4D /* Stat.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Stat.png; sourceTree = ""; }; + 02084C7911E534E800199A4D /* XML.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = XML.png; sourceTree = ""; }; + 02084D1711E53ACB00199A4D /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* XMLPerformance.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XMLPerformance.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28216C950DB411BC00E5133A /* StatsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatsViewController.h; sourceTree = ""; }; + 28216C960DB411BC00E5133A /* StatsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatsViewController.m; sourceTree = ""; }; + 28A0AB4B0D9B1048005BE974 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 3013ACF00E5CD69000DFF042 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 3097D6880E392CCC00159D5D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 3097D68A0E392CCC00159D5D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/StatsView.xib; sourceTree = ""; }; + 3097D6900E392ED500159D5D /* SongsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongsViewController.h; sourceTree = ""; }; + 3097D6910E392ED500159D5D /* SongsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongsViewController.m; sourceTree = ""; }; + 3097D6B20E392FAD00159D5D /* ParserChoiceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserChoiceViewController.h; sourceTree = ""; }; + 3097D6B30E392FAD00159D5D /* ParserChoiceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ParserChoiceViewController.m; sourceTree = ""; }; + 3097D6EE0E3939E700159D5D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 3097D7080E393EAE00159D5D /* iTunesRSSParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTunesRSSParser.h; sourceTree = ""; }; + 3097D7090E393EAE00159D5D /* iTunesRSSParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTunesRSSParser.m; sourceTree = ""; }; + 3097D7190E39427200159D5D /* Song.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Song.h; sourceTree = ""; }; + 3097D71A0E39427200159D5D /* Song.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Song.m; sourceTree = ""; }; + 3097D7220E39451800159D5D /* LibXMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibXMLParser.h; sourceTree = ""; }; + 3097D7230E39451800159D5D /* LibXMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LibXMLParser.m; sourceTree = ""; }; + 3097D7240E39451800159D5D /* CocoaXMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CocoaXMLParser.h; sourceTree = ""; }; + 3097D7250E39451800159D5D /* CocoaXMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaXMLParser.m; sourceTree = ""; }; + 3097D7290E39487200159D5D /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; + 3097D7370E394B0600159D5D /* DetailController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailController.h; sourceTree = ""; }; + 3097D7380E394B0600159D5D /* DetailController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailController.m; sourceTree = ""; }; + 309C4B870E844795007F2FBA /* Statistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Statistics.h; sourceTree = ""; }; + 309C4B880E844795007F2FBA /* Statistics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Statistics.m; sourceTree = ""; }; + 30CB63DD0FBB5A1200E8B09E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ParserChoiceView.xib; sourceTree = ""; }; + 30EC98990E3A507B0042536C /* stats.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = stats.sqlite; sourceTree = ""; }; + 30EC98BE0E3A573E0042536C /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; + 30F20C510EC3618100F74FAC /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 3097D6EF0E3939E700159D5D /* CoreGraphics.framework in Frameworks */, + 3097D72A0E39487200159D5D /* libxml2.dylib in Frameworks */, + 30EC98BF0E3A573E0042536C /* libsqlite3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 02084C6F11E534E800199A4D /* Images */ = { + isa = PBXGroup; + children = ( + 02084C7011E534E800199A4D /* Default.png */, + 02084C7111E534E800199A4D /* Icon-72.png */, + 02084C7211E534E800199A4D /* Icon-Small-50.png */, + 02084C7311E534E800199A4D /* Icon-Small.png */, + 02084C7411E534E800199A4D /* Icon-Small@2x.png */, + 02084C7511E534E800199A4D /* Icon.png */, + 02084C7611E534E800199A4D /* Icon@2x.png */, + 02084C7811E534E800199A4D /* Stat.png */, + 02084C7911E534E800199A4D /* XML.png */, + 02084D1711E53ACB00199A4D /* iTunesArtwork */, + ); + path = Images; + sourceTree = ""; + }; + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + 3097D6B20E392FAD00159D5D /* ParserChoiceViewController.h */, + 3097D6B30E392FAD00159D5D /* ParserChoiceViewController.m */, + 3097D6900E392ED500159D5D /* SongsViewController.h */, + 3097D6910E392ED500159D5D /* SongsViewController.m */, + 3097D7370E394B0600159D5D /* DetailController.h */, + 3097D7380E394B0600159D5D /* DetailController.m */, + 3097D7190E39427200159D5D /* Song.h */, + 3097D71A0E39427200159D5D /* Song.m */, + 3097D7080E393EAE00159D5D /* iTunesRSSParser.h */, + 3097D7090E393EAE00159D5D /* iTunesRSSParser.m */, + 3097D7220E39451800159D5D /* LibXMLParser.h */, + 3097D7230E39451800159D5D /* LibXMLParser.m */, + 3097D7240E39451800159D5D /* CocoaXMLParser.h */, + 3097D7250E39451800159D5D /* CocoaXMLParser.m */, + 28216C950DB411BC00E5133A /* StatsViewController.h */, + 28216C960DB411BC00E5133A /* StatsViewController.m */, + 309C4B870E844795007F2FBA /* Statistics.h */, + 309C4B880E844795007F2FBA /* Statistics.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* XMLPerformance.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* XMLPerformance */ = { + isa = PBXGroup; + children = ( + 3013ACF00E5CD69000DFF042 /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = XMLPerformance; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AB4B0D9B1048005BE974 /* Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 02084C6F11E534E800199A4D /* Images */, + 30EC98990E3A507B0042536C /* stats.sqlite */, + 8D1107310486CEB800E47090 /* Info.plist */, + 3097D6870E392CCC00159D5D /* MainWindow.xib */, + 30CB63DC0FBB5A1200E8B09E /* ParserChoiceView.xib */, + 3097D6890E392CCC00159D5D /* StatsView.xib */, + 30F20C500EC3618100F74FAC /* Localizable.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 30EC98BE0E3A573E0042536C /* libsqlite3.dylib */, + 3097D7290E39487200159D5D /* libxml2.dylib */, + 3097D6EE0E3939E700159D5D /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* XMLPerformance */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "XMLPerformance" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = XMLPerformance; + productName = XMLPerformance; + productReference = 1D6058910D05DD3D006BFB54 /* XMLPerformance.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "XMLPerformance" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* XMLPerformance */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* XMLPerformance */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3097D68B0E392CCC00159D5D /* MainWindow.xib in Resources */, + 3097D68C0E392CCC00159D5D /* StatsView.xib in Resources */, + 30EC989A0E3A507B0042536C /* stats.sqlite in Resources */, + 30F20C520EC3618100F74FAC /* Localizable.strings in Resources */, + 30CB63DE0FBB5A1200E8B09E /* ParserChoiceView.xib in Resources */, + 02084C7A11E534E800199A4D /* Default.png in Resources */, + 02084C7B11E534E800199A4D /* Icon-72.png in Resources */, + 02084C7C11E534E800199A4D /* Icon-Small-50.png in Resources */, + 02084C7D11E534E800199A4D /* Icon-Small.png in Resources */, + 02084C7E11E534E800199A4D /* Icon-Small@2x.png in Resources */, + 02084C7F11E534E800199A4D /* Icon.png in Resources */, + 02084C8011E534E800199A4D /* Icon@2x.png in Resources */, + 02084C8211E534E800199A4D /* Stat.png in Resources */, + 02084C8311E534E800199A4D /* XML.png in Resources */, + 02084D1811E53ACB00199A4D /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 28216C970DB411BC00E5133A /* StatsViewController.m in Sources */, + 3097D6920E392ED500159D5D /* SongsViewController.m in Sources */, + 3097D6B40E392FAD00159D5D /* ParserChoiceViewController.m in Sources */, + 3097D70A0E393EAE00159D5D /* iTunesRSSParser.m in Sources */, + 3097D71B0E39427200159D5D /* Song.m in Sources */, + 3097D7260E39451800159D5D /* LibXMLParser.m in Sources */, + 3097D7270E39451800159D5D /* CocoaXMLParser.m in Sources */, + 3097D7390E394B0600159D5D /* DetailController.m in Sources */, + 309C4B890E844795007F2FBA /* Statistics.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 3097D6870E392CCC00159D5D /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 3097D6880E392CCC00159D5D /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; + 3097D6890E392CCC00159D5D /* StatsView.xib */ = { + isa = PBXVariantGroup; + children = ( + 3097D68A0E392CCC00159D5D /* en */, + ); + name = StatsView.xib; + sourceTree = ""; + }; + 30CB63DC0FBB5A1200E8B09E /* ParserChoiceView.xib */ = { + isa = PBXVariantGroup; + children = ( + 30CB63DD0FBB5A1200E8B09E /* en */, + ); + name = ParserChoiceView.xib; + sourceTree = ""; + }; + 30F20C500EC3618100F74FAC /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 30F20C510EC3618100F74FAC /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + HEADER_SEARCH_PATHS = $SDKROOT/usr/include/libxml2; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = XMLPerformance; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Prefix.pch; + HEADER_SEARCH_PATHS = $SDKROOT/usr/include/libxml2; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = XMLPerformance; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "XMLPerformance" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "XMLPerformance" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/XMLPerformance/en.lproj/Localizable.strings b/XMLPerformance/en.lproj/Localizable.strings new file mode 100644 index 0000000..cd9acd6 Binary files /dev/null and b/XMLPerformance/en.lproj/Localizable.strings differ diff --git a/XMLPerformance/en.lproj/MainWindow.xib b/XMLPerformance/en.lproj/MainWindow.xib new file mode 100644 index 0000000..abdf2eb --- /dev/null +++ b/XMLPerformance/en.lproj/MainWindow.xib @@ -0,0 +1,669 @@ + + + + 528 + 10A380 + 731 + 1025.2 + 427.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 58 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + YES + + + + + + + Stats + + NSImage + Stat.png + + + + + StatsView + + + YES + + + Parse + + NSImage + XML.png + + + + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + Parsers + + + ParserChoiceView + + + + + + + + 266 + {{129, 330}, {163, 49}} + + 3 + MCAwAA + + NO + + + + + + YES + + + window + + + + 9 + + + + delegate + + + + 99 + + + + tabBarController + + + + 113 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + -1 + + + File's Owner + + + 3 + + + + + 106 + + + YES + + + + + + + + 107 + + + + + 109 + + + YES + + + + + + 110 + + + + + -2 + + + + + 115 + + + YES + + + + + + + + 116 + + + YES + + + + + + 117 + + + + + 118 + + + YES + + + + + 119 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 106.IBEditorWindowLastContentRect + 106.IBPluginDependency + 107.IBPluginDependency + 109.CustomClassName + 109.IBPluginDependency + 110.IBPluginDependency + 115.IBPluginDependency + 116.CustomClassName + 116.IBPluginDependency + 117.IBPluginDependency + 118.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + {{828, 195}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + StatsViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ParserChoiceViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + YES + + + {{229, 373}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 139 + + + + YES + + AppDelegate + NSObject + + YES + + YES + tabBarController + window + + + YES + UITabBarController + UIWindow + + + + IBProjectSource + Classes/AppDelegate.h + + + + AppDelegate + NSObject + + IBUserSource + + + + + ParserChoiceViewController + UIViewController + + startParser + id + + + startButton + UIButton + + + IBProjectSource + Classes/ParserChoiceViewController.h + + + + StatsViewController + UITableViewController + + resetStatistics + id + + + IBProjectSource + Classes/StatsViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITabBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITabBar.h + + + + UITabBarController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UITabBarItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UITabBarItem.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../XMLPerformance.xcodeproj + 3 + 3.0 + + diff --git a/XMLPerformance/en.lproj/ParserChoiceView.xib b/XMLPerformance/en.lproj/ParserChoiceView.xib new file mode 100644 index 0000000..7247361 --- /dev/null +++ b/XMLPerformance/en.lproj/ParserChoiceView.xib @@ -0,0 +1,259 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 274 + {320, 201} + + NO + YES + NO + NO + 1 + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + + 292 + {{124, 209}, {72, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + Start + Start + Start + Start + + 1 + MSAxIDEAA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MAA + + + + {320, 367} + + + 3 + MQA + + 2 + + + NO + + + + + YES + + + view + + + + 6 + + + + dataSource + + + + 7 + + + + delegate + + + + 8 + + + + startButton + + + + 9 + + + + startParser + + + 7 + + 10 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 3 + + + YES + + + + + + + 4 + + + + + 5 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 3.IBEditorWindowLastContentRect + 3.IBPluginDependency + 4.IBPluginDependency + 5.IBPluginDependency + + + YES + ParserChoiceViewController + UIResponder + {{14, 778}, {320, 367}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 10 + + + + YES + + ParserChoiceViewController + UIViewController + + startParser + id + + + startButton + UIButton + + + IBProjectSource + Classes/ParserChoiceViewController.h + + + + + 0 + ../XMLPerformance.xcodeproj + 3 + 3.0 + + diff --git a/XMLPerformance/en.lproj/StatsView.xib b/XMLPerformance/en.lproj/StatsView.xib new file mode 100644 index 0000000..9aaad1a --- /dev/null +++ b/XMLPerformance/en.lproj/StatsView.xib @@ -0,0 +1,354 @@ + + + + 768 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + + YES + + + 274 + {320, 390} + + NO + YES + NO + NO + 1 + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + + 268 + {{92, 398}, {136, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + Reset Statistics + Reset Statistics + Reset Statistics + Reset Statistics + + 1 + MSAxIDEAA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + {320, 460} + + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADgEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAACBgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAYYAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAIAAAFTAAMAAAAEAAACDodzAAcAAA/IAAACFgAAAAAACAAIAAgACAABAAEAAQABAAAPyGFw +cGwCAAAAbW50clJHQiBYWVogB9kAAgAXAA8AGAALYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAPbWAAEAAAAA0y1hcHBsaphmZhHvpWo5EzFmkmxXQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA +AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAYSbmRpbgAA +B+wAAAY+ZGVzYwAADiwAAABfZHNjbQAADowAAADwbW1vZAAAD3wAAAAoY3BydAAAD6QAAAAkWFlaIAAA +AAAAAHWbAAA+zQAAAhxYWVogAAAAAAAAWoMAAKx/AAAULFhZWiAAAAAAAAAmuAAAFM4AALzdWFlaIAAA +AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 +cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD +AQAAAgAAAUwCNgMWBCkFagbECDsJxQtdDQgOrhBgEhETvhViFw0YpRo1G7MdJh5lH5ogzSIAIzokeSWz +Ju8oMSlvKqsr5y0jLlovjTC6MegzDzQzNVY2bjeTOL857jsYPEM9Zz6HP6VAv0HWQutD+kUIRhBHFUga +SR1KHEsdTBhNF04XTyhQP1FSUmRTd1SHVZRWoVesWLdZwVrMW9dc413vXv1gDWEdYi1jQGRSZVVmUGdM +aEVpQGo/azxsOG03bjdvOHA7cT5yRnNQdFp1ZnZ4d4l4mXmoeq57qnyifZ1+mH+cgJuBnoKig6eEq4Wu +hq2HrYiviamKpYucjJCNg45yj2aQa5FuknOTdpR3lXSWbpdpmF+ZU5pGmzicJ50Tnf6e6Z/ToLmhn6KI +o3OkcKVvpm6nbqhrqWeqYqtbrFOtTK5Frz6wN7EwsimzJLQftRy2G7cauBG4+LnPuqC7dLxHvRm97L6/ +v5TAbMFEwh3C+cPWxLXFlMZ2x1nIP8knyg3K68u/zJDNY845zxHP6tDG0Z/SfdNb1DjVFdXw1srXo9h6 +2VDaJNr128Pcl9113lbfN+AW4PTh0OKo43/kVeUq5fvmyueX6GPpLun46sPri+xU7Rzt5e7C76HwgPFd +8jnzFvPw9Mf1nvZ090n4Hfju+cL6lvto/Dz9Ev3n/rz/Z///AAABHAHfAq4DrwTaBiEHjQkICpwMOA3n +D5QRQRLtFJYWNRfKGU4awRwlHVwehx+vIN0iDiNCJHAloibXKAwpPypvK54szC30LxcwPjFaMnMzijSe +Nbc21zf6ORc6NztQPGU9eT6HP5RAn0GmQqlDqUSnRaNGn0eZSJJJiEqAS3pMhk2WTqNPr1C7UcRSy1PQ +VNVV2FbbV95Y4FnkWudb7Fz0XfxfA2ANYRNiC2L6Y+hk1mXFZrZnp2iXaYlqfWtzbGltYG5cb1lwVnFW +cltzYHRjdWZ2YndReEF5Mnonex98GH0SfhB/D4ANgQqCBYMBg/yE9IXrht+H0Ii/iayKmougjJ+Noo6h +j6CQm5GSkouTfpRwlWGWUJc+mCqZE5n9muebzZyznZ2ehp+EoIKhgKJ/o3ukd6VxpmmnYKhYqU+qR6s+ +rDWtLa4lrx6wGLEUsg+zBbPstMW1mLZvt0W4G7jxuci6ort+vFu9Or4bvv+/48DIwbTCnMOIxHjFZsZK +xybIAMjZybrKmst8zGDNRM4rzxPP+tDj0cjSrtOS1HXVV9Y21xTX79jM2cDastum3Jbdht5031/gSOEx +4hji++Pe5L3lneZ751noN+kU6e/qzeuu7KHtnO6W747whvF98nLzZPRW9Uf2Nvck+BD4/vns+tj7xfy1 +/aX+lP9a//8AAACDAXgCegOiBOgGQwe4CT4KzwxlDf8PmRErEroUPxWuFyEYdxnCGv8cOh1oHpYfySD8 +IjAjXiSKJbcm4igKKTAqTStoLHwtiy6WL54woTGgMp4znDSdNZ82oDedOJk5kjqIO3s8bD1ZPkU/LUAT +QPVB10K6Q51EfkVcRj9HIEgNSP1J7ErbS8pMt02kTpBPelBlUU9SOlMkVBBU/VXsVt1XzVi+WbBanluD +XF1dOF4SXu5fzWCtYY9icmNYZEBlK2YYZwdn+mjuaeVq3mvYbNJtzG7Eb7pwrnGlcp5zm3SZdZt2nnei +eKd5qXqqe6p8q32ofqR/nICPgYOCcYNihFuFUYZJhz6IMYkhig+K+ovjjMqNro6Qj3CQTJEokgKS3JOz +lIqVY5ZBlyWYDpj4meGayZuvnJadeZ5dn0GgJaEJoe6i06O6pKCliaZzp16oSakvqg6q5au2rI2tYa42 +rwyv5LC+sZyyerNctEG1J7YPtvm357jUucO6uLuqvI69ab5Bvxu/9sDTwbHCkcNwxFHFMcYSxvHH0Mir +yYXKXcs0zAjM282qzoPPZ9BQ0TrSJNMN0/TU2NW61p3Xfthc2TnaFdrw28ncod163lLfKeAB4NnhyuK9 +463kluV/5mjnVOhD6TfqNOs+7Fftge688A/xlfNC9Sj3a/of/XH//wAAbmRpbgAAAAAAAAY2AACjZwAA +WDEAAEyRAACdDgAAJkwAABMcAABQDQAAVDkAAi4UAAIMzAABzMwAAwEAAAIAAAABAAgAFQAjADEAQQBR +AGIAcwCGAJkArQDBANcA7QEEARwBNQFPAWoBhwGkAcIB4gIEAicCTAJ0Ap0CzgMCAzkDcQOrA+UEHwRd +BJsE2wUbBV0FoQXnBi4GdwbCBw8HYAeyCAYIXgi4CRMJdQnUCjMKkQrxC1ULuQwhDIwM+Q1pDd0OUg7L +D0gPxxBLENIRWxHnEncTCBOfFDQUyxVYFeYWeBcMF6EYORjVGXIaEhq1G1kb/xynHU8d+R6lH1Ef/SCr +IVsiCiK8I3skQSUIJdMmnidoKDYpBinVKqUrdixILRst6y68L48wYTExMgMy1zOtNIo1dDZkN1M4RDku +Oh87DTv8POw93j7TP81AyUHDQshDzETXRehG/EgWSSxKLks5TEFNT05fT3ZQklGuUtNT+1UnVlZXi1jH +WgRbQ1yLXdVfHGBiYY5iwGPxZSRmXWeXaNZqGWtdbKJt6m8ycH1xyXMVdGJ1r3b7eEd5l3r/fI5+LX/H +gWiDCoSthk6H7YmNiyqMxY5fj/uRkJMplLyWTZfxmbCbdp05nvWgs6JspCul4qeeqVyrIKzprriwi7Jm +tEm2ObgaueK7q71+v1HBLcMVxQHG8cjtyvHM/s8Q0SrTQ9Vm14rZsduk3ZbfjeGK44jljued6bDrx+3l +8AvyLfRT9n74ovrK/PT//wAAAAIADAAbACoAOgBLAFwAbgCBAJQAqAC9ANIA6AD/ARcBMAFKAWUBgQGe +Ab0B3QH/AiMCSQJyAp0CzwMFAz4DeAOzA+8ELARsBK0E7wUyBXcFvgYHBlIGngbtBz8HlAfpCEMIoAj+ +CWEJxAonCokK7QtVC70MKQyZDQoNgA34DnMO8Q9zD/kQghEOEZ0SLhLCE1sT9BSQFSIVsxZHFt4XdhgR +GLAZURn1GpsbRBvvHJsdSh35HqsfXCAOIMIheCItIukjtCSFJVkmLicDJ9ootCmOKmgrQywfLPwt1y6y +L5AwbDFGMiIzATPiNMw1xDa9N7U4rDmhOpg7jjyDPXo+cz9wQHBBb0J0Q35EikWdRrRH0EjvSfNLAUwL +TRxOLk9GUGVRg1KrU9RVA1Y0V2lYplnlWyNca121XvtgRGFxYqNj1mUJZkNnfmi9agFrR2yNbddvIXBu +cb1zDHRcdax2/HhNeaF7C3yYfjF/xYFfgvuEloYvh8WJW4rujH+ODo+gkSaStpQ+lcKXUJj3mqucY54N +n7mhZKMOpLamXagGqa+rX60SrsmwhLJGtA214LeuuVK6/byjvljACcHFw4nFTccXyOvKw8ykzoXQb9JY +1ETWOdgq2hLb0N2L30rhEOLV5J/mcOhG6h/r/e3e78jxrvOV9YT3b/lW+0P9MP//AAAABgAQAB0AKgA5 +AEkAWQBrAH0AkACkALkAzwDmAP4BFwEyAU4BawGKAawBzwHzAhsCRgJzAqQC1gMMA0QDfQO3A/MEMARw +BLIE9gU7BYMFzQYZBmkGuwcRB2oHxwgnCIoI8glcCckKNwqmCxcLjAwEDH8M/g2BDgcOkg8gD7MQShDm +EYQSJBLIE3EUGRTFFWgWDha2F2EYDhi/GXIaKRriG54cWx0bHdsenR9fICIg6CGuIngjTCQvJRQl/Cbj +J8oosimbKoIraixRLTcuHS8CL+cwzDGwMpYzfjRpNVk2TDdAODM5IzoVOwU79TzlPdc+zD/FQMBBu0K9 +Q8FEy0XcRu9ICkkkSjVLTUxkTYFOok/KUPZSKFNfVJtV31cmWHZZylsgXH9d4F8/YJdh5mMyZIFl1Gcr +aIVp5WtGbKpuD291cN1yRHOudRZ2fXfleVB6yHxUffF/h4Ekgr+EWoXzh4aJGYqnjDONvY9HkMqSUZPV +lVOW1ph1mimb4p2Wn0mg/KKtpGGmFKfKqYOrQa0IrtSwprKAtGG2Tbghud27lb1RvxDA1MKgxHLGRMgf +ygHL6c3Uz8fRvdO01bDXrtmt23fdQN8U4Pbi2uS75pjocOo46+7tj+8c8Jbx//NW9If1qfa697T4pfl5 ++kb6/vun/FD82/1i/en+iP9E//8AAGRlc2MAAAAAAAAABWlNYWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1s +dWMAAAAAAAAAEgAAAAxuYk5PAAAACAAAAOhwdFBUAAAACAAAAOhzdlNFAAAACAAAAOhmaUZJAAAACAAA +AOhkYURLAAAACAAAAOh6aENOAAAACAAAAOhmckZSAAAACAAAAOhqYUpQAAAACAAAAOhlblVTAAAACAAA +AOhwbFBMAAAACAAAAOhwdEJSAAAACAAAAOhlc0VTAAAACAAAAOh6aFRXAAAACAAAAOhydVJVAAAACAAA +AOhrb0tSAAAACAAAAOhkZURFAAAACAAAAOhubE5MAAAACAAAAOhpdElUAAAACAAAAOgAaQBNAGEAY21t +b2QAAAAAAAAGEAAAnGwAAAAAwbTFAAAAAAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBs +ZSwgSW5jLiwgMjAwOQA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + + + + + YES + + + view + + + + 3 + + + + dataSource + + + + 6 + + + + delegate + + + + 7 + + + + tableView + + + + 8 + + + + resetStatistics + + + 7 + + 10 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 5 + + + + + 9 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 5.IBPluginDependency + 9.IBPluginDependency + + + YES + StatsViewController + UIResponder + {{695, 392}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 10 + + + + YES + + StatsViewController + UIViewController + + resetStatistics + id + + + tableView + UITableView + + + IBProjectSource + Classes/StatsViewController.h + + + + StatsViewController + UIViewController + + IBUserSource + + + + + + 0 + ../XMLPerformance.xcodeproj + 3 + + diff --git a/XMLPerformance/main.m b/XMLPerformance/main.m new file mode 100644 index 0000000..6338165 --- /dev/null +++ b/XMLPerformance/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: Launches the application. + Version: 1.3 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} + diff --git a/XMLPerformance/stats.sqlite b/XMLPerformance/stats.sqlite new file mode 100644 index 0000000..7290f93 Binary files /dev/null and b/XMLPerformance/stats.sqlite differ diff --git a/aurioTouch.zip b/aurioTouch.zip new file mode 100644 index 0000000..4c926ba Binary files /dev/null and b/aurioTouch.zip differ diff --git a/aurioTouch/Classes/FFTBufferManager.cpp b/aurioTouch/Classes/FFTBufferManager.cpp new file mode 100644 index 0000000..318194d --- /dev/null +++ b/aurioTouch/Classes/FFTBufferManager.cpp @@ -0,0 +1,102 @@ +/* + + File: FFTBufferManager.cpp +Abstract: This class manages buffering and computation for FFT analysis on input audio data. The methods provided are used to grab the audio, buffer it, and perform the FFT when sufficient data is available + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include "FFTBufferManager.h" + +#define min(x,y) (x < y) ? x : y + +FFTBufferManager::FFTBufferManager(UInt32 inNumberFrames) : + mNeedsAudioData(0), + mHasAudioData(0), + mNumberFrames(inNumberFrames), + mAudioBufferSize(inNumberFrames * sizeof(int32_t)), + mAudioBufferCurrentIndex(0) + +{ + mAudioBuffer = (int32_t*)malloc(mAudioBufferSize); + mSpectrumAnalysis = SpectrumAnalysisCreate(mNumberFrames); + OSAtomicIncrement32Barrier(&mNeedsAudioData); +} + +FFTBufferManager::~FFTBufferManager() +{ + free(mAudioBuffer); + SpectrumAnalysisDestroy(mSpectrumAnalysis); +} + +void FFTBufferManager::GrabAudioData(AudioBufferList *inBL) +{ + if (mAudioBufferSize < inBL->mBuffers[0].mDataByteSize) return; + + UInt32 bytesToCopy = min(inBL->mBuffers[0].mDataByteSize, mAudioBufferSize - mAudioBufferCurrentIndex); + memcpy(mAudioBuffer+mAudioBufferCurrentIndex, inBL->mBuffers[0].mData, bytesToCopy); + + mAudioBufferCurrentIndex += bytesToCopy / sizeof(int32_t); + if (mAudioBufferCurrentIndex >= mAudioBufferSize / sizeof(int32_t)) + { + OSAtomicIncrement32Barrier(&mHasAudioData); + OSAtomicDecrement32Barrier(&mNeedsAudioData); + } +} + +Boolean FFTBufferManager::ComputeFFT(int32_t *outFFTData) +{ + if (HasNewAudioData()) + { + SpectrumAnalysisProcess(mSpectrumAnalysis, mAudioBuffer, outFFTData, true); + OSAtomicDecrement32Barrier(&mHasAudioData); + OSAtomicIncrement32Barrier(&mNeedsAudioData); + mAudioBufferCurrentIndex = 0; + return true; + } + else if (mNeedsAudioData == 0) + OSAtomicIncrement32Barrier(&mNeedsAudioData); + + return false; +} diff --git a/aurioTouch/Classes/FFTBufferManager.h b/aurioTouch/Classes/FFTBufferManager.h new file mode 100644 index 0000000..8f4d723 --- /dev/null +++ b/aurioTouch/Classes/FFTBufferManager.h @@ -0,0 +1,79 @@ +/* + + File: FFTBufferManager.h +Abstract: This class manages buffering and computation for FFT analysis on input audio data. The methods provided are used to grab the audio, buffer it, and perform the FFT when sufficient data is available + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include +#include + +#include "SpectrumAnalysis.h" + +class FFTBufferManager +{ +public: + FFTBufferManager(UInt32 inNumberFrames); + ~FFTBufferManager(); + + volatile int32_t HasNewAudioData() { return mHasAudioData; } + volatile int32_t NeedsNewAudioData() { return mNeedsAudioData; } + + UInt32 GetNumberFrames() { return mNumberFrames; } + + void GrabAudioData(AudioBufferList *inBL); + Boolean ComputeFFT(int32_t *outFFTData); + +private: + volatile int32_t mNeedsAudioData; + volatile int32_t mHasAudioData; + + H_SPECTRUM_ANALYSIS mSpectrumAnalysis; + + int32_t* mAudioBuffer; + UInt32 mNumberFrames; + UInt32 mAudioBufferSize; + int32_t mAudioBufferCurrentIndex; +}; \ No newline at end of file diff --git a/aurioTouch/Classes/aurioTouchAppDelegate.h b/aurioTouch/Classes/aurioTouchAppDelegate.h new file mode 100755 index 0000000..2a7aa79 --- /dev/null +++ b/aurioTouch/Classes/aurioTouchAppDelegate.h @@ -0,0 +1,144 @@ +/* + + File: aurioTouchAppDelegate.h +Abstract: App delegate + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import +#import +#import +#include +#include + +#import "EAGLView.h" +#import "FFTBufferManager.h" +#import "aurio_helper.h" +#import "CAStreamBasicDescription.h" + +#define SPECTRUM_BAR_WIDTH 4 + +#ifndef CLAMP +#define CLAMP(min,x,max) (x < min ? min : (x > max ? max : x)) +#endif + +typedef enum aurioTouchDisplayMode { + aurioTouchDisplayModeOscilloscopeWaveform, + aurioTouchDisplayModeOscilloscopeFFT, + aurioTouchDisplayModeSpectrum +} aurioTouchDisplayMode; + +typedef struct SpectrumLinkedTexture { + GLuint texName; + struct SpectrumLinkedTexture *nextTex; +} SpectrumLinkedTexture; + +inline double linearInterp(double valA, double valB, double fract) +{ + return valA + ((valB - valA) * fract); +} + +@interface aurioTouchAppDelegate : NSObject { + IBOutlet UIWindow* window; + IBOutlet EAGLView* view; + + UIImageView* sampleSizeOverlay; + UILabel* sampleSizeText; + + SInt32* fftData; + NSUInteger fftLength; + BOOL hasNewFFTData; + + AudioUnit rioUnit; + BOOL unitIsRunning; + BOOL unitHasBeenCreated; + + BOOL initted_oscilloscope, initted_spectrum; + UInt32* texBitBuffer; + CGRect spectrumRect; + + GLuint bgTexture; + GLuint muteOffTexture, muteOnTexture; + GLuint fftOffTexture, fftOnTexture; + GLuint sonoTexture; + + aurioTouchDisplayMode displayMode; + + BOOL mute; + + SpectrumLinkedTexture* firstTex; + FFTBufferManager* fftBufferManager; + DCRejectionFilter* dcFilter; + CAStreamBasicDescription thruFormat; + Float64 hwSampleRate; + + UIEvent* pinchEvent; + CGFloat lastPinchDist; + + AURenderCallbackStruct inputProc; + + SystemSoundID buttonPressSound; + + int32_t* l_fftData; + + GLfloat* oscilLine; + BOOL resetOscilLine; +} + +@property (nonatomic, retain) UIWindow* window; +@property (nonatomic, retain) EAGLView* view; + +@property (assign) aurioTouchDisplayMode displayMode; +@property FFTBufferManager* fftBufferManager; + +@property (nonatomic, assign) AudioUnit rioUnit; +@property (nonatomic, assign) BOOL unitIsRunning; +@property (nonatomic, assign) BOOL unitHasBeenCreated; +@property (nonatomic, assign) BOOL mute; +@property (nonatomic, assign) AURenderCallbackStruct inputProc; + +@end + diff --git a/aurioTouch/Classes/aurioTouchAppDelegate.mm b/aurioTouch/Classes/aurioTouchAppDelegate.mm new file mode 100755 index 0000000..0cd2fb8 --- /dev/null +++ b/aurioTouch/Classes/aurioTouchAppDelegate.mm @@ -0,0 +1,1052 @@ +/* + + File: aurioTouchAppDelegate.mm +Abstract: n/a + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "aurioTouchAppDelegate.h" +#import "AudioUnit/AudioUnit.h" +#import "CAXException.h" + +@implementation aurioTouchAppDelegate + +// value, a, r, g, b +GLfloat colorLevels[] = { +0., 1., 0., 0., 0., +.333, 1., .7, 0., 0., +.667, 1., 0., 0., 1., +1., 1., 0., 1., 1., +}; + +@synthesize window; +@synthesize view; + +@synthesize rioUnit; +@synthesize unitIsRunning; +@synthesize unitHasBeenCreated; +@synthesize displayMode; +@synthesize fftBufferManager; +@synthesize mute; +@synthesize inputProc; + +#pragma mark- + +CGPathRef CreateRoundedRectPath(CGRect RECT, CGFloat cornerRadius) +{ + CGMutablePathRef path; + path = CGPathCreateMutable(); + + double maxRad = MAX(CGRectGetHeight(RECT) / 2., CGRectGetWidth(RECT) / 2.); + + if (cornerRadius > maxRad) cornerRadius = maxRad; + + CGPoint bl, tl, tr, br; + + bl = tl = tr = br = RECT.origin; + tl.y += RECT.size.height; + tr.y += RECT.size.height; + tr.x += RECT.size.width; + br.x += RECT.size.width; + + CGPathMoveToPoint(path, NULL, bl.x + cornerRadius, bl.y); + CGPathAddArcToPoint(path, NULL, bl.x, bl.y, bl.x, bl.y + cornerRadius, cornerRadius); + CGPathAddLineToPoint(path, NULL, tl.x, tl.y - cornerRadius); + CGPathAddArcToPoint(path, NULL, tl.x, tl.y, tl.x + cornerRadius, tl.y, cornerRadius); + CGPathAddLineToPoint(path, NULL, tr.x - cornerRadius, tr.y); + CGPathAddArcToPoint(path, NULL, tr.x, tr.y, tr.x, tr.y - cornerRadius, cornerRadius); + CGPathAddLineToPoint(path, NULL, br.x, br.y + cornerRadius); + CGPathAddArcToPoint(path, NULL, br.x, br.y, br.x - cornerRadius, br.y, cornerRadius); + + CGPathCloseSubpath(path); + + CGPathRef ret; + ret = CGPathCreateCopy(path); + CGPathRelease(path); + return ret; +} + +void cycleOscilloscopeLines() +{ + // Cycle the lines in our draw buffer so that they age and fade. The oldest line is discarded. + int drawBuffer_i; + for (drawBuffer_i=(kNumDrawBuffers - 2); drawBuffer_i>=0; drawBuffer_i--) + memmove(drawBuffers[drawBuffer_i + 1], drawBuffers[drawBuffer_i], drawBufferLen); +} + +#pragma mark -Audio Session Interruption Listener + +void rioInterruptionListener(void *inClientData, UInt32 inInterruption) +{ + printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + aurioTouchAppDelegate *THIS = (aurioTouchAppDelegate*)inClientData; + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active"); + XThrowIfError(AudioOutputUnitStart(THIS->rioUnit), "couldn't start unit"); + } + + if (inInterruption == kAudioSessionBeginInterruption) { + XThrowIfError(AudioOutputUnitStop(THIS->rioUnit), "couldn't stop unit"); + } +} + +#pragma mark -Audio Session Property Listener + +void propListener( void * inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void * inData) +{ + aurioTouchAppDelegate *THIS = (aurioTouchAppDelegate*)inClientData; + if (inID == kAudioSessionProperty_AudioRouteChange) + { + try { + UInt32 isAudioInputAvailable; + UInt32 size = sizeof(isAudioInputAvailable); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &isAudioInputAvailable), "couldn't get AudioSession AudioInputAvailable property value"); + + if(THIS->unitIsRunning && !isAudioInputAvailable) + { + XThrowIfError(AudioOutputUnitStop(THIS->rioUnit), "couldn't stop unit"); + THIS->unitIsRunning = false; + } + + else if(!THIS->unitIsRunning && isAudioInputAvailable) + { + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active\n"); + + if (!THIS->unitHasBeenCreated) // the rio unit is being created for the first time + { + XThrowIfError(SetupRemoteIO(THIS->rioUnit, THIS->inputProc, THIS->thruFormat), "couldn't setup remote i/o unit"); + THIS->unitHasBeenCreated = true; + + THIS->dcFilter = new DCRejectionFilter[THIS->thruFormat.NumberChannels()]; + + UInt32 maxFPS; + size = sizeof(maxFPS); + XThrowIfError(AudioUnitGetProperty(THIS->rioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &size), "couldn't get the remote I/O unit's max frames per slice"); + + THIS->fftBufferManager = new FFTBufferManager(maxFPS); + THIS->l_fftData = new int32_t[maxFPS/2]; + + THIS->oscilLine = (GLfloat*)malloc(drawBufferLen * 2 * sizeof(GLfloat)); + } + + XThrowIfError(AudioOutputUnitStart(THIS->rioUnit), "couldn't start unit"); + THIS->unitIsRunning = true; + } + + // we need to rescale the sonogram view's color thresholds for different input + CFStringRef newRoute; + size = sizeof(CFStringRef); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute), "couldn't get new audio route"); + if (newRoute) + { + CFShow(newRoute); + if (CFStringCompare(newRoute, CFSTR("Headset"), NULL) == kCFCompareEqualTo) // headset plugged in + { + colorLevels[0] = .3; + colorLevels[5] = .5; + } + else if (CFStringCompare(newRoute, CFSTR("Receiver"), NULL) == kCFCompareEqualTo) // headset plugged in + { + colorLevels[0] = 0; + colorLevels[5] = .333; + colorLevels[10] = .667; + colorLevels[15] = 1.0; + + } + else + { + colorLevels[0] = 0; + colorLevels[5] = .333; + colorLevels[10] = .667; + colorLevels[15] = 1.0; + + } + } + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + + } +} + +#pragma mark -RIO Render Callback + +static OSStatus PerformThru( + void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData) +{ + aurioTouchAppDelegate *THIS = (aurioTouchAppDelegate *)inRefCon; + OSStatus err = AudioUnitRender(THIS->rioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData); + if (err) { printf("PerformThru: error %d\n", (int)err); return err; } + + // Remove DC component + for(UInt32 i = 0; i < ioData->mNumberBuffers; ++i) + THIS->dcFilter[i].InplaceFilter((SInt32*)(ioData->mBuffers[i].mData), inNumberFrames, 1); + + if (THIS->displayMode == aurioTouchDisplayModeOscilloscopeWaveform) + { + // The draw buffer is used to hold a copy of the most recent PCM data to be drawn on the oscilloscope + if (drawBufferLen != drawBufferLen_alloced) + { + int drawBuffer_i; + + // Allocate our draw buffer if needed + if (drawBufferLen_alloced == 0) + for (drawBuffer_i=0; drawBuffer_imBuffers[0].mData); + for (i=0; i= drawBufferLen) + { + cycleOscilloscopeLines(); + drawBufferIdx = -i; + } + drawBuffers[0][i + drawBufferIdx] = data_ptr[2]; + data_ptr += 4; + } + drawBufferIdx += inNumberFrames; + } + + else if ((THIS->displayMode == aurioTouchDisplayModeSpectrum) || (THIS->displayMode == aurioTouchDisplayModeOscilloscopeFFT)) + { + if (THIS->fftBufferManager == NULL) return noErr; + + if (THIS->fftBufferManager->NeedsNewAudioData()) + { + THIS->fftBufferManager->GrabAudioData(ioData); + } + + } + if (THIS->mute == YES) { SilenceData(ioData); } + + return err; +} + +#pragma mark- + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // Turn off the idle timer, since this app doesn't rely on constant touch input + application.idleTimerDisabled = YES; + + // mute should be on at launch + self.mute = YES; + displayMode = aurioTouchDisplayModeOscilloscopeWaveform; + + // Initialize our remote i/o unit + + inputProc.inputProc = PerformThru; + inputProc.inputProcRefCon = self; + + CFURLRef url = NULL; + try { + url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFStringRef([[NSBundle mainBundle] pathForResource:@"button_press" ofType:@"caf"]), kCFURLPOSIXPathStyle, false); + XThrowIfError(AudioServicesCreateSystemSoundID(url, &buttonPressSound), "couldn't create button tap alert sound"); + CFRelease(url); + + // Initialize and configure the audio session + XThrowIfError(AudioSessionInitialize(NULL, NULL, rioInterruptionListener, self), "couldn't initialize audio session"); + + UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory), "couldn't set audio category"); + XThrowIfError(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener"); + + Float32 preferredBufferSize = .005; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize), "couldn't set i/o buffer duration"); + + UInt32 size = sizeof(hwSampleRate); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &hwSampleRate), "couldn't get hw sample rate"); + + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active\n"); + + XThrowIfError(SetupRemoteIO(rioUnit, inputProc, thruFormat), "couldn't setup remote i/o unit"); + unitHasBeenCreated = true; + + dcFilter = new DCRejectionFilter[thruFormat.NumberChannels()]; + + UInt32 maxFPS; + size = sizeof(maxFPS); + XThrowIfError(AudioUnitGetProperty(rioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &size), "couldn't get the remote I/O unit's max frames per slice"); + + fftBufferManager = new FFTBufferManager(maxFPS); + l_fftData = new int32_t[maxFPS/2]; + + oscilLine = (GLfloat*)malloc(drawBufferLen * 2 * sizeof(GLfloat)); + + XThrowIfError(AudioOutputUnitStart(rioUnit), "couldn't start remote i/o unit"); + + size = sizeof(thruFormat); + XThrowIfError(AudioUnitGetProperty(rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &thruFormat, &size), "couldn't get the remote I/O unit's output client format"); + + unitIsRunning = 1; + } + catch (CAXException &e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + unitIsRunning = 0; + if (dcFilter) delete[] dcFilter; + if (url) CFRelease(url); + } + catch (...) { + fprintf(stderr, "An unknown error occurred\n"); + unitIsRunning = 0; + if (dcFilter) delete[] dcFilter; + if (url) CFRelease(url); + } + + // Set ourself as the delegate for the EAGLView so that we get drawing and touch events + view.delegate = self; + + // Enable multi touch so we can handle pinch and zoom in the oscilloscope + view.multipleTouchEnabled = YES; + + // Set up our overlay view that pops up when we are pinching/zooming the oscilloscope + UIImage *img_ui = nil; + { + // Draw the rounded rect for the bg path using this convenience function + CGPathRef bgPath = CreateRoundedRectPath(CGRectMake(0, 0, 110, 234), 15.); + + CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); + // Create the bitmap context into which we will draw + CGContextRef cxt = CGBitmapContextCreate(NULL, 110, 234, 8, 4*110, cs, kCGImageAlphaPremultipliedFirst); + CGContextSetFillColorSpace(cxt, cs); + CGFloat fillClr[] = {0., 0., 0., 0.7}; + CGContextSetFillColor(cxt, fillClr); + // Add the rounded rect to the context... + CGContextAddPath(cxt, bgPath); + // ... and fill it. + CGContextFillPath(cxt); + + // Make a CGImage out of the context + CGImageRef img_cg = CGBitmapContextCreateImage(cxt); + // Make a UIImage out of the CGImage + img_ui = [UIImage imageWithCGImage:img_cg]; + + // Clean up + CGImageRelease(img_cg); + CGColorSpaceRelease(cs); + CGContextRelease(cxt); + CGPathRelease(bgPath); + } + + // Create the image view to hold the background rounded rect which we just drew + sampleSizeOverlay = [[UIImageView alloc] initWithImage:img_ui]; + sampleSizeOverlay.frame = CGRectMake(190, 124, 110, 234); + + // Create the text view which shows the size of our oscilloscope window as we pinch/zoom + sampleSizeText = [[UILabel alloc] initWithFrame:CGRectMake(-62, 0, 234, 234)]; + sampleSizeText.textAlignment = UITextAlignmentCenter; + sampleSizeText.textColor = [UIColor whiteColor]; + sampleSizeText.text = @"0000 ms"; + sampleSizeText.font = [UIFont boldSystemFontOfSize:36.]; + // Rotate the text view since we want the text to draw top to bottom (when the device is oriented vertically) + sampleSizeText.transform = CGAffineTransformMakeRotation(M_PI_2); + sampleSizeText.backgroundColor = [UIColor clearColor]; + + // Add the text view as a subview of the overlay BG + [sampleSizeOverlay addSubview:sampleSizeText]; + // Text view was retained by the above line, so we can release it now + [sampleSizeText release]; + + // We don't add sampleSizeOverlay to our main view yet. We just hang on to it for now, and add it when we + // need to display it, i.e. when a user starts a pinch/zoom. + + // Set up the view to refresh at 20 hz + [view setAnimationInterval:1./20.]; + [view startAnimation]; +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + //start animation now that we're in the foreground + view.applicationResignedActive = NO; + [view startAnimation]; + AudioSessionSetActive(true); +} + +- (void)applicationWillResignActive:(UIApplication *)application { + //stop animation before going into background + view.applicationResignedActive = YES; + [view stopAnimation]; +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { +} + + +- (void)dealloc +{ + delete[] dcFilter; + delete fftBufferManager; + + [view release]; + [window release]; + + free(oscilLine); + + [super dealloc]; +} + + +- (void)setFFTData:(int32_t *)FFTDATA length:(NSUInteger)LENGTH +{ + if (LENGTH != fftLength) + { + fftLength = LENGTH; + fftData = (SInt32 *)(realloc(fftData, LENGTH * sizeof(SInt32))); + } + memmove(fftData, FFTDATA, fftLength * sizeof(Float32)); + hasNewFFTData = YES; +} + + +- (void)createGLTexture:(GLuint *)texName fromCGImage:(CGImageRef)img +{ + GLubyte *spriteData = NULL; + CGContextRef spriteContext; + GLuint imgW, imgH, texW, texH; + + imgW = CGImageGetWidth(img); + imgH = CGImageGetHeight(img); + + // Find smallest possible powers of 2 for our texture dimensions + for (texW = 1; texW < imgW; texW *= 2) ; + for (texH = 1; texH < imgH; texH *= 2) ; + + // Allocated memory needed for the bitmap context + spriteData = (GLubyte *) calloc(texH, texW * 4); + // Uses the bitmatp creation function provided by the Core Graphics framework. + spriteContext = CGBitmapContextCreate(spriteData, texW, texH, 8, texW * 4, CGImageGetColorSpace(img), kCGImageAlphaPremultipliedLast); + + // Translate and scale the context to draw the image upside-down (conflict in flipped-ness between GL textures and CG contexts) + CGContextTranslateCTM(spriteContext, 0., texH); + CGContextScaleCTM(spriteContext, 1., -1.); + + // After you create the context, you can draw the sprite image to the context. + CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, imgW, imgH), img); + // You don't need the context at this point, so you need to release it to avoid memory leaks. + CGContextRelease(spriteContext); + + // Use OpenGL ES to generate a name for the texture. + glGenTextures(1, texName); + // Bind the texture name. + glBindTexture(GL_TEXTURE_2D, *texName); + // Speidfy a 2D texture image, provideing the a pointer to the image data in memory + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texW, texH, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); + // Set the texture parameters to use a minifying filter and a linear filer (weighted average) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Enable use of the texture + glEnable(GL_TEXTURE_2D); + // Set a blending function to use + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + // Enable blending + glEnable(GL_BLEND); + + free(spriteData); +} + + +- (void)setupViewForOscilloscope +{ + CGImageRef img; + + // Load our GL textures + + img = [UIImage imageNamed:@"oscilloscope.png"].CGImage; + [self createGLTexture:&bgTexture fromCGImage:img]; + + img = [UIImage imageNamed:@"fft_off.png"].CGImage; + [self createGLTexture:&fftOffTexture fromCGImage:img]; + + img = [UIImage imageNamed:@"fft_on.png"].CGImage; + [self createGLTexture:&fftOnTexture fromCGImage:img]; + + img = [UIImage imageNamed:@"mute_off.png"].CGImage; + [self createGLTexture:&muteOffTexture fromCGImage:img]; + + img = [UIImage imageNamed:@"mute_on.png"].CGImage; + [self createGLTexture:&muteOnTexture fromCGImage:img]; + + img = [UIImage imageNamed:@"sonogram.png"].CGImage; + [self createGLTexture:&sonoTexture fromCGImage:img]; + + initted_oscilloscope = YES; +} + + +- (void)clearTextures +{ + bzero(texBitBuffer, sizeof(UInt32) * 512); + SpectrumLinkedTexture *curTex; + + for (curTex = firstTex; curTex; curTex = curTex->nextTex) + { + glBindTexture(GL_TEXTURE_2D, curTex->texName); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, texBitBuffer); + } +} + + +- (void)setupViewForSpectrum +{ + glClearColor(0., 0., 0., 0.); + + spectrumRect = CGRectMake(10., 10., 460., 300.); + + // The bit buffer for the texture needs to be 512 pixels, because OpenGL textures are powers of + // two in either dimensions. Our texture is drawing a strip of 300 vertical pixels on the screen, + // so we need to step up to 512 (the nearest power of 2 greater than 300). + texBitBuffer = (UInt32 *)(malloc(sizeof(UInt32) * 512)); + + // Clears the view with black + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + NSUInteger texCount = ceil(CGRectGetWidth(spectrumRect) / (CGFloat)SPECTRUM_BAR_WIDTH); + GLuint *texNames; + + texNames = (GLuint *)(malloc(sizeof(GLuint) * texCount)); + glGenTextures(texCount, texNames); + + int i; + SpectrumLinkedTexture *curTex = NULL; + firstTex = (SpectrumLinkedTexture *)(calloc(1, sizeof(SpectrumLinkedTexture))); + firstTex->texName = texNames[0]; + curTex = firstTex; + + bzero(texBitBuffer, sizeof(UInt32) * 512); + + glBindTexture(GL_TEXTURE_2D, curTex->texName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + for (i=1; inextTex = (SpectrumLinkedTexture *)(calloc(1, sizeof(SpectrumLinkedTexture))); + curTex = curTex->nextTex; + curTex->texName = texNames[i]; + + glBindTexture(GL_TEXTURE_2D, curTex->texName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + // Enable use of the texture + glEnable(GL_TEXTURE_2D); + // Set a blending function to use + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + // Enable blending + glEnable(GL_BLEND); + + initted_spectrum = YES; + + free(texNames); + +} + + + +- (void)drawOscilloscope +{ + // Clear the view + glClear(GL_COLOR_BUFFER_BIT); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glColor4f(1., 1., 1., 1.); + + glPushMatrix(); + + glTranslatef(0., 480., 0.); + glRotatef(-90., 0., 0., 1.); + + + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + { + // Draw our background oscilloscope screen + const GLfloat vertices[] = { + 0., 0., + 512., 0., + 0., 512., + 512., 512., + }; + const GLshort texCoords[] = { + 0, 0, + 1, 0, + 0, 1, + 1, 1, + }; + + + glBindTexture(GL_TEXTURE_2D, bgTexture); + + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_SHORT, 0, texCoords); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + + { + // Draw our buttons + const GLfloat vertices[] = { + 0., 0., + 112, 0., + 0., 64, + 112, 64, + }; + const GLshort texCoords[] = { + 0, 0, + 1, 0, + 0, 1, + 1, 1, + }; + + glPushMatrix(); + + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_SHORT, 0, texCoords); + + glTranslatef(5, 0, 0); + glBindTexture(GL_TEXTURE_2D, sonoTexture); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glTranslatef(99, 0, 0); + glBindTexture(GL_TEXTURE_2D, mute ? muteOnTexture : muteOffTexture); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glTranslatef(99, 0, 0); + glBindTexture(GL_TEXTURE_2D, (displayMode == aurioTouchDisplayModeOscilloscopeFFT) ? fftOnTexture : fftOffTexture); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glPopMatrix(); + + } + + + + if (displayMode == aurioTouchDisplayModeOscilloscopeFFT) + { + if (fftBufferManager->HasNewAudioData()) + { + if (fftBufferManager->ComputeFFT(l_fftData)) + [self setFFTData:l_fftData length:fftBufferManager->GetNumberFrames() / 2]; + else + hasNewFFTData = NO; + } + + if (hasNewFFTData) + { + + int y, maxY; + maxY = drawBufferLen; + for (y=0; y> 24; + fft_r = (fftData[(int)fftIdx_i + 1] & 0xFF000000) >> 24; + fft_l_fl = (CGFloat)(fft_l + 80) / 64.; + fft_r_fl = (CGFloat)(fft_r + 80) / 64.; + interpVal = fft_l_fl * (1. - fftIdx_f) + fft_r_fl * fftIdx_f; + + interpVal = CLAMP(0., interpVal, 1.); + + drawBuffers[0][y] = (interpVal * 120); + + } + cycleOscilloscopeLines(); + + } + + } + + + + GLfloat *oscilLine_ptr; + GLfloat max = drawBufferLen; + SInt8 *drawBuffer_ptr; + + // Alloc an array for our oscilloscope line vertices + if (resetOscilLine) { + oscilLine = (GLfloat*)realloc(oscilLine, drawBufferLen * 2 * sizeof(GLfloat)); + resetOscilLine = NO; + } + + glPushMatrix(); + + // Translate to the left side and vertical center of the screen, and scale so that the screen coordinates + // go from 0 to 1 along the X, and -1 to 1 along the Y + glTranslatef(17., 182., 0.); + glScalef(448., 116., 1.); + + // Set up some GL state for our oscilloscope lines + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisable(GL_LINE_SMOOTH); + glLineWidth(2.); + + int drawBuffer_i; + // Draw a line for each stored line in our buffer (the lines are stored and fade over time) + for (drawBuffer_i=0; drawBuffer_inextTex = firstTex; + firstTex = newFirst; + + SpectrumLinkedTexture *thisTex = firstTex; + do { + if (!(thisTex->nextTex->nextTex)) + { + firstTex->texName = thisTex->nextTex->texName; + free(thisTex->nextTex); + thisTex->nextTex = NULL; + } + thisTex = thisTex->nextTex; + } while (thisTex); +} + + +- (void)renderFFTToTex +{ + [self cycleSpectrum]; + + UInt32 *texBitBuffer_ptr = texBitBuffer; + + static int numLevels = sizeof(colorLevels) / sizeof(GLfloat) / 5; + + int y, maxY; + maxY = CGRectGetHeight(spectrumRect); + for (y=0; y> 24; + fft_r = (fftData[(int)fftIdx_i + 1] & 0xFF000000) >> 24; + fft_l_fl = (CGFloat)(fft_l + 80) / 64.; + fft_r_fl = (CGFloat)(fft_r + 80) / 64.; + interpVal = fft_l_fl * (1. - fftIdx_f) + fft_r_fl * fftIdx_f; + + interpVal = sqrt(CLAMP(0., interpVal, 1.)); + + UInt32 newPx = 0xFF000000; + + int level_i; + const GLfloat *thisLevel = colorLevels; + const GLfloat *nextLevel = colorLevels + 5; + for (level_i=0; level_i<(numLevels-1); level_i++) + { + if ( (*thisLevel <= interpVal) && (*nextLevel >= interpVal) ) + { + double fract = (interpVal - *thisLevel) / (*nextLevel - *thisLevel); + newPx = + ((UInt8)(255. * linearInterp(thisLevel[1], nextLevel[1], fract)) << 24) + | + ((UInt8)(255. * linearInterp(thisLevel[2], nextLevel[2], fract)) << 16) + | + ((UInt8)(255. * linearInterp(thisLevel[3], nextLevel[3], fract)) << 8) + | + (UInt8)(255. * linearInterp(thisLevel[4], nextLevel[4], fract)) + ; + break; + } + + thisLevel+=5; + nextLevel+=5; + } + + *texBitBuffer_ptr++ = newPx; + } + + glBindTexture(GL_TEXTURE_2D, firstTex->texName); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, texBitBuffer); + + hasNewFFTData = NO; +} + + + +- (void)drawSpectrum +{ + // Clear the view + glClear(GL_COLOR_BUFFER_BIT); + + if (fftBufferManager->HasNewAudioData()) + { + if (fftBufferManager->ComputeFFT(l_fftData)) + { + [self setFFTData:l_fftData length:fftBufferManager->GetNumberFrames() / 2]; + } + else + hasNewFFTData = NO; + } + + if (hasNewFFTData) [self renderFFTToTex]; + + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_TEXTURE); + glEnable(GL_TEXTURE_2D); + + glPushMatrix(); + glTranslatef(0., 480., 0.); + glRotatef(-90., 0., 0., 1.); + glTranslatef(spectrumRect.origin.x + spectrumRect.size.width, spectrumRect.origin.y, 0.); + + GLfloat quadCoords[] = { + 0., 0., + SPECTRUM_BAR_WIDTH, 0., + 0., 512., + SPECTRUM_BAR_WIDTH, 512., + }; + + GLshort texCoords[] = { + 0, 0, + 1, 0, + 0, 1, + 1, 1, + }; + + glVertexPointer(2, GL_FLOAT, 0, quadCoords); + glEnableClientState(GL_VERTEX_ARRAY); + glTexCoordPointer(2, GL_SHORT, 0, texCoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glColor4f(1., 1., 1., 1.); + + SpectrumLinkedTexture *thisTex; + glPushMatrix(); + for (thisTex = firstTex; thisTex; thisTex = thisTex->nextTex) + { + glTranslatef(-(SPECTRUM_BAR_WIDTH), 0., 0.); + glBindTexture(GL_TEXTURE_2D, thisTex->texName); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glPopMatrix(); + glPopMatrix(); + + glFlush(); + +} + +- (void)drawView:(id)sender forTime:(NSTimeInterval)time +{ + if ((displayMode == aurioTouchDisplayModeOscilloscopeWaveform) || (displayMode == aurioTouchDisplayModeOscilloscopeFFT)) + { + if (!initted_oscilloscope) [self setupViewForOscilloscope]; + [self drawOscilloscope]; + } else if (displayMode == aurioTouchDisplayModeSpectrum) { + if (!initted_spectrum) [self setupViewForSpectrum]; + [self drawSpectrum]; + } +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + // If we're if waveform mode and not currently in a pinch event, and we've got two touches, start a pinch event + if ((!pinchEvent) && ([[event allTouches] count] == 2) && (self.displayMode == aurioTouchDisplayModeOscilloscopeWaveform)) + { + pinchEvent = event; + NSArray *t = [[event allTouches] allObjects]; + lastPinchDist = fabs([[t objectAtIndex:0] locationInView:view].x - [[t objectAtIndex:1] locationInView:view].x); + + sampleSizeText.text = [NSString stringWithFormat:@"%i ms", drawBufferLen / (int)(hwSampleRate / 1000.)]; + [view addSubview:sampleSizeOverlay]; + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + // If we are in a pinch event... + if ((event == pinchEvent) && ([[event allTouches] count] == 2)) + { + CGFloat thisPinchDist, pinchDiff; + NSArray *t = [[event allTouches] allObjects]; + thisPinchDist = fabs([[t objectAtIndex:0] locationInView:view].x - [[t objectAtIndex:1] locationInView:view].x); + + // Find out how far we traveled since the last event + pinchDiff = thisPinchDist - lastPinchDist; + // Adjust our draw buffer length accordingly, + drawBufferLen -= 12 * (int)pinchDiff; + drawBufferLen = CLAMP(kMinDrawSamples, drawBufferLen, kMaxDrawSamples); + resetOscilLine = YES; + + // and display the size of our oscilloscope window in our overlay view + sampleSizeText.text = [NSString stringWithFormat:@"%i ms", drawBufferLen / (int)(hwSampleRate / 1000.)]; + + lastPinchDist = thisPinchDist; + } +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (event == pinchEvent) + { + // If our pinch/zoom has ended, nil out the pinchEvent and remove the overlay view + [sampleSizeOverlay removeFromSuperview]; + pinchEvent = nil; + return; + } + + // any tap in sonogram view will exit back to the waveform + if (self.displayMode == aurioTouchDisplayModeSpectrum) + { + AudioServicesPlaySystemSound(buttonPressSound); + self.displayMode = aurioTouchDisplayModeOscilloscopeWaveform; + return; + } + + UITouch *touch = [touches anyObject]; + if (unitIsRunning) + { + if (CGRectContainsPoint(CGRectMake(0., 5., 52., 99.), [touch locationInView:view])) // The Sonogram button was touched + { + AudioServicesPlaySystemSound(buttonPressSound); + if ((self.displayMode == aurioTouchDisplayModeOscilloscopeWaveform) || (self.displayMode == aurioTouchDisplayModeOscilloscopeFFT)) + { + if (!initted_spectrum) [self setupViewForSpectrum]; + [self clearTextures]; + self.displayMode = aurioTouchDisplayModeSpectrum; + } + } + else if (CGRectContainsPoint(CGRectMake(0., 104., 52., 99.), [touch locationInView:view])) // The Mute button was touched + { + AudioServicesPlaySystemSound(buttonPressSound); + self.mute = !(self.mute); + return; + } + else if (CGRectContainsPoint(CGRectMake(0., 203, 52., 99.), [touch locationInView:view])) // The FFT button was touched + { + AudioServicesPlaySystemSound(buttonPressSound); + self.displayMode = (self.displayMode == aurioTouchDisplayModeOscilloscopeWaveform) ? aurioTouchDisplayModeOscilloscopeFFT : + aurioTouchDisplayModeOscilloscopeWaveform; + return; + } + } +} + +@end diff --git a/aurioTouch/EAGLView.h b/aurioTouch/EAGLView.h new file mode 100755 index 0000000..9235df2 --- /dev/null +++ b/aurioTouch/EAGLView.h @@ -0,0 +1,101 @@ +/* + + File: EAGLView.h +Abstract: This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view content is basically an EAGL surface you render your OpenGL scene into. Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import +#import +#import +#import + +@protocol EAGLViewDelegate +@required +- (void)drawView:(id)sender forTime:(NSTimeInterval)time; +@optional +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; +@end + +@interface EAGLView : UIView +{ +@private + + /* The pixel dimensions of the backbuffer */ + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + + /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ + GLuint viewRenderbuffer, viewFramebuffer; + + /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ + GLuint depthRenderbuffer; + + /* OpenGL name for the sprite texture */ + GLuint bgTexture; + + id delegate; + + NSTimer *animationTimer; + NSTimeInterval animationInterval; + NSTimeInterval animationStarted; + + BOOL applicationResignedActive; +} + +- (void)startAnimation; +- (void)stopAnimation; +- (void)drawView; + +@property NSTimeInterval animationInterval; +@property(assign) id delegate; +@property(assign) BOOL applicationResignedActive; + +@end diff --git a/aurioTouch/EAGLView.m b/aurioTouch/EAGLView.m new file mode 100755 index 0000000..cd94334 --- /dev/null +++ b/aurioTouch/EAGLView.m @@ -0,0 +1,269 @@ +/* + + File: EAGLView.m +Abstract: This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view content is basically an EAGL surface you render your OpenGL scene into. Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import +#import + +#import "EAGLView.h" + +#define USE_DEPTH_BUFFER 1 + +@interface EAGLView (EAGLViewPrivate) + +- (BOOL)createFramebuffer; +- (void)destroyFramebuffer; + +@end + +@interface EAGLView (EAGLViewSprite) + +- (void)setupView; + +@end + +@implementation EAGLView + +@synthesize animationInterval, applicationResignedActive; + +// You must implement this ++ (Class) layerClass +{ + return [CAEAGLLayer class]; +} + + +//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder +{ + if((self = [super initWithCoder:coder])) { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer; + + eaglLayer.opaque = YES; + + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) { + [self release]; + return nil; + } + + animationInterval = 1.0 / 60.0; + + [self setupView]; + [self drawView]; + } + + return self; +} + + +- (void)layoutSubviews +{ + [EAGLContext setCurrentContext:context]; + [self destroyFramebuffer]; + [self createFramebuffer]; + [self drawView]; +} + + +- (BOOL)createFramebuffer +{ + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + if(USE_DEPTH_BUFFER) { + glGenRenderbuffersOES(1, &depthRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + } + + if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + + +- (void)destroyFramebuffer +{ + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if(depthRenderbuffer) { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + +- (void)startAnimation +{ + animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES]; + animationStarted = [NSDate timeIntervalSinceReferenceDate]; +} + +- (void)stopAnimation +{ + [animationTimer invalidate]; + animationTimer = nil; +} + +- (void)setAnimationInterval:(NSTimeInterval)interval +{ + animationInterval = interval; + + if(animationTimer) { + [self stopAnimation]; + [self startAnimation]; + } +} + + +- (void)setupView +{ + + // Sets up matrices and transforms for OpenGL ES + glViewport(0, 0, backingWidth, backingHeight); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, backingWidth, 0, backingHeight, -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); + + // Clears the view with black + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + glEnableClientState(GL_VERTEX_ARRAY); + ///glEnableClientState(GL_TEXTURE_COORD_ARRAY); + +} + +// Updates the OpenGL view when the timer fires +- (void)drawView +{ + // the NSTimer seems to fire one final time even though it's been invalidated + // so just make sure and not draw if we're resigning active + if (self.applicationResignedActive) return; + + // Make sure that you are drawing to the current context + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + + [delegate drawView:self forTime:([NSDate timeIntervalSinceReferenceDate] - animationStarted)]; + + /* + glRotatef(3.0f, 0.0f, 0.0f, 1.0f); + + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + */ + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +// Stop animating and release resources when they are no longer needed. +- (void)dealloc +{ + [self stopAnimation]; + + if([EAGLContext currentContext] == context) { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + context = nil; + + [super dealloc]; +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + if ([(id)delegate respondsToSelector:@selector(touchesBegan:withEvent:)]) + [delegate touchesBegan:touches withEvent:event]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + if ([(id)delegate respondsToSelector:@selector(touchesMoved:withEvent:)]) + [delegate touchesMoved:touches withEvent:event]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if ([(id)delegate respondsToSelector:@selector(touchesEnded:withEvent:)]) + [delegate touchesEnded:touches withEvent:event]; +} + + + +- (id )delegate { return delegate; } +- (void)setDelegate:(id )v +{ + delegate = v; +} + +@end diff --git a/aurioTouch/Info.plist b/aurioTouch/Info.plist new file mode 100755 index 0000000..1194547 --- /dev/null +++ b/aurioTouch/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarHidden + + + diff --git a/aurioTouch/MainWindow.xib b/aurioTouch/MainWindow.xib new file mode 100755 index 0000000..d5053fb --- /dev/null +++ b/aurioTouch/MainWindow.xib @@ -0,0 +1,244 @@ + + + + 512 + 9C7010 + 658 + 949.26 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + YES + + + 1292 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MC4wMTUzMDYxMTUgMC4wMTUzMDYxMTUgMC4wMTUzMDYxMTUAA + + NO + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + view + + + + 21 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 20 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 20.CustomClassName + 20.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{569, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + aurioTouchAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 21 + + + + YES + + EAGLView + UIView + + delegate + id + + + IBProjectSource + EAGLView.h + + + + UIWindow + UIView + + IBUserSource + + + + + aurioTouchAppDelegate + NSObject + + YES + + YES + view + window + + + YES + EAGLView + UIWindow + + + + IBProjectSource + Classes/aurioTouchAppDelegate.h + + + + aurioTouchAppDelegate + NSObject + + IBUserSource + + + + + + 0 + aurioTouch.xcodeproj + 3 + + diff --git a/aurioTouch/ReadMe.txt b/aurioTouch/ReadMe.txt new file mode 100644 index 0000000..d8b36c9 --- /dev/null +++ b/aurioTouch/ReadMe.txt @@ -0,0 +1,103 @@ + +aurioTouch + +=========================================================================== +DESCRIPTION: + +aurioTouch demonstrates use of the remote i/o audio unit for handling audio input and output. The application can display the input audio in one of the forms, a regular time domain waveform, a frequency domain waveform (computed by performing a fast fourier transform on the incoming signal), and a sonogram view (a view displaying the frequency content of a signal over time, with the color signaling relative power, the y axis being frequency and the x as time). Tap the sonogram button to switch to a sonogram view, tap anywhere on the screen to return to the oscilloscope. Tap the FFT button to perform and display the input data after an FFT transform. Pinch in the oscilloscope view to expand and contract the scale for the x axis. + +The code in auriouTouch uses the remote i/o audio unit (AURemoteIO) for input and output of audio, and OpenGL for display of the input waveform. The application also uses Audio Session Services to manage route changes (as described in Core Audio Overview). + +This application shows how to: + + * Set up the remote i/o audio unit for input and output. + * Use OpenGL for graphical display of audio waveforms. + * Use touch events such as tapping and pinching for user interaction + * Use Audio Session Services to handle route changes and reconfigure the unit in response. + * Use Audio Session Services to set an audio session category for concurrent input and output. + * Use Audio Session Services to play simple alert sounds. + +aurioTouch does not demonstrate how to handle interruptions. + + +=========================================================================== +RELATED INFORMATION: + +Core Audio Overview +WWDC 2010 video sessions and resources + + +=========================================================================== +SPECIAL CONSIDERATIONS: + +aurioTouch requires audio input, and so is not appropriate for the first generation iPod touch. + + +=========================================================================== +BUILD REQUIREMENTS: + +Mac OS X v10.6.4, Xcode 3.2, iOS 4.1, iOS SDK 4.1 or later + + +=========================================================================== +RUNTIME REQUIREMENTS: + +Simulator: Mac OS X v10.6.x, iOS SDK 4.1 or later +iPhone: iOS 4.1 + + +=========================================================================== +PACKAGING LIST: + +EAGLView.h +EAGLView.m + +This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. + +aurio_helper.cpp +aurio_helper.h + +Helper functions for manipulating the remote i/o audio unit, responsible for setting up the remote i/o. + +aurioTouchAppDelegate.h +aurioTouchAppDelegate.mm + + +The application delegate for the aurioTouch app, responsible for handling touch events and drawing. + +FFTBufferManager.cpp +FFTBufferManager.h + +This class manages buffering and computation for FFT analysis on input audio data. The methods provided are used to grab the audio, buffer it, and perform the FFT when sufficient data is available. + +rad2fft.h +rad2fft.c + +Provides a set of methods for radix 2 integer FFT operations. + +SpectrumAnalysis.cpp +SpectrumAnalysis.h + +This class provides a simple spectral analysis tool. + +CAMath.h + +CAMath is a helper class for various math functions. + +CADebugMacros.h +CADebugMacros.cpp + +A helper class for printing debug messages. + +CAXException.h +CAXException.cpp + +A helper class for exception handling. + +CAStreamBasicDescription.cpp +CAStreamBasicDescription.h + +A helper class for AudioStreamBasicDescription handling and manipulation. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. diff --git a/aurioTouch/Resources/audio/button_press.caf b/aurioTouch/Resources/audio/button_press.caf new file mode 100644 index 0000000..9acb7a5 Binary files /dev/null and b/aurioTouch/Resources/audio/button_press.caf differ diff --git a/aurioTouch/Resources/images/fft_off.png b/aurioTouch/Resources/images/fft_off.png new file mode 100644 index 0000000..5e91856 Binary files /dev/null and b/aurioTouch/Resources/images/fft_off.png differ diff --git a/aurioTouch/Resources/images/fft_on.png b/aurioTouch/Resources/images/fft_on.png new file mode 100644 index 0000000..824d667 Binary files /dev/null and b/aurioTouch/Resources/images/fft_on.png differ diff --git a/aurioTouch/Resources/images/mute_off.png b/aurioTouch/Resources/images/mute_off.png new file mode 100644 index 0000000..81f80b6 Binary files /dev/null and b/aurioTouch/Resources/images/mute_off.png differ diff --git a/aurioTouch/Resources/images/mute_on.png b/aurioTouch/Resources/images/mute_on.png new file mode 100644 index 0000000..42984e7 Binary files /dev/null and b/aurioTouch/Resources/images/mute_on.png differ diff --git a/aurioTouch/Resources/images/oscilloscope.png b/aurioTouch/Resources/images/oscilloscope.png new file mode 100644 index 0000000..82283f8 Binary files /dev/null and b/aurioTouch/Resources/images/oscilloscope.png differ diff --git a/aurioTouch/Resources/images/sonogram.png b/aurioTouch/Resources/images/sonogram.png new file mode 100644 index 0000000..ef3f0a1 Binary files /dev/null and b/aurioTouch/Resources/images/sonogram.png differ diff --git a/aurioTouch/aurioTouch.xcodeproj/project.pbxproj b/aurioTouch/aurioTouch.xcodeproj/project.pbxproj new file mode 100755 index 0000000..df075c4 --- /dev/null +++ b/aurioTouch/aurioTouch.xcodeproj/project.pbxproj @@ -0,0 +1,378 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 0765F5880DF0DC28006468E4 /* rad2fft.c in Sources */ = {isa = PBXBuildFile; fileRef = 0765F5860DF0DC28006468E4 /* rad2fft.c */; }; + 1D3623260D0F684500981E51 /* aurioTouchAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* aurioTouchAppDelegate.mm */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + A10A0C0C0DEDDFD000E5A482 /* SpectrumAnalysis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A10A0C070DEDDFD000E5A482 /* SpectrumAnalysis.cpp */; }; + A10A0C0F0DEDE20700E5A482 /* FFTBufferManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A10A0C0E0DEDE20700E5A482 /* FFTBufferManager.cpp */; }; + A15CFB1D0DE4A8C600FB5D08 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = A15CFB1C0DE4A8C600FB5D08 /* icon.png */; }; + A16C46DE0DE37EC400F4A0B3 /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = A16C46DC0DE37EC400F4A0B3 /* EAGLView.m */; }; + A16C47120DE37F9E00F4A0B3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A16C47110DE37F9E00F4A0B3 /* OpenGLES.framework */; }; + A16C473F0DE3801700F4A0B3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A16C473E0DE3801700F4A0B3 /* QuartzCore.framework */; }; + A16C48360DE389CB00F4A0B3 /* oscilloscope.png in Resources */ = {isa = PBXBuildFile; fileRef = A16C48350DE389CB00F4A0B3 /* oscilloscope.png */; }; + F712EAB00DF0FEAF003F7B58 /* aurio_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F712EAAE0DF0FEAF003F7B58 /* aurio_helper.cpp */; }; + F74ADD190DDA24AA0046BEC2 /* CADebugMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F74ADD0F0DDA24AA0046BEC2 /* CADebugMacros.cpp */; }; + F74ADD1B0DDA24AA0046BEC2 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F74ADD150DDA24AA0046BEC2 /* CAStreamBasicDescription.cpp */; }; + F74ADD1C0DDA24AA0046BEC2 /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F74ADD170DDA24AA0046BEC2 /* CAXException.cpp */; }; + F7CF73110EB1258D0099AA71 /* sonogram.png in Resources */ = {isa = PBXBuildFile; fileRef = F7CF73100EB1258D0099AA71 /* sonogram.png */; }; + F7CF73160EB126740099AA71 /* fft_off.png in Resources */ = {isa = PBXBuildFile; fileRef = F7CF73120EB126740099AA71 /* fft_off.png */; }; + F7CF73170EB126740099AA71 /* fft_on.png in Resources */ = {isa = PBXBuildFile; fileRef = F7CF73130EB126740099AA71 /* fft_on.png */; }; + F7CF73180EB126740099AA71 /* mute_off.png in Resources */ = {isa = PBXBuildFile; fileRef = F7CF73140EB126740099AA71 /* mute_off.png */; }; + F7CF73190EB126740099AA71 /* mute_on.png in Resources */ = {isa = PBXBuildFile; fileRef = F7CF73150EB126740099AA71 /* mute_on.png */; }; + F7DF06DE0DF4AD57005687F5 /* button_press.caf in Resources */ = {isa = PBXBuildFile; fileRef = F7DF06DC0DF4AD57005687F5 /* button_press.caf */; }; + F7E58EDA0DCFD988006C4A2F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7E58ED90DCFD988006C4A2F /* AudioToolbox.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0765F5860DF0DC28006468E4 /* rad2fft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rad2fft.c; sourceTree = ""; }; + 0765F5870DF0DC28006468E4 /* rad2fft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rad2fft.h; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* aurioTouchAppDelegate.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = aurioTouchAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* aurioTouchAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = aurioTouchAppDelegate.mm; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* aurioTouch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = aurioTouch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainWindow.xib; path = ../MainWindow.xib; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* aurioTouch_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aurioTouch_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Info.plist; sourceTree = ""; }; + A10A0C070DEDDFD000E5A482 /* SpectrumAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpectrumAnalysis.cpp; sourceTree = ""; }; + A10A0C080DEDDFD000E5A482 /* SpectrumAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpectrumAnalysis.h; sourceTree = ""; }; + A10A0C0D0DEDE20700E5A482 /* FFTBufferManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFTBufferManager.h; sourceTree = ""; }; + A10A0C0E0DEDE20700E5A482 /* FFTBufferManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FFTBufferManager.cpp; sourceTree = ""; }; + A15CFB1C0DE4A8C600FB5D08 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon.png; path = ../icon.png; sourceTree = ""; }; + A16C46DC0DE37EC400F4A0B3 /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = SOURCE_ROOT; }; + A16C46DD0DE37EC400F4A0B3 /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = SOURCE_ROOT; }; + A16C47110DE37F9E00F4A0B3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + A16C473E0DE3801700F4A0B3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + A16C48350DE389CB00F4A0B3 /* oscilloscope.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = oscilloscope.png; sourceTree = ""; }; + F712EAAE0DF0FEAF003F7B58 /* aurio_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aurio_helper.cpp; sourceTree = ""; }; + F712EAAF0DF0FEAF003F7B58 /* aurio_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aurio_helper.h; sourceTree = ""; }; + F74ADD0F0DDA24AA0046BEC2 /* CADebugMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CADebugMacros.cpp; sourceTree = ""; }; + F74ADD100DDA24AA0046BEC2 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = ""; }; + F74ADD120DDA24AA0046BEC2 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = ""; }; + F74ADD150DDA24AA0046BEC2 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + F74ADD160DDA24AA0046BEC2 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + F74ADD170DDA24AA0046BEC2 /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = ""; }; + F74ADD180DDA24AA0046BEC2 /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = ""; }; + F7CF73100EB1258D0099AA71 /* sonogram.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = sonogram.png; sourceTree = ""; }; + F7CF73120EB126740099AA71 /* fft_off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = fft_off.png; sourceTree = ""; }; + F7CF73130EB126740099AA71 /* fft_on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = fft_on.png; sourceTree = ""; }; + F7CF73140EB126740099AA71 /* mute_off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mute_off.png; sourceTree = ""; }; + F7CF73150EB126740099AA71 /* mute_on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mute_on.png; sourceTree = ""; }; + F7DF06DC0DF4AD57005687F5 /* button_press.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = button_press.caf; sourceTree = ""; }; + F7E58ED90DCFD988006C4A2F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + F7E58EDA0DCFD988006C4A2F /* AudioToolbox.framework in Frameworks */, + A16C47120DE37F9E00F4A0B3 /* OpenGLES.framework in Frameworks */, + A16C473F0DE3801700F4A0B3 /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + A16C46DD0DE37EC400F4A0B3 /* EAGLView.h */, + A16C46DC0DE37EC400F4A0B3 /* EAGLView.m */, + A10A0C0D0DEDE20700E5A482 /* FFTBufferManager.h */, + A10A0C0E0DEDE20700E5A482 /* FFTBufferManager.cpp */, + 1D3623240D0F684500981E51 /* aurioTouchAppDelegate.h */, + 1D3623250D0F684500981E51 /* aurioTouchAppDelegate.mm */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* aurioTouch.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + A10A0BFE0DEDDFD000E5A482 /* fft */, + F74ADD0E0DDA24AA0046BEC2 /* iPublicUtility */, + F712EAAF0DF0FEAF003F7B58 /* aurio_helper.h */, + F712EAAE0DF0FEAF003F7B58 /* aurio_helper.cpp */, + 32CA4F630368D1EE00C91783 /* aurioTouch_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + F7D3FD760FD49018003CBAE4 /* audio */, + F7D3FD800FD49094003CBAE4 /* images */, + A15CFB1C0DE4A8C600FB5D08 /* icon.png */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + A16C473E0DE3801700F4A0B3 /* QuartzCore.framework */, + A16C47110DE37F9E00F4A0B3 /* OpenGLES.framework */, + F7E58ED90DCFD988006C4A2F /* AudioToolbox.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + A10A0BFE0DEDDFD000E5A482 /* fft */ = { + isa = PBXGroup; + children = ( + 0765F5870DF0DC28006468E4 /* rad2fft.h */, + 0765F5860DF0DC28006468E4 /* rad2fft.c */, + A10A0C080DEDDFD000E5A482 /* SpectrumAnalysis.h */, + A10A0C070DEDDFD000E5A482 /* SpectrumAnalysis.cpp */, + ); + path = fft; + sourceTree = ""; + }; + F74ADD0E0DDA24AA0046BEC2 /* iPublicUtility */ = { + isa = PBXGroup; + children = ( + F74ADD100DDA24AA0046BEC2 /* CADebugMacros.h */, + F74ADD0F0DDA24AA0046BEC2 /* CADebugMacros.cpp */, + F74ADD180DDA24AA0046BEC2 /* CAXException.h */, + F74ADD170DDA24AA0046BEC2 /* CAXException.cpp */, + F74ADD120DDA24AA0046BEC2 /* CAMath.h */, + F74ADD160DDA24AA0046BEC2 /* CAStreamBasicDescription.h */, + F74ADD150DDA24AA0046BEC2 /* CAStreamBasicDescription.cpp */, + ); + path = iPublicUtility; + sourceTree = ""; + }; + F7D3FD760FD49018003CBAE4 /* audio */ = { + isa = PBXGroup; + children = ( + F7DF06DC0DF4AD57005687F5 /* button_press.caf */, + ); + path = audio; + sourceTree = ""; + }; + F7D3FD800FD49094003CBAE4 /* images */ = { + isa = PBXGroup; + children = ( + F7CF73120EB126740099AA71 /* fft_off.png */, + F7CF73130EB126740099AA71 /* fft_on.png */, + F7CF73140EB126740099AA71 /* mute_off.png */, + F7CF73150EB126740099AA71 /* mute_on.png */, + A16C48350DE389CB00F4A0B3 /* oscilloscope.png */, + F7CF73100EB1258D0099AA71 /* sonogram.png */, + ); + path = images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* aurioTouch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "aurioTouch" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = aurioTouch; + productName = aurioTouch; + productReference = 1D6058910D05DD3D006BFB54 /* aurioTouch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "aurioTouch" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* aurioTouch */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + A16C48360DE389CB00F4A0B3 /* oscilloscope.png in Resources */, + A15CFB1D0DE4A8C600FB5D08 /* icon.png in Resources */, + F7DF06DE0DF4AD57005687F5 /* button_press.caf in Resources */, + F7CF73110EB1258D0099AA71 /* sonogram.png in Resources */, + F7CF73160EB126740099AA71 /* fft_off.png in Resources */, + F7CF73170EB126740099AA71 /* fft_on.png in Resources */, + F7CF73180EB126740099AA71 /* mute_off.png in Resources */, + F7CF73190EB126740099AA71 /* mute_on.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* aurioTouchAppDelegate.mm in Sources */, + F74ADD190DDA24AA0046BEC2 /* CADebugMacros.cpp in Sources */, + F74ADD1B0DDA24AA0046BEC2 /* CAStreamBasicDescription.cpp in Sources */, + F74ADD1C0DDA24AA0046BEC2 /* CAXException.cpp in Sources */, + A16C46DE0DE37EC400F4A0B3 /* EAGLView.m in Sources */, + A10A0C0C0DEDDFD000E5A482 /* SpectrumAnalysis.cpp in Sources */, + A10A0C0F0DEDE20700E5A482 /* FFTBufferManager.cpp in Sources */, + 0765F5880DF0DC28006468E4 /* rad2fft.c in Sources */, + F712EAB00DF0FEAF003F7B58 /* aurio_helper.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = aurioTouch_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = aurioTouch; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = aurioTouch_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = aurioTouch; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_THUMB_SUPPORT = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "aurioTouch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "aurioTouch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/aurioTouch/aurioTouch_Prefix.pch b/aurioTouch/aurioTouch_Prefix.pch new file mode 100755 index 0000000..e66e50b --- /dev/null +++ b/aurioTouch/aurioTouch_Prefix.pch @@ -0,0 +1,54 @@ +/* + + File: aurioTouch_Prefix.pch +Abstract: Prefix file + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/aurioTouch/aurio_helper.cpp b/aurioTouch/aurio_helper.cpp new file mode 100644 index 0000000..5dc6984 --- /dev/null +++ b/aurioTouch/aurio_helper.cpp @@ -0,0 +1,164 @@ +/* + + File: aurio_helper.cpp +Abstract: Helper class for manipulating the remote i/o audio unit + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include +#include +#include + +#include "CAXException.h" +#include "CAStreamBasicDescription.h" +#include "aurio_helper.h" + +// This determines how slowly the oscilloscope lines fade away from the display. +// Larger numbers = slower fade (and more strain on the graphics processing) +SInt8 *drawBuffers[kNumDrawBuffers]; + +int drawBufferIdx = 0; +int drawBufferLen = kDefaultDrawSamples; +int drawBufferLen_alloced = 0; + +int SetupRemoteIO (AudioUnit& inRemoteIOUnit, AURenderCallbackStruct inRenderProc, CAStreamBasicDescription& outFormat) +{ + try { + // Open the output unit + AudioComponentDescription desc; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_RemoteIO; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + AudioComponent comp = AudioComponentFindNext(NULL, &desc); + + XThrowIfError(AudioComponentInstanceNew(comp, &inRemoteIOUnit), "couldn't open the remote I/O unit"); + + UInt32 one = 1; + XThrowIfError(AudioUnitSetProperty(inRemoteIOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, sizeof(one)), "couldn't enable input on the remote I/O unit"); + + XThrowIfError(AudioUnitSetProperty(inRemoteIOUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &inRenderProc, sizeof(inRenderProc)), "couldn't set remote i/o render callback"); + + // set our required format - Canonical AU format: LPCM non-interleaved 8.24 fixed point + outFormat.SetAUCanonical(2, false); + outFormat.mSampleRate = 44100; + XThrowIfError(AudioUnitSetProperty(inRemoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outFormat, sizeof(outFormat)), "couldn't set the remote I/O unit's output client format"); + XThrowIfError(AudioUnitSetProperty(inRemoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &outFormat, sizeof(outFormat)), "couldn't set the remote I/O unit's input client format"); + + XThrowIfError(AudioUnitInitialize(inRemoteIOUnit), "couldn't initialize the remote I/O unit"); + } + catch (CAXException &e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + return 1; + } + catch (...) { + fprintf(stderr, "An unknown error occurred\n"); + return 1; + } + + return 0; +} + +void SilenceData(AudioBufferList *inData) +{ + for (UInt32 i=0; i < inData->mNumberBuffers; i++) + memset(inData->mBuffers[i].mData, 0, inData->mBuffers[i].mDataByteSize); +} + + +inline SInt32 smul32by16(SInt32 i32, SInt16 i16) +{ +#if defined __arm__ + register SInt32 r; + asm volatile("smulwb %0, %1, %2" : "=r"(r) : "r"(i32), "r"(i16)); + return r; +#else + return (SInt32)(((SInt64)i32 * (SInt64)i16) >> 16); +#endif +} + +inline SInt32 smulAdd32by16(SInt32 i32, SInt16 i16, SInt32 acc) +{ +#if defined __arm__ + register SInt32 r; + asm volatile("smlawb %0, %1, %2, %3" : "=r"(r) : "r"(i32), "r"(i16), "r"(acc)); + return r; +#else + return ((SInt32)(((SInt64)i32 * (SInt64)i16) >> 16) + acc); +#endif +} + +const Float32 DCRejectionFilter::kDefaultPoleDist = 0.975f; + +DCRejectionFilter::DCRejectionFilter(Float32 poleDist) +{ + mA1 = (SInt16)((float)(1<<15)*poleDist); + mGain = (mA1 >> 1) + (1<<14); // Normalization factor: (r+1)/2 = r/2 + 0.5 + Reset(); +} + +void DCRejectionFilter::Reset() +{ + mY1 = mX1 = 0; +} + +void DCRejectionFilter::InplaceFilter(SInt32* ioData, UInt32 numFrames, UInt32 strides) +{ + register SInt32 y1 = mY1, x1 = mX1; + for (UInt32 i=0; i < numFrames; i++) + { + register SInt32 x0, y0; + x0 = ioData[i*strides]; + y0 = smul32by16(y1, mA1); + y1 = smulAdd32by16(x0 - x1, mGain, y0) << 1; + ioData[i*strides] = y1; + x1 = x0; + } + mY1 = y1; + mX1 = x1; +} diff --git a/aurioTouch/aurio_helper.h b/aurioTouch/aurio_helper.h new file mode 100755 index 0000000..08c365b --- /dev/null +++ b/aurioTouch/aurio_helper.h @@ -0,0 +1,89 @@ +/* + + File: aurio_helper.h +Abstract: Helper class for manipulating the remote i/o audio unit + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#if !defined(__rio_helper_h__) +#define __rio_helper_h__ + +#include "CAStreamBasicDescription.h" + +#define kNumDrawBuffers 12 +#define kDefaultDrawSamples 1024 +#define kMinDrawSamples 64 +#define kMaxDrawSamples 4096 + +extern int drawBufferIdx; +extern int drawBufferLen; +extern int drawBufferLen_alloced; +extern SInt8 *drawBuffers[]; + +int SetupRemoteIO (AudioUnit& inRemoteIOUnit, AURenderCallbackStruct inRenderProcm, CAStreamBasicDescription& outFormat); +void SilenceData(AudioBufferList *inData); + +class DCRejectionFilter +{ +public: + DCRejectionFilter(Float32 poleDist = DCRejectionFilter::kDefaultPoleDist); + + void InplaceFilter(SInt32* ioData, UInt32 numFrames, UInt32 strides); + void Reset(); + +protected: + + // Coefficients + SInt16 mA1; + SInt16 mGain; + + // State variables + SInt32 mY1; + SInt32 mX1; + + static const Float32 kDefaultPoleDist; +}; + +#endif \ No newline at end of file diff --git a/aurioTouch/fft/SpectrumAnalysis.cpp b/aurioTouch/fft/SpectrumAnalysis.cpp new file mode 100644 index 0000000..3117819 --- /dev/null +++ b/aurioTouch/fft/SpectrumAnalysis.cpp @@ -0,0 +1,235 @@ +/* + + File: SpectrumAnalysis.cpp +Abstract: Simple spectral analysis tool + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include +#include +#include +#include +#include "rad2fft.h" +#include "SpectrumAnalysis.h" + +#define Scale(e) powf(2.0,e) + +#define kLog2TableLog2Size 8 +#define kLog2TableSize (1<>shiftArg]; + } + return y; +} + + +#if defined __arm__ +inline int mul32_16b(int32_t x, int32_t y) { int32_t z; asm volatile("smulwb %0, %1, %2" : "=r"(z) : "r"(x), "r"(y)); return z; } +inline int mul32_16t(int32_t x, int32_t y) { int32_t z; asm volatile("smulwt %0, %1, %2" : "=r"(z) : "r"(x), "r"(y)); return z; } +inline int32_t SquareMag(int32_t re, int32_t im) +{ + register int32_t z; + asm volatile("smultt %0, %1, %2" : "=r"(z) : "r"(re), "r"(re)); + asm volatile("smlatt %0, %1, %2, %3" : "=r"(z) : "r"(im), "r"(im), "0"(z)); + return z; +} +#else +#define mul32_16b(a,b) ((int32_t)(((int64_t)(a) * (int64_t)((b) & 0x0000ffff))>>16)) +#define mul32_16t(a,b) ((int32_t)(((int64_t)(a) * (int64_t)(((b) & 0xffff0000)>>16))>>16)) +inline int32_t SquareMag(int32_t re, int32_t im) { return (re>>16)*(re>>16)+(im>>16)*(im>>16); } +#endif + + +struct SPECTRUM_ANALYSIS +{ + int32_t size; + int16_t* weightingWindow; + Int32Cplx* fftBuffer; + PackedInt16Cplx* twiddleFactors; +}; + + + +H_SPECTRUM_ANALYSIS SpectrumAnalysisCreate(int32_t size) +{ + H_SPECTRUM_ANALYSIS p = (SPECTRUM_ANALYSIS*)malloc(sizeof(SPECTRUM_ANALYSIS)); + if(p) + { + p->size = size; + + p->weightingWindow = (int16_t*)malloc(sizeof(int16_t)*size); + float nrg = 0.0f; + for(int i = 0; i < size/2; ++i) + { + /* Hamming window */ + float w = 0.53836-0.46164*cosf(2.0*M_PI*i/(float)(size-1)); + nrg += 2.0*w*w; + p->weightingWindow[i] = (int16_t)(powf(2.0, 15.0)*w); + p->weightingWindow[size-i-1] = p->weightingWindow[i]; + } + + p->fftBuffer = (Int32Cplx*)malloc(sizeof(Int32Cplx)*size); + memset(p->fftBuffer, 0, sizeof(Int32Cplx)*size); + + p->twiddleFactors = CreatePackedTwiddleFactors(size); + } + return p; +} + +void SpectrumAnalysisDestroy(H_SPECTRUM_ANALYSIS p) +{ + if(p) + { + if(p->weightingWindow) free(p->weightingWindow); + if(p->fftBuffer) free(p->fftBuffer); + + DisposePackedTwiddleFactors(p->twiddleFactors); + + free(p); + } +} + +void SpectrumAnalysisProcess(H_SPECTRUM_ANALYSIS p, const int32_t* inTimeSig, int32_t* outMagSpectrum, bool in_dB) +{ + if(p) + { + // Apply weigthing window + for(uint i = 0; i < p->size; i += 2) + { + int32_t dualCoef = *((int32_t*)(p->weightingWindow + i)); + p->fftBuffer[i].real = mul32_16b(inTimeSig[i] << 7, dualCoef) << 1; + p->fftBuffer[i].imag = 0; + p->fftBuffer[i+1].real = mul32_16t(inTimeSig[i+1] << 7, dualCoef) << 1; + p->fftBuffer[i+1].imag = 0; + } + + Radix2IntCplxFFT(p->fftBuffer, p->size, p->twiddleFactors, 1); + + if(in_dB) + { + // Calculate magnitude spectrum in dB + for(uint i = 0; i < p->size/2; ++i) + { + // squared magnitude + int32_t squaredMag = SquareMag(p->fftBuffer[i].real, p->fftBuffer[i].imag); + + // Avoid log(0) + if(squaredMag) + { + // squared mag -> log2 + squaredMag = log2Int(squaredMag<<1) + kAdjust0dBLevel; + } + else + { + squaredMag = kAdjust0dBLevel; + } + + // log2 -> 10*log10 conversion (Q5.26 x Q2.13) + outMagSpectrum[i] = mul32_16b(squaredMag, kLog2ToLog10ScaleFactor) << 1; + } + } + else + { + // Calculate squared magnitude spectrum + for(uint i = 0; i < p->size/2; ++i) + { + // squared magnitude + outMagSpectrum[i] = SquareMag(p->fftBuffer[i].real, p->fftBuffer[i].imag); + } + } + } +} diff --git a/aurioTouch/fft/SpectrumAnalysis.h b/aurioTouch/fft/SpectrumAnalysis.h new file mode 100644 index 0000000..b5c6b3f --- /dev/null +++ b/aurioTouch/fft/SpectrumAnalysis.h @@ -0,0 +1,103 @@ +/* + + File: SpectrumAnalysis.h +Abstract: Simple spectral analysis tool + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#if !defined __SPECTRUM_ANALYSIS_H__ +#define __SPECTRUM_ANALYSIS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Forward declarations + */ +struct SPECTRUM_ANALYSIS; +typedef struct SPECTRUM_ANALYSIS* H_SPECTRUM_ANALYSIS; + + +/* + * Create a SpectrumAnalysis object. The block size argument must be a power of 2 + */ +H_SPECTRUM_ANALYSIS SpectrumAnalysisCreate(int32_t blockSize); + + +/* + * Dispose SpectrumAnalysis object + */ +void SpectrumAnalysisDestroy(H_SPECTRUM_ANALYSIS p); + +/* + * + * Inputs: + * p: an opaque SpectrumAnalysis object handle + * inTimeSig: pointer to a time signal of the same length as specified in SpectrumAnalysisCreate() + * outMagSpectrum: pointer to a magnitude spectrum. Its length must at least be size/2 + * in_dB: flag indicating wether the magnitude spectrum should be calculated in dB + * + * Discussion: + * + * the real valued time signal is first weighted with a Hamming window of the same size and then transformed + * in the frequency domain. The squared magnitudes of the resulting complex spectrum are copied into the + * outMagSpectrum vector and then converted to dB if so requested. Since the input signal is real, the magnitude + * spectrum is only half the size (note that the Nyquist term is discarded) as the input signal. + * + * Value ranges: + * + * the input signal is expected to be in a Q7.24 format in the range [-1, 1) which means that the integer parts should be zero + * the ouput magnitude spectrum is in Q7.24 format with a range of [-128, 0) when calculated in dB. + */ +void SpectrumAnalysisProcess(H_SPECTRUM_ANALYSIS p, const int32_t* inTimeSig, int32_t* outMagSpectrum, bool in_dB); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/aurioTouch/fft/rad2fft.c b/aurioTouch/fft/rad2fft.c new file mode 100644 index 0000000..dfb908e --- /dev/null +++ b/aurioTouch/fft/rad2fft.c @@ -0,0 +1,178 @@ +/* + + File: rad2fft.c +Abstract: Radix 2 integer FFT + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include +#include +#include "rad2fft.h" + +#define CplxMul32Packed(x,p) { \ + int tmp = x.real; int c = (p) & 0xffff0000; int s = ((p)<<16); \ + x.real = (int)( ( (int64_t)tmp * (int64_t)c - (int64_t)x.imag * (int64_t)s ) >> 32 ); \ + x.imag = (int)( ( (int64_t)tmp * (int64_t)s + (int64_t)x.imag * (int64_t)c ) >> 32 ); \ +} \ + +#define Radix2IntButterfly(x0,x1,n) { \ + int tmp = x0.real>>1; \ + x0.real = tmp + (x1.real>>n);\ + x1.real = tmp - (x1.real>>n);\ + tmp = (x0.imag>>1); \ + x0.imag = tmp + (x1.imag>>n);\ + x1.imag = tmp - (x1.imag>>n);\ +} \ + +static int FloatToInt16(float x) +{ + int y; + if(x<0.f) { + if(x<=-32768.0f) y = -32768; + else y = (int)(x - 0.5f); + } else { + if(x>=32767.0f) y = 32767; + else y = (int)(x + 0.5f); + } + return y; +} + + +static void BitReverseReorder(Int32Cplx* ioCplxData, int N) +{ + int linearIdx, bitReversedIdx; + + for(linearIdx = 1, bitReversedIdx = 0; linearIdx < N - 1; ++linearIdx) { + int halfSize = N; + do { + halfSize >>=1; + bitReversedIdx ^= halfSize; + } while(bitReversedIdx < halfSize); + + if(linearIdx < bitReversedIdx) { + /* Swap linear and bit reversed indexed values */ + Int32Cplx tmp = ioCplxData[bitReversedIdx]; + ioCplxData[bitReversedIdx] = ioCplxData[linearIdx]; + ioCplxData[linearIdx] = tmp; + } + } +} + + +PackedInt16Cplx* CreatePackedTwiddleFactors(int size) +{ + int i; + PackedInt16Cplx* twiddleFactors = (PackedInt16Cplx*)malloc(sizeof(PackedInt16Cplx)*size); + float scaleFac = (float)(1<<15); + + if(twiddleFactors) { + for(i = 0; i < size/2; ++i) { + int cosSin; + float tmp; + tmp = scaleFac*cosf(2.0*M_PI*i/size); + cosSin = FloatToInt16(tmp) << 16; + tmp = -scaleFac*sinf(2.0*M_PI*i/size); + cosSin |= FloatToInt16(tmp) & 0x0000ffff; + twiddleFactors[i] = cosSin; + } + } + return twiddleFactors; +} + + +void DisposePackedTwiddleFactors(PackedInt16Cplx* twiddleFactors) +{ + if(twiddleFactors) { + free(twiddleFactors); + } +} + + +void Radix2IntCplxFFT(Int32Cplx* ioCplxData, int size, const PackedInt16Cplx* twiddleFactors, int twiddleFactorsStrides) +{ + int span, twiddle, strides; + + /* Reorder input data in bit reversed order */ + BitReverseReorder(ioCplxData, size); + + span = 1; + twiddle = 1; + strides = twiddleFactorsStrides*size / 2; + + do { + Int32Cplx x0, x1; + int idx = 0; + + do { + /* Multiply-less butterfly */ + x1 = ioCplxData[idx+span]; + x0 = ioCplxData[idx]; + Radix2IntButterfly(x0, x1, 1); + ioCplxData[idx] = x0; + ioCplxData[idx+span] = x1; + idx += span << 1; + } while(idx < size); + + twiddle = 1; + + while(twiddle < span) { + int packedTwiddleFactor = twiddleFactors[strides*twiddle]; + idx = twiddle; + + do { + x1 = ioCplxData[idx+span]; + x0 = ioCplxData[idx]; + CplxMul32Packed(x1, packedTwiddleFactor); + Radix2IntButterfly(x0, x1, 0); + ioCplxData[idx] = x0; + ioCplxData[idx+span] = x1; + idx += span << 1; + } while(idx < size); + ++twiddle; + } + span <<= 1; + strides >>= 1; + } while(span < size); +} diff --git a/aurioTouch/fft/rad2fft.h b/aurioTouch/fft/rad2fft.h new file mode 100644 index 0000000..610fc85 --- /dev/null +++ b/aurioTouch/fft/rad2fft.h @@ -0,0 +1,96 @@ +/* + + File: rad2fft.h +Abstract: Radix 2 integer FFT + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#ifndef __RAD2_FFT_H__ +#define __RAD2_FFT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Struct for holding a 32 bit integer complex numbers + */ +struct Int32Cplx +{ + int real; + int imag; +}; +typedef struct Int32Cplx Int32Cplx; + +/* + * Packed complex type. The upper 16 bits correspond to the real part, + * the lower 16 bit to imaginary part + */ +typedef int PackedInt16Cplx; + + +/* + * Create a lookup table with "size" twiddle factors for the FFT. + */ +PackedInt16Cplx* CreatePackedTwiddleFactors(int size); + + +/* + * Dispose the twiddle factor table + */ +void DisposePackedTwiddleFactors(PackedInt16Cplx* cosSinTable); + + +/* + * Inplace complex radix 2 FFT. The complex data vector must have the specified size and must be a power of 2. + */ +void Radix2IntCplxFFT(Int32Cplx* ioCplxData, int size, const PackedInt16Cplx* twiddleFactors, int twiddleFactorsStrides); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/aurioTouch/iPublicUtility/CADebugMacros.cpp b/aurioTouch/iPublicUtility/CADebugMacros.cpp new file mode 100755 index 0000000..e652f3d --- /dev/null +++ b/aurioTouch/iPublicUtility/CADebugMacros.cpp @@ -0,0 +1,91 @@ +/* + + File: CADebugMacros.cpp +Abstract: Helper class for printing debug messages + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include "CADebugMacros.h" +#include +#include +#if TARGET_API_MAC_OSX + #include +#endif + +#if DEBUG +#include + +void DebugPrint(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} +#endif // DEBUG + +#if TARGET_API_MAC_OSX +void LogError(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); +#if DEBUG + vprintf(fmt, args); +#endif + vsyslog(LOG_ERR, fmt, args); + va_end(args); +} + +void LogWarning(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); +#if DEBUG + vprintf(fmt, args); +#endif + vsyslog(LOG_WARNING, fmt, args); + va_end(args); +} +#endif diff --git a/aurioTouch/iPublicUtility/CADebugMacros.h b/aurioTouch/iPublicUtility/CADebugMacros.h new file mode 100755 index 0000000..d3141c5 --- /dev/null +++ b/aurioTouch/iPublicUtility/CADebugMacros.h @@ -0,0 +1,440 @@ +/* + + File: CADebugMacros.h +Abstract: Helper class for printing debug messages + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#if !defined(__CADebugMacros_h__) +#define __CADebugMacros_h__ + +//============================================================================= +// Includes +//============================================================================= + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CADebugMacros +//============================================================================= + +//#define CoreAudio_StopOnFailure 1 +//#define CoreAudio_TimeStampMessages 1 +//#define CoreAudio_ThreadStampMessages 1 +//#define CoreAudio_FlushDebugMessages 1 + +#if TARGET_RT_BIG_ENDIAN + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } +#else + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } +#endif + +#pragma mark Basic Definitions + +#if DEBUG || CoreAudio_Debug + + // can be used to break into debugger immediately, also see CADebugger + #define BusError() (*(long *)0 = 0) + + // basic debugging print routines + #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON + extern void DebugStr(const unsigned char* debuggerMsg); + #define DebugMessage(msg) DebugStr("\p"msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #else + #include "CADebugPrintf.h" + + #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) + #define FlushRtn ,fflush(DebugPrintfFile) + #else + #define FlushRtn + #endif + + #if CoreAudio_ThreadStampMessages + #include + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #elif CoreAudio_TimeStampMessages + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #else + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%s"DebugPrintfLineEnding, msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #endif + #endif + void DebugPrint(const char *fmt, ...); // can be used like printf + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) + #endif + #if VERBOSE + #define vprint(msg) DEBUGPRINT(msg) + #else + #define vprint(msg) + #endif + + #if CoreAudio_StopOnFailure + #include "CADebugger.h" + #define STOP CADebuggerStop() + #else + #define STOP + #endif + +#else + #define DebugMessage(msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #define DebugMessageN4(msg, N1, N2, N3, N4) + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) + #define DEBUGPRINT(msg) + #define vprint(msg) + #define STOP +#endif + +void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) +void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) + +#if DEBUG || CoreAudio_Debug + +#pragma mark Debug Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + DebugMessage(inMethodName": Subclasses must implement this method"); \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#else + +#pragma mark Release Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + if((inKernelError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + if((inError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#endif // DEBUG || CoreAudio_Debug + +#endif diff --git a/aurioTouch/iPublicUtility/CAMath.h b/aurioTouch/iPublicUtility/CAMath.h new file mode 100755 index 0000000..f19d7a1 --- /dev/null +++ b/aurioTouch/iPublicUtility/CAMath.h @@ -0,0 +1,71 @@ +/* + + File: CAMath.h +Abstract: Helper class for various math functions + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#ifndef __CAMath_h__ +#define __CAMath_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +inline bool fiszero(Float64 f) { return (f == 0.); } +inline bool fiszero(Float32 f) { return (f == 0.f); } + +inline bool fnonzero(Float64 f) { return !fiszero(f); } +inline bool fnonzero(Float32 f) { return !fiszero(f); } + +inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } +inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } + +inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } +inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } + +#endif // __CAMath_h__ diff --git a/aurioTouch/iPublicUtility/CAStreamBasicDescription.cpp b/aurioTouch/iPublicUtility/CAStreamBasicDescription.cpp new file mode 100755 index 0000000..8aa1a83 --- /dev/null +++ b/aurioTouch/iPublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,552 @@ +/* + + File: CAStreamBasicDescription.cpp +Abstract: Helper class for audio stream descriptions + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include "CAStreamBasicDescription.h" +#include "CAMath.h" + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +#if TARGET_OS_WIN32 + #include +#endif + +#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; + mReserved = 0; +} + +char *CAStreamBasicDescription::AsString(char *buf, size_t bufsize) const +{ + char *theBuffer = buf; + int nc; + char formatID[5]; + *(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID); + formatID[4] = '\0'; + nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); + buf += nc; bufsize -= nc; + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (wordSize > 0 && PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + sprintf(packed, "packed in %d bytes", wordSize); + else + sprintf(packed, "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + char bitdepth[20]; + +#if CA_PREFER_FIXED_POINT + int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; + if (fracbits > 0) + sprintf(bitdepth, "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); + else +#endif + sprintf(bitdepth, "%d", (int)mBitsPerChannel); + + nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s", + bitdepth, endian, sign, floatInt, + commaSpace, packed, align, deinter); + //buf += nc; bufsize -= nc; + } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless + int sourceBits = 0; + switch (mFormatFlags) + { + case 1: // kAppleLosslessFormatFlag_16BitSourceData + sourceBits = 16; + break; + case 2: // kAppleLosslessFormatFlag_20BitSourceData + sourceBits = 20; + break; + case 3: // kAppleLosslessFormatFlag_24BitSourceData + sourceBits = 24; + break; + case 4: // kAppleLosslessFormatFlag_32BitSourceData + sourceBits = 32; + break; + } + if (sourceBits) + nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits); + else + nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, "); + buf += nc; bufsize -= nc; + nc = snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket); + //buf += nc; bufsize -= nc; + } + else + nc = snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", + (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); + return theBuffer; +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format + if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) + { + // the canonical linear PCM format + ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; + ioDescription.mBytesPerPacket = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerFrame = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType); + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(fiszero(ioDescription.mSampleRate)) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + const char* theMixabilityString = NULL; + if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) + { + theMixabilityString = "Mixable"; + } + else + { + theMixabilityString = "Unmixable"; + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strcpy(outName, "AC-3"); + break; + + case kAudioFormat60958AC3: + strcpy(outName, "AC-3 for SPDIF"); + break; + + default: + CACopy4CCToCString(outName, inDescription.mFormatID); + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + + // mixable is always better than non-mixable for linear PCM and should be the second order sort item + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) + { + theAnswer = true; + isDone = true; + } + else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) + { + theAnswer = false; + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) + { + if(fnotequal(x.mSampleRate, y.mSampleRate)) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + + // if the number of channels is 0 or 1, we don't care about non-interleavedness + if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) { + xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const +{ + if (interpretingWildcards) + return *this == other; + return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0.) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024); +} diff --git a/aurioTouch/iPublicUtility/CAStreamBasicDescription.h b/aurioTouch/iPublicUtility/CAStreamBasicDescription.h new file mode 100755 index 0000000..66b568f --- /dev/null +++ b/aurioTouch/iPublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,310 @@ +/* + + File: CAStreamBasicDescription.h +Abstract: Helper class for audio stream descriptions + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CoreFoundation.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it + +// define Leopard specific symbols for backward compatibility if applicable +#if COREAUDIOTYPES_VERSION < 1050 +typedef Float32 AudioSampleType; +enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; +#endif +#if COREAUDIOTYPES_VERSION < 1051 +typedef Float32 AudioUnitSampleType; +#endif + +// define the IsMixable format flag for all versions of the system +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; +#else + enum { kIsNonMixableFlag = (1L << 6) }; +#endif + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { + return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; + } + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; +#if TARGET_IPHONE_SIMULATOR + int sampleSize = sizeof(Float32); + mFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + int sampleSize = sizeof(AudioSampleType); + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mBitsPerChannel = 8 * sampleSize; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; + else { + mBytesPerPacket = mBytesPerFrame = sampleSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + bool IsCanonical() const + { + if (mFormatID != kAudioFormatLinearPCM) return false; + UInt32 reqFormatFlags; +#if (COREAUDIOTYPES_VERSION <= 1050) + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh); +#else + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); +#endif + bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; +#if TARGET_IPHONE_SIMULATOR + unsigned sampleSize = sizeof(Float32); + reqFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + unsigned sampleSize = sizeof(AudioSampleType); + reqFormatFlags = kAudioFormatFlagsCanonical; +#endif + UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; + + return ((mFormatFlags & flagsMask) == reqFormatFlags + && mBitsPerChannel == 8 * sampleSize + && mFramesPerPacket == 1 + && mBytesPerFrame == reqFrameSize + && mBytesPerPacket == reqFrameSize); + } + + void SetAUCanonical(UInt32 nChannels, bool interleaved) + { + mFormatID = kAudioFormatLinearPCM; +#if CA_PREFER_FIXED_POINT + mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); +#else + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); + else { + mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + if (wordSize == 0) + wordSize = (mBitsPerChannel + 7) / 8; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; + + void Print() const { + Print (stdout); + } + + void Print(FILE* file) const { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const { + char buf[256]; + fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); + } + + void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline + char buf[256]; + fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); + } + + char * AsString(char *buf, size_t bufsize) const; + + static void Print (const AudioStreamBasicDescription &inDesc) + { + CAStreamBasicDescription desc(inDesc); + desc.Print (); + } + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__ diff --git a/aurioTouch/iPublicUtility/CAXException.cpp b/aurioTouch/iPublicUtility/CAXException.cpp new file mode 100755 index 0000000..13648ba --- /dev/null +++ b/aurioTouch/iPublicUtility/CAXException.cpp @@ -0,0 +1,53 @@ +/* + + File: CAXException.cpp +Abstract: Helper class for excpetion handling + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + + +#include "CAXException.h" + +CAXException::WarningHandler CAXException::sWarningHandler = NULL; diff --git a/aurioTouch/iPublicUtility/CAXException.h b/aurioTouch/iPublicUtility/CAXException.h new file mode 100755 index 0000000..ddedcf0 --- /dev/null +++ b/aurioTouch/iPublicUtility/CAXException.h @@ -0,0 +1,216 @@ +/* + + File: CAXException.h +Abstract: Helper class for excpetion handling + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + + +#ifndef __CAXException_h__ +#define __CAXException_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif +#include "CADebugMacros.h" +#include +#include +#include + +class CAX4CCString { +public: + CAX4CCString(OSStatus error) { + // see if it appears to be a 4-char-code + char *str = mStr; + *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); + if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { + str[0] = str[5] = '\''; + str[6] = '\0'; + } else if (error > -200000 && error < 200000) + // no, format it as an integer + sprintf(str, "%d", (int)error); + else + sprintf(str, "0x%x", (int)error); + } + const char *get() const { return mStr; } + operator const char *() const { return mStr; } +private: + char mStr[16]; +}; + +// An extended exception class that includes the name of the failed operation +class CAXException { +public: + CAXException(const char *operation, OSStatus err) : + mError(err) + { + if (operation == NULL) + mOperation[0] = '\0'; + else if (strlen(operation) >= sizeof(mOperation)) { + memcpy(mOperation, operation, sizeof(mOperation) - 1); + mOperation[sizeof(mOperation) - 1] = '\0'; + } else + strcpy(mOperation, operation); + } + + char *FormatError(char *str) const + { + return FormatError(str, mError); + } + + char mOperation[256]; + const OSStatus mError; + + // ------------------------------------------------- + + typedef void (*WarningHandler)(const char *msg, OSStatus err); + + static char *FormatError(char *str, OSStatus error) + { + strcpy(str, CAX4CCString(error)); + return str; + } + + static void Warning(const char *s, OSStatus error) + { + if (sWarningHandler) + (*sWarningHandler)(s, error); + } + + static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } +private: + static WarningHandler sWarningHandler; +}; + +#if DEBUG || CoreAudio_Debug + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + DebugMessageN2("about to throw %s: %s", CAX4CCString(error).get(), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + DebugMessageN2("about to throw %s: %s", CAX4CCString(error).get(), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + DebugMessageN2("about to throw %s: %s", CAX4CCString(error).get(), #error);\ + STOP; \ + goto label; \ + } \ + } while (0) + + #define XAssert(assertion) \ + do { \ + if (!(assertion)) { \ + DebugMessageN1("error: failed assertion: %s", #assertion);\ + STOP; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + DebugMessageN2("error %s: %s", CAX4CCString(error).get(), #error);\ + STOP; \ + } \ + } while (0) + +#else + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + goto label; \ + } \ + } while (0) + + #define XAssert(assertion) \ + do { \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + /*OSStatus __err =*/ error; \ + } while (0) +#endif + +#define XThrow(error, operation) XThrowIf(true, error, operation) +#define XThrowIfErr(error) XThrowIfError(error, #error) + +#endif // __CAXException_h__ diff --git a/aurioTouch/icon.png b/aurioTouch/icon.png new file mode 100644 index 0000000..6d402a7 Binary files /dev/null and b/aurioTouch/icon.png differ diff --git a/aurioTouch/main.m b/aurioTouch/main.m new file mode 100755 index 0000000..693950a --- /dev/null +++ b/aurioTouch/main.m @@ -0,0 +1,58 @@ +/* + + File: main.m +Abstract: main file + Version: 1.21 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/iAdSuite.zip b/iAdSuite.zip index 2ed73cf..3903c71 100644 Binary files a/iAdSuite.zip and b/iAdSuite.zip differ diff --git a/iAdSuite/BasicBanner/BasicBanner.xcodeproj/project.pbxproj b/iAdSuite/BasicBanner/BasicBanner.xcodeproj/project.pbxproj index 64179e0..c33ee4f 100644 --- a/iAdSuite/BasicBanner/BasicBanner.xcodeproj/project.pbxproj +++ b/iAdSuite/BasicBanner/BasicBanner.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 631EA77F1402F8B1003FB021 /* TextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631EA77D1402F8B1003FB021 /* TextViewController.m */; }; 631EA81414032496003FB021 /* TextViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 631EA81614032496003FB021 /* TextViewController.xib */; }; 63A104391404674A007D2134 /* ipsums.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63A104371404674A007D2134 /* ipsums.plist */; }; + 63B6242515E84C1100D77C46 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 63B6242415E84C1100D77C46 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -35,6 +36,7 @@ 631EA77D1402F8B1003FB021 /* TextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextViewController.m; sourceTree = ""; }; 631EA81514032496003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TextViewController.xib; sourceTree = ""; }; 63A104381404674A007D2134 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/ipsums.plist; sourceTree = ""; }; + 63B6242415E84C1100D77C46 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Resources/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -96,6 +98,7 @@ 631EA7211402E7CF003FB021 /* Supporting Files */ = { isa = PBXGroup; children = ( + 63B6242415E84C1100D77C46 /* Default-568h@2x.png */, 63A104371404674A007D2134 /* ipsums.plist */, 631EA7221402E7CF003FB021 /* BasicBanner-Info.plist */, 631EA7231402E7CF003FB021 /* InfoPlist.strings */, @@ -131,7 +134,7 @@ 631EA70D1402E7CF003FB021 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 0450; }; buildConfigurationList = 631EA7101402E7CF003FB021 /* Build configuration list for PBXProject "BasicBanner" */; compatibilityVersion = "Xcode 3.2"; @@ -158,6 +161,7 @@ 631EA7251402E7CF003FB021 /* InfoPlist.strings in Resources */, 631EA81414032496003FB021 /* TextViewController.xib in Resources */, 63A104391404674A007D2134 /* ipsums.plist in Resources */, + 63B6242515E84C1100D77C46 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -210,6 +214,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -221,10 +226,19 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.2; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -236,15 +250,25 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.2; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; diff --git a/iAdSuite/BasicBanner/BasicBanner.xcodeproj/xcshareddata/xcschemes/BasicBanner.xcscheme b/iAdSuite/BasicBanner/BasicBanner.xcodeproj/xcshareddata/xcschemes/BasicBanner.xcscheme index c1ef53b..627c1b0 100644 --- a/iAdSuite/BasicBanner/BasicBanner.xcodeproj/xcshareddata/xcschemes/BasicBanner.xcscheme +++ b/iAdSuite/BasicBanner/BasicBanner.xcodeproj/xcshareddata/xcschemes/BasicBanner.xcscheme @@ -1,5 +1,6 @@ @@ -39,11 +40,12 @@ diff --git a/iAdSuite/BasicBanner/BasicBanner/AppDelegate.h b/iAdSuite/BasicBanner/BasicBanner/AppDelegate.h index 7caa518..4dcb6a9 100644 --- a/iAdSuite/BasicBanner/BasicBanner/AppDelegate.h +++ b/iAdSuite/BasicBanner/BasicBanner/AppDelegate.h @@ -1,47 +1,49 @@ -/* File: AppDelegate.h */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: AppDelegate.h +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import diff --git a/iAdSuite/BasicBanner/BasicBanner/AppDelegate.m b/iAdSuite/BasicBanner/BasicBanner/AppDelegate.m index 772f884..c2d94e4 100644 --- a/iAdSuite/BasicBanner/BasicBanner/AppDelegate.m +++ b/iAdSuite/BasicBanner/BasicBanner/AppDelegate.m @@ -1,68 +1,68 @@ -/* File: AppDelegate.m */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: AppDelegate.m +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "AppDelegate.h" #import "TextViewController.h" @implementation AppDelegate -@synthesize window = _window; - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; - NSData *tmp = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; - NSDictionary *_data = [NSPropertyListSerialization propertyListWithData:tmp options:NSPropertyListImmutable format:nil error:nil]; + NSData *ipsumData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; + NSDictionary *ipsums = [NSPropertyListSerialization propertyListWithData:ipsumData options:NSPropertyListImmutable format:nil error:nil]; - TextViewController *tvc = [[TextViewController alloc] init]; - tvc.title = NSLocalizedString(@"Original", @"Original"); - tvc.text = [_data objectForKey:@"Original"]; + TextViewController *textViewController = [[TextViewController alloc] init]; + textViewController.title = NSLocalizedString(@"Original", @"Original"); + textViewController.text = ipsums[@"Original"]; - self.window.rootViewController = tvc; + self.window.rootViewController = textViewController; [self.window makeKeyAndVisible]; return YES; diff --git a/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Info.plist b/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Info.plist index 71a8ea6..ab1633f 100644 --- a/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Info.plist +++ b/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Info.plist @@ -19,23 +19,23 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 2.1 CFBundleSignature ???? CFBundleVersion - 1.0 + 2.1 LSRequiresIPhoneOS + UIRequiredDeviceCapabilities + + armv7 + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIRequiredDeviceCapabilities - - armv7 - UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait diff --git a/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Prefix.pch b/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Prefix.pch index 21a1f0d..fe6011c 100644 --- a/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Prefix.pch +++ b/iAdSuite/BasicBanner/BasicBanner/BasicBanner-Prefix.pch @@ -4,10 +4,10 @@ #import -#ifndef __IPHONE_4_2 -#warning "This project uses features only available in iOS SDK 4.2 and later." -#elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_2 -#error "This project requires features only available in iOS 4.2 and later." +#ifndef __IPHONE_6_0 +#warning "This project uses features only available in iOS SDK 6.0 and later." +#elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 +#error "This project requires features only available in iOS 5.0 and later." #endif #ifdef __OBJC__ diff --git a/iAdSuite/BasicBanner/BasicBanner/TextViewController.h b/iAdSuite/BasicBanner/BasicBanner/TextViewController.h index f8b624d..29b28e6 100644 --- a/iAdSuite/BasicBanner/BasicBanner/TextViewController.h +++ b/iAdSuite/BasicBanner/BasicBanner/TextViewController.h @@ -1,56 +1,55 @@ -/* File: TextViewController.h */ -/* Abstract: A simple view controller that manages a content view and an ADBannerView */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: TextViewController.h +Abstract: A simple view controller that manages a content view and an ADBannerView + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import #import @interface TextViewController : UIViewController -@property(nonatomic, strong) IBOutlet UIView *contentView; -@property(nonatomic, strong) IBOutlet UITextView *textView; -@property(nonatomic, strong) IBOutlet UILabel *timerLabel; -@property(nonatomic, copy) NSString *text; +@property (nonatomic, copy) NSString *text; @end diff --git a/iAdSuite/BasicBanner/BasicBanner/TextViewController.m b/iAdSuite/BasicBanner/BasicBanner/TextViewController.m index badf9f2..66172a1 100644 --- a/iAdSuite/BasicBanner/BasicBanner/TextViewController.m +++ b/iAdSuite/BasicBanner/BasicBanner/TextViewController.m @@ -1,90 +1,92 @@ -/* File: TextViewController.m */ -/* Abstract: A simple view controller that manages a content view and an ADBannerView */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: TextViewController.m +Abstract: A simple view controller that manages a content view and an ADBannerView + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "TextViewController.h" -@implementation TextViewController -{ +@interface TextViewController () + +@property (nonatomic, strong) IBOutlet UIView *contentView; +@property (nonatomic, strong) IBOutlet UITextView *textView; +@property (nonatomic, strong) IBOutlet UILabel *timerLabel; + +@end + +@implementation TextViewController { ADBannerView *_bannerView; NSTimer *_timer; CFTimeInterval _ticks; } -@synthesize contentView = _contentView; -@synthesize textView = _textView; -@synthesize timerLabel = _timerLabel; -@synthesize text = _text; - -- (id)init +- (instancetype)init { self = [super initWithNibName:@"TextViewController" bundle:nil]; if (self) { - _bannerView = [[ADBannerView alloc] init]; + // On iOS 6 ADBannerView introduces a new initializer, use it when available. + if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) { + _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner]; + } else { + _bannerView = [[ADBannerView alloc] init]; + } _bannerView.delegate = self; - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; } return self; } -- (void)dealloc -{ - [_timer invalidate]; - // When running on iOS 5.0 and later, ADBannerView's delegate property acts as a weak reference, making this unnecessary. - // However since this sample supports iOS 4.2 and later, we do this here to ensure correct behavior on all systems. - _bannerView.delegate = nil; -} - - (void)layoutAnimated:(BOOL)animated { - if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { + // As of iOS 6.0, the banner will automatically resize itself based on its width. + // To support iOS 5.0 however, we continue to set the currentContentSizeIdentifier appropriately. + CGRect contentFrame = self.view.bounds; + if (contentFrame.size.width < contentFrame.size.height) { _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; } else { _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; } - CGRect contentFrame = self.view.bounds; CGRect bannerFrame = _bannerView.frame; if (_bannerView.bannerLoaded) { contentFrame.size.height -= _bannerView.frame.size.height; @@ -106,6 +108,19 @@ - (void)setText:(NSString *)text self.textView.text = text; } +- (void)startTimer +{ + if (_timer == nil) { + _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; + } +} + +- (void)stopTimer +{ + [_timer invalidate]; + _timer = nil; +} + - (void)timerTick:(NSTimer *)timer { // Timers are not guaranteed to tick at the nominal rate specified, so this isn't technically accurate. @@ -124,32 +139,34 @@ - (void)viewDidLoad self.textView.text = self.text; } -- (void)viewDidUnload +- (void)viewDidAppear:(BOOL)animated { - [super viewDidUnload]; - self.contentView = nil; - self.textView = nil; - self.timerLabel = nil; + [super viewDidAppear:animated]; + [self layoutAnimated:NO]; + [self startTimer]; } -- (void)viewDidAppear:(BOOL)animated +- (void)viewDidDisappear:(BOOL)animated { - [self layoutAnimated:NO]; + [super viewDidDisappear:animated]; + [self stopTimer]; } +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } +#endif -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +- (NSUInteger)supportedInterfaceOrientations { - if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; - } else { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; - } - [self layoutAnimated:duration > 0.0]; + return UIInterfaceOrientationMaskAll; +} + +- (void)viewDidLayoutSubviews +{ + [self layoutAnimated:[UIView areAnimationsEnabled]]; } - (void)bannerViewDidLoadAd:(ADBannerView *)banner @@ -164,14 +181,13 @@ - (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError * - (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave { - [_timer invalidate]; - _timer = nil; + [self stopTimer]; return YES; } - (void)bannerViewActionDidFinish:(ADBannerView *)banner { - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; + [self startTimer]; } @end diff --git a/iAdSuite/BasicBanner/BasicBanner/main.m b/iAdSuite/BasicBanner/BasicBanner/main.m index 1d0d001..5ee99f7 100644 --- a/iAdSuite/BasicBanner/BasicBanner/main.m +++ b/iAdSuite/BasicBanner/BasicBanner/main.m @@ -1,47 +1,49 @@ -/* File: main.m */ -/* Abstract: Main entry point */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: main.m +Abstract: Main entry point + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import diff --git a/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/project.pbxproj b/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/project.pbxproj index 4dd5052..b9203fc 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/project.pbxproj +++ b/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 631EA81414032496003FB021 /* TextViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 631EA81614032496003FB021 /* TextViewController.xib */; }; 631FFC8B1404819700E94C63 /* BannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631FFC8A1404819700E94C63 /* BannerViewController.m */; }; 63A104391404674A007D2134 /* ipsums.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63A104371404674A007D2134 /* ipsums.plist */; }; + 63B6242815E84CC600D77C46 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 63B6242715E84CC600D77C46 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -38,6 +39,7 @@ 631FFC891404819700E94C63 /* BannerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BannerViewController.h; sourceTree = ""; }; 631FFC8A1404819700E94C63 /* BannerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BannerViewController.m; sourceTree = ""; }; 63A104381404674A007D2134 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/ipsums.plist; sourceTree = ""; }; + 63B6242715E84CC600D77C46 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Resources/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -101,6 +103,7 @@ 631EA7211402E7CF003FB021 /* Supporting Files */ = { isa = PBXGroup; children = ( + 63B6242715E84CC600D77C46 /* Default-568h@2x.png */, 63A104371404674A007D2134 /* ipsums.plist */, 631EA7221402E7CF003FB021 /* ContainerBanner-Info.plist */, 631EA7231402E7CF003FB021 /* InfoPlist.strings */, @@ -163,6 +166,7 @@ 631EA7251402E7CF003FB021 /* InfoPlist.strings in Resources */, 631EA81414032496003FB021 /* TextViewController.xib in Resources */, 63A104391404674A007D2134 /* ipsums.plist in Resources */, + 63B6242815E84CC600D77C46 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -216,6 +220,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -227,10 +232,19 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -242,15 +256,25 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; diff --git a/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/xcshareddata/xcschemes/ContainerBanner.xcscheme b/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/xcshareddata/xcschemes/ContainerBanner.xcscheme index 1654815..013d3a3 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/xcshareddata/xcschemes/ContainerBanner.xcscheme +++ b/iAdSuite/ContainerBanner/ContainerBanner.xcodeproj/xcshareddata/xcschemes/ContainerBanner.xcscheme @@ -1,5 +1,6 @@ @@ -39,11 +40,12 @@ diff --git a/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.h b/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.h index 7caa518..4dcb6a9 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.h +++ b/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.h @@ -1,47 +1,49 @@ -/* File: AppDelegate.h */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: AppDelegate.h +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import diff --git a/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.m b/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.m index ec58954..3e2d647 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.m +++ b/iAdSuite/ContainerBanner/ContainerBanner/AppDelegate.m @@ -1,72 +1,71 @@ -/* File: AppDelegate.m */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: AppDelegate.m +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "AppDelegate.h" #import "TextViewController.h" #import "BannerViewController.h" -@implementation AppDelegate -{ +@implementation AppDelegate { BannerViewController *_bannerViewController; } -@synthesize window = _window; - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; - NSData *tmp = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; - NSDictionary *_data = [NSPropertyListSerialization propertyListWithData:tmp options:NSPropertyListImmutable format:nil error:nil]; + NSData *ipsumData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; + NSDictionary *ipsums = [NSPropertyListSerialization propertyListWithData:ipsumData options:NSPropertyListImmutable format:nil error:nil]; - TextViewController *tvc = [[TextViewController alloc] init]; - tvc.title = NSLocalizedString(@"Original", @"Original"); - tvc.text = [_data objectForKey:@"Original"]; + TextViewController *textViewController = [[TextViewController alloc] init]; + textViewController.title = NSLocalizedString(@"Original", @"Original"); + textViewController.text = ipsums[@"Original"]; - _bannerViewController = [[BannerViewController alloc] initWithContentViewController:tvc]; + _bannerViewController = [[BannerViewController alloc] initWithContentViewController:textViewController]; self.window.rootViewController = _bannerViewController; diff --git a/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.h b/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.h index 5cd7d21..f538bf7 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.h +++ b/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.h @@ -1,47 +1,49 @@ -/* File: BannerViewController.h */ -/* Abstract: A container view controller that manages an ADBannerView and a content view controller */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: BannerViewController.h +Abstract: A container view controller that manages an ADBannerView and a content view controller + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import #import @@ -49,8 +51,8 @@ extern NSString * const BannerViewActionWillBegin; extern NSString * const BannerViewActionDidFinish; -@interface BannerViewController : UIViewController +@interface BannerViewController : UIViewController -- (id)initWithContentViewController:(UIViewController *)contentController; +- (instancetype)initWithContentViewController:(UIViewController *)contentController; @end diff --git a/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.m b/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.m index 56b7133..0b89a9a 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.m +++ b/iAdSuite/ContainerBanner/ContainerBanner/BannerViewController.m @@ -1,64 +1,74 @@ -/* File: BannerViewController.m */ -/* Abstract: A container view controller that manages an ADBannerView and a content view controller */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: BannerViewController.m +Abstract: A container view controller that manages an ADBannerView and a content view controller + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "BannerViewController.h" NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin"; NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish"; -@implementation BannerViewController -{ +@interface BannerViewController () + +@end + +@implementation BannerViewController { ADBannerView *_bannerView; UIViewController *_contentController; } -- (id)initWithContentViewController:(UIViewController *)contentController +- (instancetype)initWithContentViewController:(UIViewController *)contentController { self = [super init]; if (self != nil) { - _bannerView = [[ADBannerView alloc] init]; + // On iOS 6 ADBannerView introduces a new initializer, use it when available. + if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) { + _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner]; + } else { + _bannerView = [[ADBannerView alloc] init]; + } _bannerView.delegate = self; _contentController = contentController; } @@ -75,27 +85,44 @@ - (void)loadView self.view = contentView; } -- (void)viewDidUnload +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - [super viewDidUnload]; + return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; } +#endif -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { - return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; + return [_contentController preferredInterfaceOrientationForPresentation]; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + return [_contentController supportedInterfaceOrientations]; } - (void)viewDidLayoutSubviews { - if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { + CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 + // If configured to support iOS <6.0, then we need to set the currentContentSizeIdentifier in order to resize the banner properly. + // This continues to work on iOS 6.0, so we won't need to do anything further to resize the banner. + if (contentFrame.size.width < contentFrame.size.height) { _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; } else { _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; } - CGRect contentFrame = self.view.bounds; - CGRect bannerFrame = _bannerView.frame; + bannerFrame = _bannerView.frame; +#else + // If configured to support iOS >= 6.0 only, then we want to avoid currentContentSizeIdentifier as it is deprecated. + // Fortunately all we need to do is ask the banner for a size that fits into the layout area we are using. + // At this point in this method contentFrame=self.view.bounds, so we'll use that size for the layout. + bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size]; +#endif + if (_bannerView.bannerLoaded) { - contentFrame.size.height -= _bannerView.frame.size.height; + contentFrame.size.height -= bannerFrame.size.height; bannerFrame.origin.y = contentFrame.size.height; } else { bannerFrame.origin.y = contentFrame.size.height; diff --git a/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Info.plist b/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Info.plist index 71a8ea6..ab1633f 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Info.plist +++ b/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Info.plist @@ -19,23 +19,23 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 2.1 CFBundleSignature ???? CFBundleVersion - 1.0 + 2.1 LSRequiresIPhoneOS + UIRequiredDeviceCapabilities + + armv7 + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIRequiredDeviceCapabilities - - armv7 - UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait diff --git a/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Prefix.pch b/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Prefix.pch index 2901f50..5788422 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Prefix.pch +++ b/iAdSuite/ContainerBanner/ContainerBanner/ContainerBanner-Prefix.pch @@ -4,8 +4,8 @@ #import -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." +#ifndef __IPHONE_6_0 +#warning "This project uses features only available in iOS SDK 6.0 and later." #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 #error "This project requires features only available in iOS 5.0 and later." #endif diff --git a/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.h b/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.h index 9302fd6..bf1b148 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.h +++ b/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.h @@ -1,54 +1,54 @@ -/* File: TextViewController.h */ -/* Abstract: A simple view controller that manages a content view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: TextViewController.h +Abstract: A simple view controller that manages a content view + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import @interface TextViewController : UIViewController -@property (nonatomic, strong) IBOutlet UITextView *textView; -@property(nonatomic, strong) IBOutlet UILabel *timerLabel; @property (nonatomic, copy) NSString *text; @end diff --git a/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.m b/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.m index 0cd5002..aa99599 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.m +++ b/iAdSuite/ContainerBanner/ContainerBanner/TextViewController.m @@ -1,75 +1,77 @@ -/* File: TextViewController.m */ -/* Abstract: A simple view controller that manages a content view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: TextViewController.m +Abstract: A simple view controller that manages a content view + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "TextViewController.h" #import "BannerViewController.h" -@implementation TextViewController -{ +@interface TextViewController () + +@property (nonatomic, strong) IBOutlet UITextView *textView; +@property (nonatomic, strong) IBOutlet UILabel *timerLabel; + +@end + +@implementation TextViewController { NSTimer *_timer; CFTimeInterval _ticks; } -@synthesize textView = _textView; -@synthesize timerLabel = _timerLabel; -@synthesize text = _text; - -- (id)init +- (instancetype)init { self = [super initWithNibName:@"TextViewController" bundle:nil]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willBeginBannerViewActionNotification:) name:BannerViewActionWillBegin object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishBannerViewActionNotification:) name:BannerViewActionDidFinish object:nil]; - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; } return self; } - (void)dealloc { - [_timer invalidate]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } @@ -79,6 +81,19 @@ - (void)setText:(NSString *)text self.textView.text = text; } +- (void)startTimer +{ + if (_timer == nil) { + _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; + } +} + +- (void)stopTimer +{ + [_timer invalidate]; + _timer = nil; +} + - (void)timerTick:(NSTimer *)timer { // Timers are not guaranteed to tick at the nominal rate specified, so this isn't technically accurate. @@ -96,26 +111,38 @@ - (void)viewDidLoad self.textView.text = self.text; } -- (void)viewDidUnload +- (void)viewDidAppear:(BOOL)animated { - [super viewDidUnload]; - self.textView = nil; - self.timerLabel = nil; + [super viewDidAppear:animated]; + [self startTimer]; } +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + [self stopTimer]; +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } +#endif + +- (NSUInteger)supportedInterfaceOrientations +{ + return UIInterfaceOrientationMaskAll; +} - (void)willBeginBannerViewActionNotification:(NSNotification *)notification { - [_timer invalidate]; + [self stopTimer]; } - (void)didFinishBannerViewActionNotification:(NSNotification *)notification { - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; + [self startTimer]; } @end diff --git a/iAdSuite/ContainerBanner/ContainerBanner/main.m b/iAdSuite/ContainerBanner/ContainerBanner/main.m index 1d0d001..5ee99f7 100644 --- a/iAdSuite/ContainerBanner/ContainerBanner/main.m +++ b/iAdSuite/ContainerBanner/ContainerBanner/main.m @@ -1,47 +1,49 @@ -/* File: main.m */ -/* Abstract: Main entry point */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: main.m +Abstract: Main entry point + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner.xcodeproj/project.pbxproj b/iAdSuite/MediumRectBanner/MediumRectBanner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..35234df --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner.xcodeproj/project.pbxproj @@ -0,0 +1,309 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 6390749715C3207600B1754D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6390749615C3207600B1754D /* UIKit.framework */; }; + 6390749915C3207600B1754D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6390749815C3207600B1754D /* Foundation.framework */; }; + 6390749B15C3207600B1754D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6390749A15C3207600B1754D /* CoreGraphics.framework */; }; + 639074A115C3207600B1754D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6390749F15C3207600B1754D /* InfoPlist.strings */; }; + 639074A315C3207600B1754D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 639074A215C3207600B1754D /* main.m */; }; + 639074A715C3207600B1754D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 639074A615C3207600B1754D /* AppDelegate.m */; }; + 639074AA15C3207600B1754D /* CollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 639074A915C3207600B1754D /* CollectionViewController.m */; }; + 639074AD15C3207600B1754D /* CollectionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639074AB15C3207600B1754D /* CollectionViewController.xib */; }; + 639074B415C320B900B1754D /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 639074B315C320B900B1754D /* iAd.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6390749215C3207600B1754D /* MediumRectBanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MediumRectBanner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6390749615C3207600B1754D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 6390749815C3207600B1754D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 6390749A15C3207600B1754D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 6390749E15C3207600B1754D /* MediumRectBanner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MediumRectBanner-Info.plist"; sourceTree = ""; }; + 639074A015C3207600B1754D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 639074A215C3207600B1754D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 639074A415C3207600B1754D /* MediumRectBanner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MediumRectBanner-Prefix.pch"; sourceTree = ""; }; + 639074A515C3207600B1754D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 639074A615C3207600B1754D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 639074A815C3207600B1754D /* CollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CollectionViewController.h; sourceTree = ""; }; + 639074A915C3207600B1754D /* CollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CollectionViewController.m; sourceTree = ""; }; + 639074AC15C3207600B1754D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CollectionViewController.xib; sourceTree = ""; }; + 639074B315C320B900B1754D /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6390748F15C3207600B1754D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 639074B415C320B900B1754D /* iAd.framework in Frameworks */, + 6390749715C3207600B1754D /* UIKit.framework in Frameworks */, + 6390749915C3207600B1754D /* Foundation.framework in Frameworks */, + 6390749B15C3207600B1754D /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6390748715C3207600B1754D = { + isa = PBXGroup; + children = ( + 6390749C15C3207600B1754D /* MediumRectBanner */, + 6390749515C3207600B1754D /* Frameworks */, + 6390749315C3207600B1754D /* Products */, + ); + sourceTree = ""; + }; + 6390749315C3207600B1754D /* Products */ = { + isa = PBXGroup; + children = ( + 6390749215C3207600B1754D /* MediumRectBanner.app */, + ); + name = Products; + sourceTree = ""; + }; + 6390749515C3207600B1754D /* Frameworks */ = { + isa = PBXGroup; + children = ( + 639074B315C320B900B1754D /* iAd.framework */, + 6390749615C3207600B1754D /* UIKit.framework */, + 6390749815C3207600B1754D /* Foundation.framework */, + 6390749A15C3207600B1754D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6390749C15C3207600B1754D /* MediumRectBanner */ = { + isa = PBXGroup; + children = ( + 639074A515C3207600B1754D /* AppDelegate.h */, + 639074A615C3207600B1754D /* AppDelegate.m */, + 639074A815C3207600B1754D /* CollectionViewController.h */, + 639074A915C3207600B1754D /* CollectionViewController.m */, + 639074AB15C3207600B1754D /* CollectionViewController.xib */, + 6390749D15C3207600B1754D /* Supporting Files */, + ); + path = MediumRectBanner; + sourceTree = ""; + }; + 6390749D15C3207600B1754D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6390749E15C3207600B1754D /* MediumRectBanner-Info.plist */, + 6390749F15C3207600B1754D /* InfoPlist.strings */, + 639074A215C3207600B1754D /* main.m */, + 639074A415C3207600B1754D /* MediumRectBanner-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6390749115C3207600B1754D /* MediumRectBanner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 639074B015C3207600B1754D /* Build configuration list for PBXNativeTarget "MediumRectBanner" */; + buildPhases = ( + 6390748E15C3207600B1754D /* Sources */, + 6390748F15C3207600B1754D /* Frameworks */, + 6390749015C3207600B1754D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MediumRectBanner; + productName = MediumRectBanner; + productReference = 6390749215C3207600B1754D /* MediumRectBanner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6390748915C3207600B1754D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = Apple; + }; + buildConfigurationList = 6390748C15C3207600B1754D /* Build configuration list for PBXProject "MediumRectBanner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 6390748715C3207600B1754D; + productRefGroup = 6390749315C3207600B1754D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6390749115C3207600B1754D /* MediumRectBanner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6390749015C3207600B1754D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 639074A115C3207600B1754D /* InfoPlist.strings in Resources */, + 639074AD15C3207600B1754D /* CollectionViewController.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6390748E15C3207600B1754D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 639074A315C3207600B1754D /* main.m in Sources */, + 639074A715C3207600B1754D /* AppDelegate.m in Sources */, + 639074AA15C3207600B1754D /* CollectionViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6390749F15C3207600B1754D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 639074A015C3207600B1754D /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 639074AB15C3207600B1754D /* CollectionViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 639074AC15C3207600B1754D /* en */, + ); + name = CollectionViewController.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 639074AE15C3207600B1754D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + 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_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Debug; + }; + 639074AF15C3207600B1754D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = 2; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 639074B115C3207600B1754D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MediumRectBanner/MediumRectBanner-Prefix.pch"; + INFOPLIST_FILE = "MediumRectBanner/MediumRectBanner-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 639074B215C3207600B1754D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MediumRectBanner/MediumRectBanner-Prefix.pch"; + INFOPLIST_FILE = "MediumRectBanner/MediumRectBanner-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6390748C15C3207600B1754D /* Build configuration list for PBXProject "MediumRectBanner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 639074AE15C3207600B1754D /* Debug */, + 639074AF15C3207600B1754D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 639074B015C3207600B1754D /* Build configuration list for PBXNativeTarget "MediumRectBanner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 639074B115C3207600B1754D /* Debug */, + 639074B215C3207600B1754D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6390748915C3207600B1754D /* Project object */; +} diff --git a/iAdSuite/NavigationBanner/NavigationBanner.xcodeproj/xcshareddata/xcschemes/NavigationBanner.xcscheme b/iAdSuite/MediumRectBanner/MediumRectBanner.xcodeproj/xcshareddata/xcschemes/MediumRectBanner.xcscheme similarity index 68% rename from iAdSuite/NavigationBanner/NavigationBanner.xcodeproj/xcshareddata/xcschemes/NavigationBanner.xcscheme rename to iAdSuite/MediumRectBanner/MediumRectBanner.xcodeproj/xcshareddata/xcschemes/MediumRectBanner.xcscheme index e22c0f7..eb5cd56 100644 --- a/iAdSuite/NavigationBanner/NavigationBanner.xcodeproj/xcshareddata/xcschemes/NavigationBanner.xcscheme +++ b/iAdSuite/MediumRectBanner/MediumRectBanner.xcodeproj/xcshareddata/xcschemes/MediumRectBanner.xcscheme @@ -1,5 +1,6 @@ + BlueprintIdentifier = "6390749115C3207600B1754D" + BuildableName = "MediumRectBanner.app" + BlueprintName = "MediumRectBanner" + ReferencedContainer = "container:MediumRectBanner.xcodeproj"> @@ -31,28 +32,29 @@ + BlueprintIdentifier = "6390749115C3207600B1754D" + BuildableName = "MediumRectBanner.app" + BlueprintName = "MediumRectBanner" + ReferencedContainer = "container:MediumRectBanner.xcodeproj"> + BlueprintIdentifier = "6390749115C3207600B1754D" + BuildableName = "MediumRectBanner.app" + BlueprintName = "MediumRectBanner" + ReferencedContainer = "container:MediumRectBanner.xcodeproj"> @@ -67,10 +69,10 @@ + BlueprintIdentifier = "6390749115C3207600B1754D" + BuildableName = "MediumRectBanner.app" + BlueprintName = "MediumRectBanner" + ReferencedContainer = "container:MediumRectBanner.xcodeproj"> diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/AppDelegate.h b/iAdSuite/MediumRectBanner/MediumRectBanner/AppDelegate.h new file mode 100644 index 0000000..1693f46 --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/AppDelegate.h @@ -0,0 +1,56 @@ +/* + File: AppDelegate.h +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class CollectionViewController; + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/AppDelegate.m b/iAdSuite/MediumRectBanner/MediumRectBanner/AppDelegate.m new file mode 100644 index 0000000..3b53bfa --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/AppDelegate.m @@ -0,0 +1,66 @@ +/* + File: AppDelegate.m +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "CollectionViewController.h" + +@implementation AppDelegate { + CollectionViewController *_viewController; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.backgroundColor = [UIColor whiteColor]; + + _viewController = [[CollectionViewController alloc] initWithNibName:@"CollectionViewController" bundle:nil]; + self.window.rootViewController = _viewController; + [self.window makeKeyAndVisible]; + return YES; +} + +@end diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/CollectionViewController.h b/iAdSuite/MediumRectBanner/MediumRectBanner/CollectionViewController.h new file mode 100644 index 0000000..33ab5a7 --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/CollectionViewController.h @@ -0,0 +1,52 @@ +/* + File: CollectionViewController.h + Abstract: A simple view controller that manages a collection view controller and a medium rect ADBannerView + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface CollectionViewController : UICollectionViewController + +@end diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/CollectionViewController.m b/iAdSuite/MediumRectBanner/MediumRectBanner/CollectionViewController.m new file mode 100644 index 0000000..a7071e1 --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/CollectionViewController.m @@ -0,0 +1,199 @@ +/* + File: CollectionViewController.m + Abstract: A simple view controller that manages a collection view controller and a medium rect ADBannerView + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import +#import "CollectionViewController.h" + +@interface ImageViewCell : UICollectionViewCell + +@property (nonatomic, readonly) UIImageView *imageView; + +@end + +@implementation ImageViewCell + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self != nil) { + _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; + _imageView.contentMode = UIViewContentModeScaleAspectFit; + [self.contentView addSubview:_imageView]; + } + return self; +} + +@end + +@interface BannerViewCell : UICollectionViewCell + +@property (nonatomic, retain) ADBannerView *bannerView; + +@end + +@implementation BannerViewCell + +- (void)setBannerView:(ADBannerView *)bannerView +{ + [_bannerView removeFromSuperview]; + _bannerView = bannerView; + [self.contentView addSubview:_bannerView]; + _bannerView.center = CGPointMake(CGRectGetMidX(self.contentView.bounds), CGRectGetMidY(self.contentView.bounds)); +} + +@end + +@interface CollectionViewController () + +@end + +@implementation CollectionViewController { + ADBannerView *_banner; + // We only want to insert/delete our banner if we are changing from Loaded to Non-loaded and vice versa, so we use this + // ivar to track that state. If this wasn't a concern, we wouldn't need this ivar at all. + BOOL _bannerWasLoaded; +} + +- (void)viewDidLoad +{ + _banner = [[ADBannerView alloc] initWithAdType:ADAdTypeMediumRectangle]; + _banner.delegate = self; + [self.collectionView registerClass:[ImageViewCell class] forCellWithReuseIdentifier:@"ImageView"]; + [self.collectionView registerClass:[BannerViewCell class] forCellWithReuseIdentifier:@"BannerView"]; +} + +#pragma mark - UICollectionViewDataSource + +#define kBaseNumberOfItems 30 +#define kNumberOfItemsWithBanners 33 + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + // We only have 1 banner, but we display it in one of 3 locations, so if the banner is loaded, we add 3 more items. + return _banner.bannerLoaded ? kNumberOfItemsWithBanners : kBaseNumberOfItems; +} + +- (UIImage *)makeArt:(NSInteger)index +{ + static UIImage *art[kBaseNumberOfItems]; + if (art[index] == nil) { + UIGraphicsBeginImageContextWithOptions(CGSizeMake(300.0, 300.0), YES, 0.0); + CGContextRef context = UIGraphicsGetCurrentContext(); + [[UIColor redColor] setFill]; + [[UIColor blueColor] setStroke]; + CGPoint center = CGPointMake(150.0, 150.0); + CGContextMoveToPoint(context, center.x, center.y + 120.0); + NSInteger numPoints = index * 2 + 3; + for(int i = 1; i < numPoints; ++i) + { + CGFloat x = 120.0 * sinf(i * (numPoints - 1) * M_PI / numPoints); + CGFloat y = 120.0 * cosf(i * (numPoints - 1) * M_PI / numPoints); + CGContextAddLineToPoint(context, center.x + x, center.y + y); + } + CGContextClosePath(context); + CGContextDrawPath(context, kCGPathEOFillStroke); + art[index] = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + } + return art[index]; +} + +#define kBannerLocation1 5 +#define kBannerLocation2 16 +#define kBannerLocation3 27 + +- (BOOL)isBannerItem:(NSIndexPath *)indexPath +{ + return (indexPath.item == kBannerLocation1) || (indexPath.item == kBannerLocation2) || (indexPath.item == kBannerLocation3); +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + UICollectionViewCell *cell; + if (_banner.bannerLoaded && [self isBannerItem:indexPath]) { + BannerViewCell *bannerCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"BannerView" forIndexPath:indexPath]; + bannerCell.bannerView = _banner; + cell = bannerCell; + } else { + ImageViewCell *imageCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ImageView" forIndexPath:indexPath]; + NSInteger index = indexPath.item; + if (index > kBannerLocation3) { + index -= 3; + } else if (index > kBannerLocation2) { + index -= 2; + } else if (index > kBannerLocation1) { + index -= 1; + } + imageCell.imageView.image = [self makeArt:index]; + cell = imageCell; + } + return cell; +} + +#pragma mark - ADBannerViewDelegate + +- (void)bannerViewDidLoadAd:(ADBannerView *)banner +{ + if (!_bannerWasLoaded) { + [self.collectionView performBatchUpdates:^{ + [self.collectionView insertItemsAtIndexPaths:@[ [NSIndexPath indexPathForItem:kBannerLocation1 inSection:0], [NSIndexPath indexPathForItem:kBannerLocation2 inSection:0], [NSIndexPath indexPathForItem:kBannerLocation3 inSection:0]]]; + } completion:nil]; + } + _bannerWasLoaded = YES; +} + +- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error +{ + if (_bannerWasLoaded) { + [self.collectionView performBatchUpdates:^{ + [self.collectionView deleteItemsAtIndexPaths:@[ [NSIndexPath indexPathForItem:kBannerLocation1 inSection:0], [NSIndexPath indexPathForItem:kBannerLocation2 inSection:0], [NSIndexPath indexPathForItem:kBannerLocation3 inSection:0]]]; + } completion:nil]; + } + _bannerWasLoaded = NO; +} + +@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/SplitViewBanner-Info.plist b/iAdSuite/MediumRectBanner/MediumRectBanner/MediumRectBanner-Info.plist similarity index 93% rename from iAdSuite/SplitViewBanner/SplitViewBanner/SplitViewBanner-Info.plist rename to iAdSuite/MediumRectBanner/MediumRectBanner/MediumRectBanner-Info.plist index 39a1ecd..2857df9 100644 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/SplitViewBanner-Info.plist +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/MediumRectBanner-Info.plist @@ -8,8 +8,6 @@ ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} - CFBundleIconFiles - CFBundleIdentifier com.yourcompany.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion @@ -19,13 +17,17 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 2.1 CFBundleSignature ???? CFBundleVersion - 1.0 + 2.1 LSRequiresIPhoneOS + UIRequiredDeviceCapabilities + + armv7 + UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait @@ -33,9 +35,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIRequiredDeviceCapabilities - - armv7 - diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/MediumRectBanner-Prefix.pch b/iAdSuite/MediumRectBanner/MediumRectBanner/MediumRectBanner-Prefix.pch new file mode 100644 index 0000000..d0e5a99 --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/MediumRectBanner-Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header for all source files of the 'MediumRectBanner' target in the 'MediumRectBanner' project +// + +#import + +#ifndef __IPHONE_6_0 +#warning "This project uses features only available in iOS SDK 6.0 and later." +#elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 +#error "This project requires features only available in iOS 6.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/en.lproj/CollectionViewController.xib b/iAdSuite/MediumRectBanner/MediumRectBanner/en.lproj/CollectionViewController.xib new file mode 100644 index 0000000..a410fcb --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/en.lproj/CollectionViewController.xib @@ -0,0 +1,175 @@ + + + + 1536 + 12A269 + 2838 + 1187 + 624.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1922 + + + IBProxyObject + IBUICollectionView + IBUICollectionViewFlowLayout + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + + {768, 1004} + + + + _NS:9 + YES + YES + IBIPadFramework + 0.0 + 0.0 + + + {300, 300} + 16 + 16 + + + + + + + + + view + + + + 16 + + + + dataSource + + + + 14 + + + + delegate + + + + 15 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + + 5 + + + + + + + CollectionViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 16 + + + + + CollectionViewController + UICollectionViewController + + IBProjectSource + ./Classes/CollectionViewController.h + + + + UICollectionViewController + UIViewController + + IBProjectSource + ./Classes/UICollectionViewController.h + + + + UICollectionViewFlowLayout + UICollectionViewLayout + + IBProjectSource + ./Classes/UICollectionViewFlowLayout.h + + + + UICollectionViewLayout + NSObject + + IBProjectSource + ./Classes/UICollectionViewLayout.h + + + + + 0 + IBIPadFramework + YES + 3 + YES + 1922 + + diff --git a/iAdSuite/NavigationBanner/NavigationBanner/en.lproj/InfoPlist.strings b/iAdSuite/MediumRectBanner/MediumRectBanner/en.lproj/InfoPlist.strings similarity index 100% rename from iAdSuite/NavigationBanner/NavigationBanner/en.lproj/InfoPlist.strings rename to iAdSuite/MediumRectBanner/MediumRectBanner/en.lproj/InfoPlist.strings diff --git a/iAdSuite/MediumRectBanner/MediumRectBanner/main.m b/iAdSuite/MediumRectBanner/MediumRectBanner/main.m new file mode 100644 index 0000000..1bf6484 --- /dev/null +++ b/iAdSuite/MediumRectBanner/MediumRectBanner/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: Main entry point + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +#import "AppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/iAdSuite/NavigationBanner/NavigationBanner.xcodeproj/project.pbxproj b/iAdSuite/NavigationBanner/NavigationBanner.xcodeproj/project.pbxproj deleted file mode 100644 index 9948355..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,303 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 631EA7CF14030B36003FB021 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631EA7CE14030B36003FB021 /* UIKit.framework */; }; - 631EA7D114030B36003FB021 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631EA7D014030B36003FB021 /* Foundation.framework */; }; - 631EA7D314030B36003FB021 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631EA7D214030B36003FB021 /* CoreGraphics.framework */; }; - 631EA7D914030B36003FB021 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 631EA7D714030B36003FB021 /* InfoPlist.strings */; }; - 631EA7DB14030B36003FB021 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 631EA7DA14030B36003FB021 /* main.m */; }; - 631EA7DF14030B36003FB021 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 631EA7DE14030B36003FB021 /* AppDelegate.m */; }; - 631EA7FE14031CEB003FB021 /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631EA7FD14031CEB003FB021 /* iAd.framework */; }; - 631EA80B14032398003FB021 /* TextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631EA80914032398003FB021 /* TextViewController.m */; }; - 631EA80F140323B3003FB021 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631EA80E140323B3003FB021 /* MasterViewController.m */; }; - 631EA81A140324AF003FB021 /* TextViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 631EA81C140324AF003FB021 /* TextViewController.xib */; }; - 631EA822140324C9003FB021 /* ipsums.plist in Resources */ = {isa = PBXBuildFile; fileRef = 631EA820140324C9003FB021 /* ipsums.plist */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 631EA7CA14030B36003FB021 /* NavigationBanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NavigationBanner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 631EA7CE14030B36003FB021 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 631EA7D014030B36003FB021 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 631EA7D214030B36003FB021 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 631EA7D614030B36003FB021 /* NavigationBanner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NavigationBanner-Info.plist"; sourceTree = ""; }; - 631EA7D814030B36003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 631EA7DA14030B36003FB021 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 631EA7DC14030B36003FB021 /* NavigationBanner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NavigationBanner-Prefix.pch"; sourceTree = ""; }; - 631EA7DD14030B36003FB021 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 631EA7DE14030B36003FB021 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 631EA7FD14031CEB003FB021 /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; - 631EA80814032398003FB021 /* TextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextViewController.h; sourceTree = ""; }; - 631EA80914032398003FB021 /* TextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextViewController.m; sourceTree = ""; }; - 631EA80D140323B3003FB021 /* MasterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; }; - 631EA80E140323B3003FB021 /* MasterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; }; - 631EA81B140324AF003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TextViewController.xib; sourceTree = ""; }; - 631EA821140324C9003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/ipsums.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 631EA7C714030B36003FB021 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 631EA7FE14031CEB003FB021 /* iAd.framework in Frameworks */, - 631EA7CF14030B36003FB021 /* UIKit.framework in Frameworks */, - 631EA7D114030B36003FB021 /* Foundation.framework in Frameworks */, - 631EA7D314030B36003FB021 /* CoreGraphics.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 631EA7BF14030B36003FB021 = { - isa = PBXGroup; - children = ( - 631EA7D414030B36003FB021 /* NavigationBanner */, - 631EA7CD14030B36003FB021 /* Frameworks */, - 631EA7CB14030B36003FB021 /* Products */, - ); - sourceTree = ""; - }; - 631EA7CB14030B36003FB021 /* Products */ = { - isa = PBXGroup; - children = ( - 631EA7CA14030B36003FB021 /* NavigationBanner.app */, - ); - name = Products; - sourceTree = ""; - }; - 631EA7CD14030B36003FB021 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 631EA7FD14031CEB003FB021 /* iAd.framework */, - 631EA7CE14030B36003FB021 /* UIKit.framework */, - 631EA7D014030B36003FB021 /* Foundation.framework */, - 631EA7D214030B36003FB021 /* CoreGraphics.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 631EA7D414030B36003FB021 /* NavigationBanner */ = { - isa = PBXGroup; - children = ( - 631EA7DD14030B36003FB021 /* AppDelegate.h */, - 631EA7DE14030B36003FB021 /* AppDelegate.m */, - 631EA80D140323B3003FB021 /* MasterViewController.h */, - 631EA80E140323B3003FB021 /* MasterViewController.m */, - 631EA80814032398003FB021 /* TextViewController.h */, - 631EA80914032398003FB021 /* TextViewController.m */, - 631EA81C140324AF003FB021 /* TextViewController.xib */, - 631EA7D514030B36003FB021 /* Supporting Files */, - ); - path = NavigationBanner; - sourceTree = ""; - }; - 631EA7D514030B36003FB021 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 631EA820140324C9003FB021 /* ipsums.plist */, - 631EA7D614030B36003FB021 /* NavigationBanner-Info.plist */, - 631EA7D714030B36003FB021 /* InfoPlist.strings */, - 631EA7DA14030B36003FB021 /* main.m */, - 631EA7DC14030B36003FB021 /* NavigationBanner-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 631EA7C914030B36003FB021 /* NavigationBanner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 631EA7EE14030B36003FB021 /* Build configuration list for PBXNativeTarget "NavigationBanner" */; - buildPhases = ( - 631EA7C614030B36003FB021 /* Sources */, - 631EA7C714030B36003FB021 /* Frameworks */, - 631EA7C814030B36003FB021 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = NavigationBanner; - productName = NavigationBanner; - productReference = 631EA7CA14030B36003FB021 /* NavigationBanner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 631EA7C114030B36003FB021 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0420; - }; - buildConfigurationList = 631EA7C414030B36003FB021 /* Build configuration list for PBXProject "NavigationBanner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 631EA7BF14030B36003FB021; - productRefGroup = 631EA7CB14030B36003FB021 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 631EA7C914030B36003FB021 /* NavigationBanner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 631EA7C814030B36003FB021 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 631EA7D914030B36003FB021 /* InfoPlist.strings in Resources */, - 631EA81A140324AF003FB021 /* TextViewController.xib in Resources */, - 631EA822140324C9003FB021 /* ipsums.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 631EA7C614030B36003FB021 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 631EA7DB14030B36003FB021 /* main.m in Sources */, - 631EA7DF14030B36003FB021 /* AppDelegate.m in Sources */, - 631EA80B14032398003FB021 /* TextViewController.m in Sources */, - 631EA80F140323B3003FB021 /* MasterViewController.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 631EA7D714030B36003FB021 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 631EA7D814030B36003FB021 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 631EA81C140324AF003FB021 /* TextViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - 631EA81B140324AF003FB021 /* en */, - ); - name = TextViewController.xib; - sourceTree = ""; - }; - 631EA820140324C9003FB021 /* ipsums.plist */ = { - isa = PBXVariantGroup; - children = ( - 631EA821140324C9003FB021 /* en */, - ); - name = ipsums.plist; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 631EA7EC14030B36003FB021 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CLANG_ENABLE_OBJC_ARC = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - 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_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.2; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 631EA7ED14030B36003FB021 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CLANG_ENABLE_OBJC_ARC = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.2; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 631EA7EF14030B36003FB021 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "NavigationBanner/NavigationBanner-Prefix.pch"; - INFOPLIST_FILE = "NavigationBanner/NavigationBanner-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - 631EA7F014030B36003FB021 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "NavigationBanner/NavigationBanner-Prefix.pch"; - INFOPLIST_FILE = "NavigationBanner/NavigationBanner-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 631EA7C414030B36003FB021 /* Build configuration list for PBXProject "NavigationBanner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 631EA7EC14030B36003FB021 /* Debug */, - 631EA7ED14030B36003FB021 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 631EA7EE14030B36003FB021 /* Build configuration list for PBXNativeTarget "NavigationBanner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 631EA7EF14030B36003FB021 /* Debug */, - 631EA7F014030B36003FB021 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; -/* End XCConfigurationList section */ - }; - rootObject = 631EA7C114030B36003FB021 /* Project object */; -} diff --git a/iAdSuite/NavigationBanner/NavigationBanner/AppDelegate.h b/iAdSuite/NavigationBanner/NavigationBanner/AppDelegate.h deleted file mode 100644 index 96b261d..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/AppDelegate.h +++ /dev/null @@ -1,63 +0,0 @@ -/* File: AppDelegate.h */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import -#import - -@protocol BannerViewContainer - -- (void)showBannerView:(ADBannerView *)bannerView animated:(BOOL)animated; -- (void)hideBannerView:(ADBannerView *)bannerView animated:(BOOL)animated; - -@end - -extern NSString * const BannerViewActionWillBegin; -extern NSString * const BannerViewActionDidFinish; - -@interface AppDelegate : UIResponder - -@property (nonatomic, strong) UIWindow *window; - -@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/AppDelegate.m b/iAdSuite/NavigationBanner/NavigationBanner/AppDelegate.m deleted file mode 100644 index 4b6ff2e..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/AppDelegate.m +++ /dev/null @@ -1,114 +0,0 @@ -/* File: AppDelegate.m */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "AppDelegate.h" - -#import "MasterViewController.h" - -NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin"; -NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish"; - -@implementation AppDelegate -{ - UINavigationController *_navigationController; - UIViewController *_currentController; - ADBannerView *_bannerView; -} - -@synthesize window = _window; - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - CGRect bounds = [[UIScreen mainScreen] bounds]; - self.window = [[UIWindow alloc] initWithFrame:bounds]; - self.window.backgroundColor = [UIColor whiteColor]; - - // The ADBannerView will fix up the given size, we just want to ensure it is created at a location off the bottom of the screen. - // This ensures that the first animation doesn't come in from the top of the screen. - _bannerView = [[ADBannerView alloc] initWithFrame:CGRectMake(0.0, bounds.size.height, 0.0, 0.0)]; - _bannerView.delegate = self; - - MasterViewController *masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStyleGrouped]; - _navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController]; - _navigationController.delegate = self; - - self.window.rootViewController = _navigationController; - [self.window makeKeyAndVisible]; - - _currentController = nil; // top most controller is not a banner container, so this starts out nil. - - return YES; -} - -- (void)bannerViewDidLoadAd:(ADBannerView *)banner -{ - [_currentController showBannerView:banner animated:YES]; -} - -- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error -{ - [_currentController hideBannerView:_bannerView animated:YES]; -} - -- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave -{ - [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self]; - return YES; -} - -- (void)bannerViewActionDidFinish:(ADBannerView *)banner -{ - [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self]; -} - -- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated -{ - _currentController = [viewController respondsToSelector:@selector(showBannerView:animated:)] ? (UIViewController *)viewController : nil; - if (_bannerView.bannerLoaded && (_currentController != nil)) { - [(UIViewController *)viewController showBannerView:_bannerView animated:NO]; - } -} - -@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/MasterViewController.h b/iAdSuite/NavigationBanner/NavigationBanner/MasterViewController.h deleted file mode 100644 index 93697b6..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/MasterViewController.h +++ /dev/null @@ -1,50 +0,0 @@ -/* File: MasterViewController.h */ -/* Abstract: A simple view controller that manages a table view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import - -@interface MasterViewController : UITableViewController - -@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/MasterViewController.m b/iAdSuite/NavigationBanner/NavigationBanner/MasterViewController.m deleted file mode 100644 index f841db4..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/MasterViewController.m +++ /dev/null @@ -1,108 +0,0 @@ -/* File: MasterViewController.m */ -/* Abstract: A simple view controller that manages a table view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "MasterViewController.h" -#import "TextViewController.h" - -@implementation MasterViewController -{ - NSDictionary *_data; - NSArray *_keys; -} - -- (id)initWithStyle:(UITableViewStyle)style -{ - self = [super initWithStyle:style]; - if (self) { - self.title = NSLocalizedString(@"Ipsum", @"Ipsum"); - - NSData *tmp = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; - _data = [NSPropertyListSerialization propertyListWithData:tmp options:NSPropertyListImmutable format:nil error:nil]; - _keys = [[_data allKeys] sortedArrayUsingSelector:@selector(compare:)]; - } - return self; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [_data count]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - static NSString *CellIdentifier = @"Cell"; - - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (cell == nil) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; - } - - // Configure the cell. - cell.textLabel.text = [_keys objectAtIndex:indexPath.row]; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.selectionStyle = UITableViewCellSelectionStyleBlue; - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - TextViewController *tvc = [[TextViewController alloc] init]; - tvc.title = NSLocalizedString([_keys objectAtIndex:indexPath.row], @"Original-Meaty-Vegan"); - tvc.text = [_data objectForKey:[_keys objectAtIndex:indexPath.row]]; - [self.navigationController pushViewController:tvc animated:YES]; -} - -@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/NavigationBanner-Prefix.pch b/iAdSuite/NavigationBanner/NavigationBanner/NavigationBanner-Prefix.pch deleted file mode 100644 index 4341e35..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/NavigationBanner-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header for all source files of the 'NavigationBanner' target in the 'NavigationBanner' project -// - -#import - -#ifndef __IPHONE_4_2 -#warning "This project uses features only available in iOS SDK 4.2 and later." -#elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_2 -#error "This project requires features only available in iOS 4.2 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/iAdSuite/NavigationBanner/NavigationBanner/TextViewController.h b/iAdSuite/NavigationBanner/NavigationBanner/TextViewController.h deleted file mode 100644 index 32fd27a..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/TextViewController.h +++ /dev/null @@ -1,57 +0,0 @@ -/* File: TextViewController.h */ -/* Abstract: A simple view controller that manages a content view and an ADBannerView */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import -#import -#import "AppDelegate.h" - -@interface TextViewController : UIViewController - -@property(nonatomic, strong) IBOutlet UIView *contentView; -@property(nonatomic, strong) IBOutlet UITextView *textView; -@property(nonatomic, strong) IBOutlet UILabel *timerLabel; -@property(nonatomic, copy) NSString *text; - -@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/TextViewController.m b/iAdSuite/NavigationBanner/NavigationBanner/TextViewController.m deleted file mode 100644 index c8d7453..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/TextViewController.m +++ /dev/null @@ -1,170 +0,0 @@ -/* File: TextViewController.m */ -/* Abstract: A simple view controller that manages a content view and an ADBannerView */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "TextViewController.h" - -@implementation TextViewController -{ - ADBannerView *_bannerView; - NSTimer *_timer; - CFTimeInterval _ticks; -} - -@synthesize contentView = _contentView; -@synthesize textView = _textView; -@synthesize timerLabel = _timerLabel; -@synthesize text = _text; - -- (id)init -{ - self = [super initWithNibName:@"TextViewController" bundle:nil]; - if (self) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willBeginBannerViewActionNotification:) name:BannerViewActionWillBegin object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishBannerViewActionNotification:) name:BannerViewActionDidFinish object:nil]; - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; - } - return self; -} - -- (void)dealloc -{ - [_timer invalidate]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)layoutAnimated:(BOOL)animated -{ - if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; - } else { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; - } - - CGRect contentFrame = self.view.bounds; - CGRect bannerFrame = _bannerView.frame; - if (_bannerView.bannerLoaded) { - contentFrame.size.height -= _bannerView.frame.size.height; - bannerFrame.origin.y = contentFrame.size.height; - } else { - bannerFrame.origin.y = contentFrame.size.height; - } - - [UIView animateWithDuration:animated ? 0.25 : 0.0 animations:^{ - _contentView.frame = contentFrame; - [_contentView layoutIfNeeded]; - _bannerView.frame = bannerFrame; - }]; -} - -- (void)setText:(NSString *)text -{ - _text = [text copy]; - self.textView.text = text; -} - -- (void)timerTick:(NSTimer *)timer -{ - // Timers are not guaranteed to tick at the nominal rate specified, so this isn't technically accurate. - // However, this is just an example to demonstrate how to stop some ongoing activity, so we can live with that inaccuracy. - _ticks += 0.1; - double seconds = fmod(_ticks, 60.0); - double minutes = fmod(trunc(_ticks / 60.0), 60.0); - double hours = trunc(_ticks / 3600.0); - self.timerLabel.text = [NSString stringWithFormat:@"%02.0f:%02.0f:%04.1f", hours, minutes, seconds]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - self.textView.text = self.text; -} - -- (void)viewDidUnload -{ - [super viewDidUnload]; - self.contentView = nil; - self.textView = nil; - self.timerLabel = nil; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [self layoutAnimated:NO]; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - [self layoutAnimated:duration > 0.0]; -} - -- (void)showBannerView:(ADBannerView *)bannerView animated:(BOOL)animated -{ - _bannerView = bannerView; - [self.view addSubview:_bannerView]; - [self layoutAnimated:animated]; -} - -- (void)hideBannerView:(ADBannerView *)bannerView animated:(BOOL)animated -{ - _bannerView = nil; - [self layoutAnimated:animated]; -} - -- (void)willBeginBannerViewActionNotification:(NSNotification *)notification -{ - [_timer invalidate]; -} - -- (void)didFinishBannerViewActionNotification:(NSNotification *)notification -{ - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; -} - -@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/en.lproj/TextViewController.xib b/iAdSuite/NavigationBanner/NavigationBanner/en.lproj/TextViewController.xib deleted file mode 100644 index d032750..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/en.lproj/TextViewController.xib +++ /dev/null @@ -1,275 +0,0 @@ - - - - 1280 - 11B26 - 1928 - 1138 - 566.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 924 - - - IBUITextView - IBUIView - IBUILabel - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 274 - - - - 274 - {{0, 49}, {320, 411}} - - - - _NS:625 - - 1 - MSAxIDEAA - - YES - YES - - - - IBCocoaTouchFramework - NO - NO - - - 2 - IBCocoaTouchFramework - - - 1 - 14 - - - Helvetica - 14 - 16 - - - - - 290 - {{20, 20}, {280, 21}} - - - - _NS:312 - NO - YES - 7 - NO - IBCocoaTouchFramework - 00:00:00.0 - - 1 - MCAwIDAAA - - - 1 - 10 - 1 - - 1 - 17 - - - Helvetica - 17 - 16 - - - - {320, 460} - - - - _NS:196 - - 3 - MQA - - 2 - - - IBCocoaTouchFramework - - - {{0, 20}, {320, 460}} - - - - - 3 - MQA - - - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - contentView - - - - 6 - - - - textView - - - - 10 - - - - timerLabel - - - - 11 - - - - - - 0 - - - - - - 1 - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - - - - - 5 - - - - - 8 - - - - - - - TextViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 11 - - - - - TextViewController - UIViewController - - UIView - UITextView - UILabel - - - - contentView - UIView - - - textView - UITextView - - - timerLabel - UILabel - - - - IBProjectSource - ./Classes/TextViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 924 - - diff --git a/iAdSuite/NavigationBanner/NavigationBanner/main.m b/iAdSuite/NavigationBanner/NavigationBanner/main.m deleted file mode 100644 index db4eda7..0000000 --- a/iAdSuite/NavigationBanner/NavigationBanner/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// NavigationBanner -// -// Created by David Duncan on 8/22/11. -// Copyright (c) 2011 __MyCompanyName__. All rights reserved. -// - -#import - -#import "AppDelegate.h" - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/iAdSuite/ReadMe.txt b/iAdSuite/ReadMe.txt index 3071328..67904e3 100644 --- a/iAdSuite/ReadMe.txt +++ b/iAdSuite/ReadMe.txt @@ -1,27 +1,38 @@ iAdSuite ========== -iAdSuite is a set of five samples demonstrating how to manage an ADBannerView in 4 common scenarios: An application with a single view controller (BasicBanner, ContainerBanner), an application that uses a UITabBarViewController (TabbedBanner), an application that uses a UINavigationViewController (NavigationBanner) and an application that uses a UISplitViewController (SplitViewBanner). +iAdSuite is a set of samples demonstrating how to manage an ADBannerView in many common scenarios, each scenario demonstrated in a particular sample application. -All of the samples use a simple view controller that display a read-only UITextView (managed by the TextViewController class) along with a label that shows a running timer. The ADBannerView is placed at the bottom of the view in all cases, and all orientations are supported by each sample. The BasicBanner and ContainerBanner are configured to support both iPhone and iPad idioms, the TabbedBanner and NavigationBanner to support only the iPhone idiom, and the SplitViewBanner to support only the iPad idiom. +BasicBanner + This application demonstrates the basics of how you might add a banner view to an application that dynamically adapts to the presence of an advertisement, as well as showing how to respond in a simple way to the standard delegate methods. -A note on banner management: -It is highly recommended that you create and share a single ADBannerView for use with all view controllers in your application. +ContainerBanner + By using view controller containment, this sample abstracts the setup demonstrated in BasicBanner to a custom container view controller (BannerViewController). This view controller manages hiding and showing the banner view at the appropriate time, and resizing its contained view controller. -If you need to support iOS 4, then you should do this by moving the banner between each view controller than you present, and keeping some central object (such as your Application Delegate) as the banner view's delegate and using the ADBannerViewDelegate protocol to further message the other view controllers. This technique is demonstrated in the TabbedBanner and NavigationBanner samples. +SplitNavigationBanner + Using the approach demonstrated in ContainerBanner, this sample demonstrates adding an ADBannerView to an application that is based on UINavigationController (iPhone) or UISplitViewController (iPad). This sample replaces the NavigationBanner and SplitViewBanner samples. + +TabbedBanner + When using a UITabBarController, the banner should appear above the tabs. This sample again builds upon the approach from ContainerBanner, modifying BannerViewController to allow for the existence of multiple instances that share the same ADBannerView. -By contrast, if you can require iOS 5, you can use View Controller contentment to create a custom container view controller that displays your ADBannerView. This container view controller than then be the delegate if the banner view and simply arranges its child view controller's view as necessary to make room for the banner. This technique is demonstrated in the ContainerBanner and SplitViewBanner samples. +MediumRectBanner + iOS 6 introduces a new banner size that is intended for use inline with your content. This sample demonstrates using the new MediumRect 300x250 sized banner in a simple image gallery type application. -The ContainerBanner and SplitViewBanner samples both require iOS 5.0 and later, while the other samples require iOS 4.2 and later. All samples are built against the iOS 5.0 SDK (the projects are configured use the Latest iOS SDK), require Xcode 4.2 and the LLVM 3.0 compiler, and use ARC for memory management. +In many of the samples the content is represented by a simple TextViewController view controller that displays some text in a read-only UITextView and runs a timer. The UITextView represents your application's content and the timer represents ongoing activity in your application that you will want to pause when the advertisement takes over the user interface. The MediumRectBanner sample uses a UICollectionView with image content instead, adding the banners as additional cells. + +The traditional banner (represented with the ADAdTypeBanner constant) is expected to be placed at or near the bottom of the screen and placed to consume the full width of the screen. New in iOS 6 is the Medium Rect sized banner (represented with the ADAdTypeMediumRectangle constant) which is intended to be placed inline with other content from your application. It is highly recommended that you create only a single instance of each type of banner that you use (so if you use both a banner and medium rect type, you would have at most 1 instance of each) and that you share these instances among the places in your UI that they are used. + +Except for the MediumRectBanner (which requires iOS 6) these samples require iOS 5.0 or later to run. Build Requirements -Xcode 4.2, iOS 5.0 SDK, LLVM Compiler 3.0, Automated Reference Counting (ARC). +Xcode 4.5, iOS 6.0 SDK, LLVM Compiler 4.1, Automated Reference Counting (ARC). Runtime Requirements -BasicBanner, TabbedBanned and NavigationBanner require iOS 4.2 and later. -ContainerBanner and SplitViewBanner require iOS 5.0 and later. +iOS 5.0 or later, except for MediumRectBanner which requires iOS 6.0. Changes from Previous Versions +2.1 - Updated for iOS 6.0, removed support for iOS versions prior to 5.0. + 2.0 - Updated for iOS 5.0, removed support for iOS 4.1 and below, added samples that use a custom container view controller to manage the ADBannerView, converted all samples to use ARC. 1.2 - Updated for iOS 4.2, changed deprecated content size identifiers, "AdBannerNavigation" sample now shares ad banners across view controllers. diff --git a/iAdSuite/Resources/Default-568h@2x.png b/iAdSuite/Resources/Default-568h@2x.png new file mode 100644 index 0000000..b18fe43 Binary files /dev/null and b/iAdSuite/Resources/Default-568h@2x.png differ diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner.xcodeproj/project.pbxproj b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner.xcodeproj/project.pbxproj similarity index 79% rename from iAdSuite/SplitViewBanner/SplitViewBanner.xcodeproj/project.pbxproj rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner.xcodeproj/project.pbxproj index 8b732f5..e8eae58 100644 --- a/iAdSuite/SplitViewBanner/SplitViewBanner.xcodeproj/project.pbxproj +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner.xcodeproj/project.pbxproj @@ -19,28 +19,30 @@ 631EA7701402E8B7003FB021 /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631EA76F1402E8B7003FB021 /* iAd.framework */; }; 631EA7741402EA96003FB021 /* BannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631EA7731402EA96003FB021 /* BannerViewController.m */; }; 631EA7771402F1C9003FB021 /* ipsums.plist in Resources */ = {isa = PBXBuildFile; fileRef = 631EA7751402F1C9003FB021 /* ipsums.plist */; }; + 63B6242B15E84CCE00D77C46 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 63B6242A15E84CCE00D77C46 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 631EA73C1402E87D003FB021 /* SplitViewBanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SplitViewBanner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 631EA73C1402E87D003FB021 /* SplitNavigationBanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SplitNavigationBanner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 631EA7401402E87D003FB021 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 631EA7421402E87D003FB021 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 631EA7441402E87D003FB021 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 631EA7481402E87D003FB021 /* SplitViewBanner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SplitViewBanner-Info.plist"; sourceTree = ""; }; + 631EA7481402E87D003FB021 /* SplitNavigationBanner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SplitNavigationBanner-Info.plist"; sourceTree = ""; }; 631EA74A1402E87D003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 631EA74C1402E87D003FB021 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 631EA74E1402E87D003FB021 /* SplitViewBanner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SplitViewBanner-Prefix.pch"; sourceTree = ""; }; + 631EA74E1402E87D003FB021 /* SplitNavigationBanner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SplitNavigationBanner-Prefix.pch"; sourceTree = ""; }; 631EA74F1402E87D003FB021 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 631EA7501402E87D003FB021 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 631EA7521402E87D003FB021 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; }; 631EA7531402E87D003FB021 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; }; - 631EA7551402E87D003FB021 /* TextViewController.h */ = {isa = PBXFileReference; path = TextViewController.h; sourceTree = ""; }; + 631EA7551402E87D003FB021 /* TextViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextViewController.h; sourceTree = ""; }; 631EA7561402E87D003FB021 /* TextViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TextViewController.m; sourceTree = ""; }; 631EA75C1402E87D003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TextViewController.xib; sourceTree = ""; }; 631EA76F1402E8B7003FB021 /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 631EA7721402EA96003FB021 /* BannerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BannerViewController.h; sourceTree = ""; }; 631EA7731402EA96003FB021 /* BannerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BannerViewController.m; sourceTree = ""; }; 631EA7761402F1C9003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/ipsums.plist; sourceTree = ""; }; + 63B6242A15E84CCE00D77C46 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Resources/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -61,7 +63,7 @@ 631EA7311402E87D003FB021 = { isa = PBXGroup; children = ( - 631EA7461402E87D003FB021 /* SplitViewBanner */, + 631EA7461402E87D003FB021 /* SplitNavigationBanner */, 631EA73F1402E87D003FB021 /* Frameworks */, 631EA73D1402E87D003FB021 /* Products */, ); @@ -70,7 +72,7 @@ 631EA73D1402E87D003FB021 /* Products */ = { isa = PBXGroup; children = ( - 631EA73C1402E87D003FB021 /* SplitViewBanner.app */, + 631EA73C1402E87D003FB021 /* SplitNavigationBanner.app */, ); name = Products; sourceTree = ""; @@ -86,7 +88,7 @@ name = Frameworks; sourceTree = ""; }; - 631EA7461402E87D003FB021 /* SplitViewBanner */ = { + 631EA7461402E87D003FB021 /* SplitNavigationBanner */ = { isa = PBXGroup; children = ( 631EA74F1402E87D003FB021 /* AppDelegate.h */, @@ -100,17 +102,18 @@ 631EA75B1402E87D003FB021 /* TextViewController.xib */, 631EA7471402E87D003FB021 /* Supporting Files */, ); - path = SplitViewBanner; + path = SplitNavigationBanner; sourceTree = ""; }; 631EA7471402E87D003FB021 /* Supporting Files */ = { isa = PBXGroup; children = ( + 63B6242A15E84CCE00D77C46 /* Default-568h@2x.png */, 631EA7751402F1C9003FB021 /* ipsums.plist */, - 631EA7481402E87D003FB021 /* SplitViewBanner-Info.plist */, + 631EA7481402E87D003FB021 /* SplitNavigationBanner-Info.plist */, 631EA7491402E87D003FB021 /* InfoPlist.strings */, 631EA74C1402E87D003FB021 /* main.m */, - 631EA74E1402E87D003FB021 /* SplitViewBanner-Prefix.pch */, + 631EA74E1402E87D003FB021 /* SplitNavigationBanner-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; @@ -118,9 +121,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 631EA73B1402E87D003FB021 /* SplitViewBanner */ = { + 631EA73B1402E87D003FB021 /* SplitNavigationBanner */ = { isa = PBXNativeTarget; - buildConfigurationList = 631EA7601402E87D003FB021 /* Build configuration list for PBXNativeTarget "SplitViewBanner" */; + buildConfigurationList = 631EA7601402E87D003FB021 /* Build configuration list for PBXNativeTarget "SplitNavigationBanner" */; buildPhases = ( 631EA7381402E87D003FB021 /* Sources */, 631EA7391402E87D003FB021 /* Frameworks */, @@ -130,9 +133,9 @@ ); dependencies = ( ); - name = SplitViewBanner; - productName = SplitViewBanner; - productReference = 631EA73C1402E87D003FB021 /* SplitViewBanner.app */; + name = SplitNavigationBanner; + productName = SplitNavigationBanner; + productReference = 631EA73C1402E87D003FB021 /* SplitNavigationBanner.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -143,7 +146,7 @@ attributes = { LastUpgradeCheck = 0420; }; - buildConfigurationList = 631EA7361402E87D003FB021 /* Build configuration list for PBXProject "SplitViewBanner" */; + buildConfigurationList = 631EA7361402E87D003FB021 /* Build configuration list for PBXProject "SplitNavigationBanner" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -155,7 +158,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 631EA73B1402E87D003FB021 /* SplitViewBanner */, + 631EA73B1402E87D003FB021 /* SplitNavigationBanner */, ); }; /* End PBXProject section */ @@ -168,6 +171,7 @@ 631EA74B1402E87D003FB021 /* InfoPlist.strings in Resources */, 631EA75D1402E87D003FB021 /* TextViewController.xib in Resources */, 631EA7771402F1C9003FB021 /* ipsums.plist in Resources */, + 63B6242B15E84CCE00D77C46 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -222,6 +226,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -233,12 +238,21 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = 2; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -248,17 +262,27 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = 2; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -267,9 +291,9 @@ isa = XCBuildConfiguration; buildSettings = { GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "SplitViewBanner/SplitViewBanner-Prefix.pch"; - INFOPLIST_FILE = "SplitViewBanner/SplitViewBanner-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; + GCC_PREFIX_HEADER = "SplitNavigationBanner/SplitNavigationBanner-Prefix.pch"; + INFOPLIST_FILE = "SplitNavigationBanner/SplitNavigationBanner-Info.plist"; + PRODUCT_NAME = SplitNavigationBanner; WRAPPER_EXTENSION = app; }; name = Debug; @@ -278,9 +302,9 @@ isa = XCBuildConfiguration; buildSettings = { GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "SplitViewBanner/SplitViewBanner-Prefix.pch"; - INFOPLIST_FILE = "SplitViewBanner/SplitViewBanner-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; + GCC_PREFIX_HEADER = "SplitNavigationBanner/SplitNavigationBanner-Prefix.pch"; + INFOPLIST_FILE = "SplitNavigationBanner/SplitNavigationBanner-Info.plist"; + PRODUCT_NAME = SplitNavigationBanner; WRAPPER_EXTENSION = app; }; name = Release; @@ -288,7 +312,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 631EA7361402E87D003FB021 /* Build configuration list for PBXProject "SplitViewBanner" */ = { + 631EA7361402E87D003FB021 /* Build configuration list for PBXProject "SplitNavigationBanner" */ = { isa = XCConfigurationList; buildConfigurations = ( 631EA75E1402E87D003FB021 /* Debug */, @@ -297,7 +321,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 631EA7601402E87D003FB021 /* Build configuration list for PBXNativeTarget "SplitViewBanner" */ = { + 631EA7601402E87D003FB021 /* Build configuration list for PBXNativeTarget "SplitNavigationBanner" */ = { isa = XCConfigurationList; buildConfigurations = ( 631EA7611402E87D003FB021 /* Debug */, diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner.xcodeproj/xcshareddata/xcschemes/SplitViewBanner.xcscheme b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner.xcodeproj/xcshareddata/xcschemes/SplitNavigationBanner.xcscheme similarity index 73% rename from iAdSuite/SplitViewBanner/SplitViewBanner.xcodeproj/xcshareddata/xcschemes/SplitViewBanner.xcscheme rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner.xcodeproj/xcshareddata/xcschemes/SplitNavigationBanner.xcscheme index 1644ac9..5d801f2 100644 --- a/iAdSuite/SplitViewBanner/SplitViewBanner.xcodeproj/xcshareddata/xcschemes/SplitViewBanner.xcscheme +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner.xcodeproj/xcshareddata/xcschemes/SplitNavigationBanner.xcscheme @@ -1,5 +1,6 @@ + BuildableName = "SplitNavigationBanner.app" + BlueprintName = "SplitNavigationBanner" + ReferencedContainer = "container:SplitNavigationBanner.xcodeproj"> @@ -32,27 +33,28 @@ + BuildableName = "SplitNavigationBanner.app" + BlueprintName = "SplitNavigationBanner" + ReferencedContainer = "container:SplitNavigationBanner.xcodeproj"> + BuildableName = "SplitNavigationBanner.app" + BlueprintName = "SplitNavigationBanner" + ReferencedContainer = "container:SplitNavigationBanner.xcodeproj"> @@ -68,9 +70,9 @@ + BuildableName = "SplitNavigationBanner.app" + BlueprintName = "SplitNavigationBanner" + ReferencedContainer = "container:SplitNavigationBanner.xcodeproj"> diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/AppDelegate.h b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/AppDelegate.h new file mode 100644 index 0000000..06d7f06 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/AppDelegate.h @@ -0,0 +1,56 @@ +/* + File: AppDelegate.h +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class BannerViewController; + +@interface AppDelegate : UIResponder + +@property (nonatomic, strong) UIWindow *window; + +@end diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/AppDelegate.m b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/AppDelegate.m new file mode 100644 index 0000000..ec85837 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/AppDelegate.m @@ -0,0 +1,99 @@ +/* + File: AppDelegate.m +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import "AppDelegate.h" +#import "MasterViewController.h" +#import "TextViewController.h" +#import "BannerViewController.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate { + UINavigationController *_navigationController; + UISplitViewController *_splitViewController; + BannerViewController *_bannerViewController; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.backgroundColor = [UIColor whiteColor]; + + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + // On iPhone we use a UINavigationController as our primary user interface. + // In that configuration, the master view controller won't have a detail view controller. + MasterViewController *masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStyleGrouped]; + _navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController]; + _bannerViewController = [[BannerViewController alloc] initWithContentViewController:_navigationController]; + } else { + // On iPad we use a UISplitViewController as our primary user interface. + // In this configuration, the master view controller has a detail view controller that it will update as the selection changes. + MasterViewController *masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStylePlain]; + TextViewController *detailViewController = [[TextViewController alloc] init]; + masterViewController.detailViewController = detailViewController; + + _splitViewController = [[UISplitViewController alloc] init]; + _splitViewController.viewControllers = @[ + [[UINavigationController alloc] initWithRootViewController:masterViewController], + [[UINavigationController alloc] initWithRootViewController:detailViewController] + ]; + _splitViewController.delegate = self; + _bannerViewController = [[BannerViewController alloc] initWithContentViewController:_splitViewController]; + } + self.window.rootViewController = _bannerViewController; + [self.window makeKeyAndVisible]; + return YES; +} + +- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation +{ + return NO; +} + +@end diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/BannerViewController.h b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/BannerViewController.h new file mode 100644 index 0000000..afb19c3 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/BannerViewController.h @@ -0,0 +1,58 @@ +/* + File: BannerViewController.h +Abstract: A container view controller that manages an ADBannerView and a content view controller + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +extern NSString * const BannerViewActionWillBegin; +extern NSString * const BannerViewActionDidFinish; + +@interface BannerViewController : UIViewController + +- (instancetype)initWithContentViewController:(UIViewController *)contentController; + +@end diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/BannerViewController.m b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/BannerViewController.m new file mode 100644 index 0000000..0b89a9a --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/BannerViewController.m @@ -0,0 +1,161 @@ +/* + File: BannerViewController.m +Abstract: A container view controller that manages an ADBannerView and a content view controller + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import "BannerViewController.h" + +NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin"; +NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish"; + +@interface BannerViewController () + +@end + +@implementation BannerViewController { + ADBannerView *_bannerView; + UIViewController *_contentController; +} + +- (instancetype)initWithContentViewController:(UIViewController *)contentController +{ + self = [super init]; + if (self != nil) { + // On iOS 6 ADBannerView introduces a new initializer, use it when available. + if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) { + _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner]; + } else { + _bannerView = [[ADBannerView alloc] init]; + } + _bannerView.delegate = self; + _contentController = contentController; + } + return self; +} + +- (void)loadView +{ + UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + [contentView addSubview:_bannerView]; + [self addChildViewController:_contentController]; + [contentView addSubview:_contentController.view]; + [_contentController didMoveToParentViewController:self]; + self.view = contentView; +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; +} +#endif + +- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation +{ + return [_contentController preferredInterfaceOrientationForPresentation]; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + return [_contentController supportedInterfaceOrientations]; +} + +- (void)viewDidLayoutSubviews +{ + CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 + // If configured to support iOS <6.0, then we need to set the currentContentSizeIdentifier in order to resize the banner properly. + // This continues to work on iOS 6.0, so we won't need to do anything further to resize the banner. + if (contentFrame.size.width < contentFrame.size.height) { + _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; + } else { + _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; + } + bannerFrame = _bannerView.frame; +#else + // If configured to support iOS >= 6.0 only, then we want to avoid currentContentSizeIdentifier as it is deprecated. + // Fortunately all we need to do is ask the banner for a size that fits into the layout area we are using. + // At this point in this method contentFrame=self.view.bounds, so we'll use that size for the layout. + bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size]; +#endif + + if (_bannerView.bannerLoaded) { + contentFrame.size.height -= bannerFrame.size.height; + bannerFrame.origin.y = contentFrame.size.height; + } else { + bannerFrame.origin.y = contentFrame.size.height; + } + _contentController.view.frame = contentFrame; + _bannerView.frame = bannerFrame; +} + +- (void)bannerViewDidLoadAd:(ADBannerView *)banner +{ + [UIView animateWithDuration:0.25 animations:^{ + [self.view setNeedsLayout]; + [self.view layoutIfNeeded]; + }]; +} + +- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error +{ + [UIView animateWithDuration:0.25 animations:^{ + [self.view setNeedsLayout]; + [self.view layoutIfNeeded]; + }]; +} + +- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave +{ + [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self]; + return YES; +} + +- (void)bannerViewActionDidFinish:(ADBannerView *)banner +{ + [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self]; +} + +@end diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/MasterViewController.h b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/MasterViewController.h new file mode 100644 index 0000000..ff69145 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/MasterViewController.h @@ -0,0 +1,56 @@ +/* + File: MasterViewController.h +Abstract: A simple view controller that manages a table view + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +@class TextViewController; + +@interface MasterViewController : UITableViewController + +@property (nonatomic, strong) TextViewController *detailViewController; + +@end diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/MasterViewController.m b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/MasterViewController.m new file mode 100644 index 0000000..5ff1694 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/MasterViewController.m @@ -0,0 +1,141 @@ +/* + File: MasterViewController.m +Abstract: A simple view controller that manages a table view + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import "MasterViewController.h" + +#import "TextViewController.h" + +@implementation MasterViewController { + NSDictionary *_ipsums; + NSArray *_ipsumNames; +} + +- (instancetype)initWithStyle:(UITableViewStyle)style +{ + self = [super initWithStyle:style]; + if (self) { + self.title = NSLocalizedString(@"Ipsums", @"Ipsums"); + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + // On iPad only, don't clear the selection (we are displaying in a split view on iPad). + self.clearsSelectionOnViewWillAppear = NO; + } + + NSData *tmp = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; + _ipsums = [NSPropertyListSerialization propertyListWithData:tmp options:NSPropertyListImmutable format:nil error:nil]; + _ipsumNames = [[_ipsums allKeys] sortedArrayUsingSelector:@selector(compare:)]; + } + return self; +} + +- (void)configureDetailItemForRow:(NSUInteger)row +{ + NSString *item = _ipsumNames[row]; + NSString *text = _ipsums[item]; + NSString *title = NSLocalizedString(item, @"Original-Meaty-Vegan"); + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + // On iPhone we need to push on our navigation stack. + TextViewController *textViewController = [[TextViewController alloc] init]; + textViewController.text = text; + textViewController.title = title; + [self.navigationController pushViewController:textViewController animated:YES]; + } else { + // On iPad we need to just configure our detail view. + self.detailViewController.text = text; + self.detailViewController.title = title; + } +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle]; + [self configureDetailItemForRow:0]; + } +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} +#endif + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [_ipsums count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; + } + + // Configure the cell. + cell.textLabel.text = _ipsumNames[indexPath.row]; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + // Disclsure indicators on iPhone only. + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [self configureDetailItemForRow:indexPath.row]; +} + +@end diff --git a/iAdSuite/NavigationBanner/NavigationBanner/NavigationBanner-Info.plist b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/SplitNavigationBanner-Info.plist similarity index 77% rename from iAdSuite/NavigationBanner/NavigationBanner/NavigationBanner-Info.plist rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner/SplitNavigationBanner-Info.plist index fd37b06..ab1633f 100644 --- a/iAdSuite/NavigationBanner/NavigationBanner/NavigationBanner-Info.plist +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/SplitNavigationBanner-Info.plist @@ -19,22 +19,29 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 2.1 CFBundleSignature ???? CFBundleVersion - 1.0 + 2.1 LSRequiresIPhoneOS + UIRequiredDeviceCapabilities + + armv7 + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIRequiredDeviceCapabilities + UISupportedInterfaceOrientations~ipad - armv7 + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/SplitViewBanner-Prefix.pch b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/SplitNavigationBanner-Prefix.pch similarity index 81% rename from iAdSuite/SplitViewBanner/SplitViewBanner/SplitViewBanner-Prefix.pch rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner/SplitNavigationBanner-Prefix.pch index 5c9bd0e..8a4244a 100644 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/SplitViewBanner-Prefix.pch +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/SplitNavigationBanner-Prefix.pch @@ -4,8 +4,8 @@ #import -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." +#ifndef __IPHONE_6_0 +#warning "This project uses features only available in iOS SDK 6.0 and later." #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 #error "This project requires features only available in iOS 5.0 and later." #endif diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/TextViewController.h b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/TextViewController.h new file mode 100644 index 0000000..bf1b148 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/TextViewController.h @@ -0,0 +1,54 @@ +/* + File: TextViewController.h +Abstract: A simple view controller that manages a content view + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +@interface TextViewController : UIViewController + +@property (nonatomic, copy) NSString *text; + +@end diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/TextViewController.m b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/TextViewController.m new file mode 100644 index 0000000..aa99599 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/TextViewController.m @@ -0,0 +1,148 @@ +/* + File: TextViewController.m +Abstract: A simple view controller that manages a content view + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import "TextViewController.h" +#import "BannerViewController.h" + +@interface TextViewController () + +@property (nonatomic, strong) IBOutlet UITextView *textView; +@property (nonatomic, strong) IBOutlet UILabel *timerLabel; + +@end + +@implementation TextViewController { + NSTimer *_timer; + CFTimeInterval _ticks; +} + +- (instancetype)init +{ + self = [super initWithNibName:@"TextViewController" bundle:nil]; + if (self) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willBeginBannerViewActionNotification:) name:BannerViewActionWillBegin object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishBannerViewActionNotification:) name:BannerViewActionDidFinish object:nil]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)setText:(NSString *)text +{ + _text = [text copy]; + self.textView.text = text; +} + +- (void)startTimer +{ + if (_timer == nil) { + _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; + } +} + +- (void)stopTimer +{ + [_timer invalidate]; + _timer = nil; +} + +- (void)timerTick:(NSTimer *)timer +{ + // Timers are not guaranteed to tick at the nominal rate specified, so this isn't technically accurate. + // However, this is just an example to demonstrate how to stop some ongoing activity, so we can live with that inaccuracy. + _ticks += 0.1; + double seconds = fmod(_ticks, 60.0); + double minutes = fmod(trunc(_ticks / 60.0), 60.0); + double hours = trunc(_ticks / 3600.0); + self.timerLabel.text = [NSString stringWithFormat:@"%02.0f:%02.0f:%04.1f", hours, minutes, seconds]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.textView.text = self.text; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + [self startTimer]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + [self stopTimer]; +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} +#endif + +- (NSUInteger)supportedInterfaceOrientations +{ + return UIInterfaceOrientationMaskAll; +} + +- (void)willBeginBannerViewActionNotification:(NSNotification *)notification +{ + [self stopTimer]; +} + +- (void)didFinishBannerViewActionNotification:(NSNotification *)notification +{ + [self startTimer]; +} + +@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/InfoPlist.strings b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/en.lproj/InfoPlist.strings similarity index 100% rename from iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/InfoPlist.strings rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner/en.lproj/InfoPlist.strings diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/TextViewController.xib b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/en.lproj/TextViewController.xib similarity index 100% rename from iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/TextViewController.xib rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner/en.lproj/TextViewController.xib diff --git a/iAdSuite/NavigationBanner/NavigationBanner/en.lproj/ipsums.plist b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/en.lproj/ipsums.plist similarity index 100% rename from iAdSuite/NavigationBanner/NavigationBanner/en.lproj/ipsums.plist rename to iAdSuite/SplitNavigationBanner/SplitNavigationBanner/en.lproj/ipsums.plist diff --git a/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/main.m b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/main.m new file mode 100644 index 0000000..1bf6484 --- /dev/null +++ b/iAdSuite/SplitNavigationBanner/SplitNavigationBanner/main.m @@ -0,0 +1,57 @@ +/* + File: main.m + Abstract: Main entry point + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import + +#import "AppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/AppDelegate.h b/iAdSuite/SplitViewBanner/SplitViewBanner/AppDelegate.h deleted file mode 100644 index ef19122..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/AppDelegate.h +++ /dev/null @@ -1,54 +0,0 @@ -/* File: AppDelegate.h */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import - -@class BannerViewController; - -@interface AppDelegate : UIResponder - -@property (nonatomic, strong) UIWindow *window; - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/AppDelegate.m b/iAdSuite/SplitViewBanner/SplitViewBanner/AppDelegate.m deleted file mode 100644 index 44411b9..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/AppDelegate.m +++ /dev/null @@ -1,87 +0,0 @@ -/* File: AppDelegate.m */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "AppDelegate.h" -#import "MasterViewController.h" -#import "TextViewController.h" -#import "BannerViewController.h" - -@implementation AppDelegate -{ - UISplitViewController *_splitViewController; - BannerViewController *_bannerViewController; -} - -@synthesize window = _window; - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.window.backgroundColor = [UIColor whiteColor]; - - MasterViewController *masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStylePlain]; - UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController]; - - TextViewController *detailViewController = [[TextViewController alloc] init]; - UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController]; - - masterViewController.detailViewController = detailViewController; - - _splitViewController = [[UISplitViewController alloc] init]; - _splitViewController.delegate = self; - _splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController, detailNavigationController, nil]; - - _bannerViewController = [[BannerViewController alloc] initWithContentViewController:_splitViewController]; - self.window.rootViewController = _bannerViewController; - [self.window makeKeyAndVisible]; - return YES; -} - -- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation -{ - return NO; -} - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/BannerViewController.h b/iAdSuite/SplitViewBanner/SplitViewBanner/BannerViewController.h deleted file mode 100644 index 5cd7d21..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/BannerViewController.h +++ /dev/null @@ -1,56 +0,0 @@ -/* File: BannerViewController.h */ -/* Abstract: A container view controller that manages an ADBannerView and a content view controller */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import -#import - -extern NSString * const BannerViewActionWillBegin; -extern NSString * const BannerViewActionDidFinish; - -@interface BannerViewController : UIViewController - -- (id)initWithContentViewController:(UIViewController *)contentController; - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/BannerViewController.m b/iAdSuite/SplitViewBanner/SplitViewBanner/BannerViewController.m deleted file mode 100644 index 56b7133..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/BannerViewController.m +++ /dev/null @@ -1,134 +0,0 @@ -/* File: BannerViewController.m */ -/* Abstract: A container view controller that manages an ADBannerView and a content view controller */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "BannerViewController.h" - -NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin"; -NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish"; - -@implementation BannerViewController -{ - ADBannerView *_bannerView; - UIViewController *_contentController; -} - -- (id)initWithContentViewController:(UIViewController *)contentController -{ - self = [super init]; - if (self != nil) { - _bannerView = [[ADBannerView alloc] init]; - _bannerView.delegate = self; - _contentController = contentController; - } - return self; -} - -- (void)loadView -{ - UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - [contentView addSubview:_bannerView]; - [self addChildViewController:_contentController]; - [contentView addSubview:_contentController.view]; - [_contentController didMoveToParentViewController:self]; - self.view = contentView; -} - -- (void)viewDidUnload -{ - [super viewDidUnload]; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; -} - -- (void)viewDidLayoutSubviews -{ - if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; - } else { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; - } - CGRect contentFrame = self.view.bounds; - CGRect bannerFrame = _bannerView.frame; - if (_bannerView.bannerLoaded) { - contentFrame.size.height -= _bannerView.frame.size.height; - bannerFrame.origin.y = contentFrame.size.height; - } else { - bannerFrame.origin.y = contentFrame.size.height; - } - _contentController.view.frame = contentFrame; - _bannerView.frame = bannerFrame; -} - -- (void)bannerViewDidLoadAd:(ADBannerView *)banner -{ - [UIView animateWithDuration:0.25 animations:^{ - [self.view setNeedsLayout]; - [self.view layoutIfNeeded]; - }]; -} - -- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error -{ - [UIView animateWithDuration:0.25 animations:^{ - [self.view setNeedsLayout]; - [self.view layoutIfNeeded]; - }]; -} - -- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave -{ - [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self]; - return YES; -} - -- (void)bannerViewActionDidFinish:(ADBannerView *)banner -{ - [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self]; -} - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/MasterViewController.h b/iAdSuite/SplitViewBanner/SplitViewBanner/MasterViewController.h deleted file mode 100644 index e00fc2d..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/MasterViewController.h +++ /dev/null @@ -1,54 +0,0 @@ -/* File: MasterViewController.h */ -/* Abstract: A simple view controller that manages a table view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import - -@class TextViewController; - -@interface MasterViewController : UITableViewController - -@property (nonatomic, strong) TextViewController *detailViewController; - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/MasterViewController.m b/iAdSuite/SplitViewBanner/SplitViewBanner/MasterViewController.m deleted file mode 100644 index 04f5b84..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/MasterViewController.m +++ /dev/null @@ -1,120 +0,0 @@ -/* File: MasterViewController.m */ -/* Abstract: A simple view controller that manages a table view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "MasterViewController.h" - -#import "TextViewController.h" - -@implementation MasterViewController -{ - NSDictionary *_data; - NSArray *_keys; -} - -@synthesize detailViewController = _detailViewController; - -- (id)initWithStyle:(UITableViewStyle)style -{ - self = [super initWithStyle:style]; - if (self) { - self.title = NSLocalizedString(@"Ipsums", @"Ipsums"); - self.clearsSelectionOnViewWillAppear = NO; - - NSData *tmp = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; - _data = [NSPropertyListSerialization propertyListWithData:tmp options:NSPropertyListImmutable format:nil error:nil]; - _keys = [[_data allKeys] sortedArrayUsingSelector:@selector(compare:)]; - } - return self; -} - -- (void)configureDetailItemForRow:(NSUInteger)row -{ - NSString *item = [_keys objectAtIndex:row]; - self.detailViewController.text = [_data objectForKey:item]; - self.detailViewController.title = NSLocalizedString(item, @"Original-Meaty-Vegan"); -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle]; - [self configureDetailItemForRow:0]; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [_data count]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - static NSString *CellIdentifier = @"Cell"; - - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (cell == nil) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; - } - - // Configure the cell. - cell.textLabel.text = [_keys objectAtIndex:indexPath.row]; - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [self configureDetailItemForRow:indexPath.row]; -} - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/TextViewController.h b/iAdSuite/SplitViewBanner/SplitViewBanner/TextViewController.h deleted file mode 100644 index 9302fd6..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/TextViewController.h +++ /dev/null @@ -1,54 +0,0 @@ -/* File: TextViewController.h */ -/* Abstract: A simple view controller that manages a content view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import - -@interface TextViewController : UIViewController - -@property (nonatomic, strong) IBOutlet UITextView *textView; -@property(nonatomic, strong) IBOutlet UILabel *timerLabel; -@property (nonatomic, copy) NSString *text; - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/TextViewController.m b/iAdSuite/SplitViewBanner/SplitViewBanner/TextViewController.m deleted file mode 100644 index 0cd5002..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/TextViewController.m +++ /dev/null @@ -1,121 +0,0 @@ -/* File: TextViewController.m */ -/* Abstract: A simple view controller that manages a content view */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ - -#import "TextViewController.h" -#import "BannerViewController.h" - -@implementation TextViewController -{ - NSTimer *_timer; - CFTimeInterval _ticks; -} - -@synthesize textView = _textView; -@synthesize timerLabel = _timerLabel; -@synthesize text = _text; - -- (id)init -{ - self = [super initWithNibName:@"TextViewController" bundle:nil]; - if (self) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willBeginBannerViewActionNotification:) name:BannerViewActionWillBegin object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishBannerViewActionNotification:) name:BannerViewActionDidFinish object:nil]; - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; - } - return self; -} - -- (void)dealloc -{ - [_timer invalidate]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)setText:(NSString *)text -{ - _text = [text copy]; - self.textView.text = text; -} - -- (void)timerTick:(NSTimer *)timer -{ - // Timers are not guaranteed to tick at the nominal rate specified, so this isn't technically accurate. - // However, this is just an example to demonstrate how to stop some ongoing activity, so we can live with that inaccuracy. - _ticks += 0.1; - double seconds = fmod(_ticks, 60.0); - double minutes = fmod(trunc(_ticks / 60.0), 60.0); - double hours = trunc(_ticks / 3600.0); - self.timerLabel.text = [NSString stringWithFormat:@"%02.0f:%02.0f:%04.1f", hours, minutes, seconds]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - self.textView.text = self.text; -} - -- (void)viewDidUnload -{ - [super viewDidUnload]; - self.textView = nil; - self.timerLabel = nil; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - -- (void)willBeginBannerViewActionNotification:(NSNotification *)notification -{ - [_timer invalidate]; -} - -- (void)didFinishBannerViewActionNotification:(NSNotification *)notification -{ - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; -} - -@end diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/ipsums.plist b/iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/ipsums.plist deleted file mode 100644 index 3375053..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/en.lproj/ipsums.plist +++ /dev/null @@ -1,46 +0,0 @@ - - - - - Original - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin eget purus nisi. Phasellus sed dolor vitae dolor semper adipiscing. Vivamus eu velit nunc, nec vulputate magna. Vivamus egestas ante ut felis tempus in sollicitudin nulla ultricies. Nullam hendrerit semper diam eu lacinia. Fusce ac augue arcu. Phasellus ac enim magna, et luctus dui. Aenean blandit, felis eget volutpat tempor, libero dolor tristique lectus, sit amet pellentesque est velit eget ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis posuere ullamcorper mauris, sodales convallis orci fermentum non. - -Maecenas eget varius enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut adipiscing condimentum mi, sed pulvinar ligula cursus quis. Morbi venenatis nisl vel mauris viverra posuere. Cras tempor accumsan risus nec fermentum. Nulla quis diam nec libero sodales blandit. Pellentesque vehicula metus ac libero commodo sed tincidunt est congue. Donec pulvinar tincidunt justo ut blandit. Fusce aliquet faucibus placerat. Nunc vitae lacus elit, condimentum pellentesque neque. Vivamus leo mauris, elementum nec lacinia id, ullamcorper quis orci. In in lacus nulla, sed molestie neque. Nam vitae risus sit amet ipsum dictum posuere. - -Cras ullamcorper luctus euismod. Duis ullamcorper purus sed libero egestas viverra. Morbi felis magna, auctor et ultricies id, accumsan sit amet neque. Nulla molestie luctus dapibus. Etiam eget volutpat risus. Vivamus lacinia enim sit amet felis euismod adipiscing. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce et felis fringilla risus volutpat sollicitudin eu sit amet diam. Morbi mi odio, tincidunt sit amet malesuada nec, vestibulum ac enim. Vestibulum vel lectus quis felis auctor convallis non a mi. Quisque sodales posuere purus viverra mollis. Aliquam quis suscipit quam. Suspendisse vestibulum, dolor ac blandit imperdiet, urna mi blandit sem, malesuada placerat dui mauris in metus. Morbi malesuada rhoncus sapien sit amet fermentum. Aenean risus diam, egestas nec luctus non, viverra venenatis lectus. In nec arcu eu orci molestie mollis id sit amet dolor. - -Donec id arcu ac nisi consectetur tincidunt non et est. Nulla quis arcu vel erat pretium ornare quis id enim. Donec sed feugiat ipsum. Vivamus magna purus, accumsan vel blandit id, dapibus eget risus. Nulla lorem lectus, interdum non vestibulum vitae, cursus a arcu. In sed massa et felis pretium ultrices a imperdiet metus. Phasellus vestibulum scelerisque tempus. Phasellus pellentesque pellentesque orci. - -Proin sollicitudin sagittis arcu, ut commodo lectus rutrum ac. Nulla at est et ante molestie lacinia. Donec in tortor ut est tincidunt dapibus. Vestibulum tincidunt, lorem nec egestas scelerisque, lacus augue pharetra elit, vitae laoreet nisl nisl ac risus. Nullam a vestibulum sem. Nam quis facilisis eros. Phasellus accumsan dui vitae lectus convallis ac ultricies justo auctor. Aliquam hendrerit augue quis lacus blandit ullamcorper. Suspendisse vitae erat placerat sapien consectetur luctus. Nullam et mi dui. Phasellus eleifend volutpat turpis, a sagittis orci rutrum ac. Praesent volutpat iaculis ultricies. Sed mattis lacinia fermentum. Donec orci elit, egestas et pharetra vel, varius cursus justo. Ut ullamcorper justo nec nisl imperdiet mollis. Suspendisse tincidunt justo id velit egestas tempor. - - - Meaty - Boudin meatloaf beef ribs, sausage salami biltong tail flank brisket pancetta pork chop ham hamburger venison kielbasa. Salami biltong ground round pork loin fatback beef ribs. Bresaola biltong beef jowl venison. Beef ribs boudin bacon filet mignon andouille meatloaf. Meatloaf sirloin pastrami pork belly, ribeye pig strip steak biltong pork loin turkey drumstick short ribs venison. Andouille pork loin filet mignon, shank ham hock meatball flank pig prosciutto. Tongue ribeye corned beef tri-tip, andouille kielbasa spare ribs shank. - -Ground round bacon fatback, corned beef salami short loin rump shank meatloaf short ribs sausage pork belly capicola. Swine bacon t-bone ham hock. Hamburger tri-tip chicken shank, tail shankle pork belly kielbasa frankfurter ham fatback tongue chuck ribeye sirloin. Turkey shank filet mignon, swine sausage ball tip meatball. Hamburger shoulder shank pastrami, turducken frankfurter ball tip pork chop tongue filet mignon pancetta biltong bacon. Tongue pig fatback, short ribs pork chuck ribeye sirloin meatball tail. Rump brisket shoulder, andouille drumstick pastrami kielbasa turducken pancetta meatball chuck tail prosciutto pork. - -Ham bacon meatloaf, beef venison spare ribs cow ball tip frankfurter drumstick ground round ribeye jowl. Pork loin pig rump, hamburger cow sausage swine beef ribs frankfurter corned beef filet mignon short loin salami. Leberkäse salami capicola, spare ribs venison ball tip turkey. Shankle tongue boudin tail, bresaola meatball chicken chuck ham hock frankfurter ball tip filet mignon jowl jerky. Filet mignon prosciutto bresaola chuck, leberkäse shankle sausage ground round drumstick tail pork belly. Leberkäse tongue filet mignon ham capicola. Tongue short ribs turducken, beef ribs ham hock turkey tail sausage venison. - -Short ribs shoulder pancetta ribeye tenderloin. Beef ribs corned beef shank, brisket biltong bacon jowl short ribs shankle tongue frankfurter pastrami meatball. Short loin sausage leberkäse brisket frankfurter pork loin pork chop corned beef, sirloin cow rump pancetta bresaola tongue prosciutto. Flank kielbasa pastrami meatloaf. T-bone tri-tip meatloaf, ham hock rump ball tip pork loin. Short ribs kielbasa t-bone, filet mignon jerky pork chop salami pork loin cow short loin pig turducken strip steak. Shoulder hamburger bacon chuck meatball, rump ham hock pork chop biltong ground round andouille ball tip short loin tail. - -Short loin spare ribs filet mignon, jowl bresaola ball tip rump beef ribs tri-tip biltong strip steak cow ham hock. Tenderloin sausage pork chop ham hock, salami pancetta strip steak jowl brisket tail boudin filet mignon pork loin meatloaf tongue. Corned beef swine pork loin strip steak, spare ribs pastrami salami. Flank meatloaf capicola bresaola shankle. Shankle boudin bresaola, bacon turducken salami sausage tenderloin tongue turkey pork chop jerky. Prosciutto andouille ground round turducken corned beef. Rump t-bone pork belly, turkey tenderloin sirloin spare ribs biltong beef pancetta turducken jerky kielbasa. - - - Vegan - Veggies sunt bona vobis, proinde vos postulo esse magis gram sweet pepper fava bean collard greens black-eyed pea endive cauliflower green bean salsify jícama silver beet bell pepper amaranth courgette rutabaga chickpea. - -Burdock radish chickpea komatsuna garlic dulse garbanzo zucchini pumpkin watercress spinach caulie asparagus wattle seed mustard sorrel horseradish. Lettuce welsh onion parsley courgette silver beet desert raisin melon beet greens quandong. Kohlrabi horseradish lotus root cauliflower rock melon seakale fava bean aubergine beet greens. - -Corn bush tomato pumpkin corn amaranth bok choy garlic collard greens water spinach peanut lotus root quandong prairie turnip. Broccoli rabe garlic spinach cucumber garlic bunya nuts chicory. Dandelion caulie winter purslane lotus root melon lettuce gram celtuce rutabaga. Parsnip azuki bean coriander sweet pepper melon artichoke groundnut nori broccoli rabe. Cabbage salad amaranth parsnip corn summer purslane collard greens beet greens chickpea dandelion carrot soko spring onion. - -Summer purslane water chestnut amaranth yarrow squash radish wattle seed pea gumbo. Azuki bean nori avocado shallot salsify rutabaga lettuce bamboo shoot beetroot quandong rock melon brussels sprout horseradish tomato. Yarrow radicchio courgette kakadu plum nori bell pepper aubergine asparagus fennel bunya nuts tigernut chickpea lotus root pea sprouts horseradish. - -Welsh onion peanut zucchini dandelion celery radicchio tatsoi cauliflower wakame broccoli rabe ricebean onion chickweed chickpea collard greens. Endive yarrow catsear courgette sierra leone bologi napa cabbage tomatillo bunya nuts asparagus okra quandong taro seakale. Dandelion chicory asparagus melon pea seakale jícama chickweed kale artichoke sea lettuce bell pepper sweet pepper eggplant summer purslane salad. - -Catsear bitterleaf ricebean water spinach water chestnut burdock rutabaga earthnut pea cucumber lentil seakale summer purslane salad dulse. Bell pepper zucchini wattle seed melon maize sweet pepper. Tatsoi black-eyed pea komatsuna radicchio watercress prairie turnip lotus root radish tomato garbanzo grape gumbo cress daikon. Avocado okra lotus root potato welsh onion tigernut soko kohlrabi catsear avocado salad cress cauliflower rock melon carrot spring onion ricebean. Rutabaga soybean sea lettuce winter purslane tigernut eggplant. - -Daikon winter purslane bamboo shoot kakadu plum sweet pepper courgette dandelion burdock. Potato parsley celery nori turnip greens onion corn rutabaga salsify bok choy water chestnut chard dandelion artichoke. Arugula winter purslane leek soko tomatillo epazote garbanzo asparagus okra lettuce avocado artichoke. - -Cress turnip greens cress watercress coriander sierra leone bologi garlic. Fava bean peanut artichoke chicory parsley turnip sea lettuce bamboo shoot chickweed celtuce horseradish broccoli rabe watercress. Sierra leone bologi corn celery ricebean beetroot kohlrabi water spinach pea sprouts earthnut pea chickweed fava bean. Endive prairie turnip cabbage taro tomato scallion. Winter purslane wakame collard greens watercress komatsuna sierra leone bologi. - - diff --git a/iAdSuite/SplitViewBanner/SplitViewBanner/main.m b/iAdSuite/SplitViewBanner/SplitViewBanner/main.m deleted file mode 100644 index c66ca85..0000000 --- a/iAdSuite/SplitViewBanner/SplitViewBanner/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// SplitViewBanner -// -// Created by David Duncan on 8/22/11. -// Copyright (c) 2011 __MyCompanyName__. All rights reserved. -// - -#import - -#import "AppDelegate.h" - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/project.pbxproj b/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/project.pbxproj index 6a1dbc4..e539c60 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/project.pbxproj +++ b/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/project.pbxproj @@ -17,6 +17,8 @@ 631EA7FC14031CE0003FB021 /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631EA7FB14031CE0003FB021 /* iAd.framework */; }; 631EA817140324AA003FB021 /* TextViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 631EA819140324AA003FB021 /* TextViewController.xib */; }; 631EA81F140324BE003FB021 /* ipsums.plist in Resources */ = {isa = PBXBuildFile; fileRef = 631EA81D140324BE003FB021 /* ipsums.plist */; }; + 6378845B15DC69D600EE3135 /* BannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6378845A15DC69D600EE3135 /* BannerViewController.m */; }; + 63B6242E15E84D6200D77C46 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 63B6242D15E84D6200D77C46 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -35,6 +37,9 @@ 631EA7FB14031CE0003FB021 /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 631EA818140324AA003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/TextViewController.xib; sourceTree = ""; }; 631EA81E140324BE003FB021 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/ipsums.plist; sourceTree = ""; }; + 6378845915DC69D600EE3135 /* BannerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BannerViewController.h; sourceTree = ""; }; + 6378845A15DC69D600EE3135 /* BannerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BannerViewController.m; sourceTree = ""; }; + 63B6242D15E84D6200D77C46 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Resources/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +90,8 @@ children = ( 631EA7A314030B0E003FB021 /* AppDelegate.h */, 631EA7A414030B0E003FB021 /* AppDelegate.m */, + 6378845915DC69D600EE3135 /* BannerViewController.h */, + 6378845A15DC69D600EE3135 /* BannerViewController.m */, 631EA7F61403165B003FB021 /* TextViewController.h */, 631EA7F71403165B003FB021 /* TextViewController.m */, 631EA819140324AA003FB021 /* TextViewController.xib */, @@ -96,6 +103,7 @@ 631EA79B14030B0E003FB021 /* Supporting Files */ = { isa = PBXGroup; children = ( + 63B6242D15E84D6200D77C46 /* Default-568h@2x.png */, 631EA81D140324BE003FB021 /* ipsums.plist */, 631EA79C14030B0E003FB021 /* TabbedBanner-Info.plist */, 631EA79D14030B0E003FB021 /* InfoPlist.strings */, @@ -158,6 +166,7 @@ 631EA79F14030B0E003FB021 /* InfoPlist.strings in Resources */, 631EA817140324AA003FB021 /* TextViewController.xib in Resources */, 631EA81F140324BE003FB021 /* ipsums.plist in Resources */, + 63B6242E15E84D6200D77C46 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -171,6 +180,7 @@ 631EA7A114030B0E003FB021 /* main.m in Sources */, 631EA7A514030B0E003FB021 /* AppDelegate.m in Sources */, 631EA7F91403165B003FB021 /* TextViewController.m in Sources */, + 6378845B15DC69D600EE3135 /* BannerViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -210,6 +220,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -221,11 +232,21 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.2; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -235,16 +256,27 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.2; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -255,9 +287,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "TabbedBanner/TabbedBanner-Prefix.pch"; INFOPLIST_FILE = "TabbedBanner/TabbedBanner-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = 1; WRAPPER_EXTENSION = app; }; name = Debug; @@ -268,9 +298,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "TabbedBanner/TabbedBanner-Prefix.pch"; INFOPLIST_FILE = "TabbedBanner/TabbedBanner-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = 1; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/xcshareddata/xcschemes/TabbedBanner.xcscheme b/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/xcshareddata/xcschemes/TabbedBanner.xcscheme index a25c25d..b51a1c0 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/xcshareddata/xcschemes/TabbedBanner.xcscheme +++ b/iAdSuite/TabbedBanner/TabbedBanner.xcodeproj/xcshareddata/xcschemes/TabbedBanner.xcscheme @@ -1,5 +1,6 @@ @@ -39,11 +40,12 @@ diff --git a/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.h b/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.h index 72d29d6..5aa0627 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.h +++ b/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.h @@ -1,61 +1,53 @@ -/* File: AppDelegate.h */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: AppDelegate.h +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import #import -@protocol BannerViewContainer - -- (void)showBannerView:(ADBannerView *)bannerView animated:(BOOL)animated; -- (void)hideBannerView:(ADBannerView *)bannerView animated:(BOOL)animated; - -@end - -extern NSString * const BannerViewActionWillBegin; -extern NSString * const BannerViewActionDidFinish; - @interface AppDelegate : UIResponder @property (nonatomic, strong) UIWindow *window; diff --git a/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.m b/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.m index cf346fb..415258e 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.m +++ b/iAdSuite/TabbedBanner/TabbedBanner/AppDelegate.m @@ -1,131 +1,89 @@ -/* File: AppDelegate.m */ -/* Abstract: Application delegate */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: AppDelegate.m +Abstract: Application delegate + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "AppDelegate.h" #import "TextViewController.h" +#import "BannerViewController.h" -NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin"; -NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish"; - -@implementation AppDelegate -{ +@implementation AppDelegate { UITabBarController *_tabBarController; - UIViewController *_currentController; - ADBannerView *_bannerView; } -@synthesize window = _window; - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { CGRect bounds = [[UIScreen mainScreen] bounds]; self.window = [[UIWindow alloc] initWithFrame:bounds]; self.window.backgroundColor = [UIColor whiteColor]; - // The ADBannerView will fix up the given size, we just want to ensure it is created at a location off the bottom of the screen. - // This ensures that the first animation doesn't come in from the top of the screen. - _bannerView = [[ADBannerView alloc] initWithFrame:CGRectMake(0.0, bounds.size.height, 0.0, 0.0)]; - _bannerView.delegate = self; + NSData *ipsumData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; + NSDictionary *ipsums = [NSPropertyListSerialization propertyListWithData:ipsumData options:NSPropertyListImmutable format:nil error:nil]; - NSData *tmp = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ipsums" withExtension:@"plist"] options:NSDataReadingMappedIfSafe error:nil]; - NSDictionary *_data = [NSPropertyListSerialization propertyListWithData:tmp options:NSPropertyListImmutable format:nil error:nil]; - - TextViewController *original = [[TextViewController alloc] init]; - original.title = NSLocalizedString(@"Original", @"Original"); - original.text = [_data objectForKey:@"Original"]; + TextViewController *originalIpsumViewController = [[TextViewController alloc] init]; + originalIpsumViewController.title = NSLocalizedString(@"Original", @"Original"); + originalIpsumViewController.text = ipsums[@"Original"]; - TextViewController *meaty = [[TextViewController alloc] init]; - meaty.title = NSLocalizedString(@"Meaty", @"Meaty"); - meaty.text = [_data objectForKey:@"Meaty"]; + TextViewController *meatyIpsumViewController = [[TextViewController alloc] init]; + meatyIpsumViewController.title = NSLocalizedString(@"Meaty", @"Meaty"); + meatyIpsumViewController.text = ipsums[@"Meaty"]; - TextViewController *vegan = [[TextViewController alloc] init]; - vegan.title = NSLocalizedString(@"Vegan", @"Vegan"); - vegan.text = [_data objectForKey:@"Vegan"]; + TextViewController *veganIpsumViewController = [[TextViewController alloc] init]; + veganIpsumViewController.title = NSLocalizedString(@"Vegan", @"Vegan"); + veganIpsumViewController.text = ipsums[@"Vegan"]; _tabBarController = [[UITabBarController alloc] init]; - _tabBarController.viewControllers = [NSArray arrayWithObjects:original, meaty, vegan, nil]; - _tabBarController.delegate = self; - - _currentController = (UIViewController *)_tabBarController.selectedViewController; + _tabBarController.viewControllers = @[ + [[BannerViewController alloc] initWithContentViewController:originalIpsumViewController], + [[BannerViewController alloc] initWithContentViewController:meatyIpsumViewController], + [[BannerViewController alloc] initWithContentViewController:veganIpsumViewController], + ]; self.window.rootViewController = _tabBarController; [self.window makeKeyAndVisible]; return YES; } -- (void)bannerViewDidLoadAd:(ADBannerView *)banner -{ - [_currentController showBannerView:_bannerView animated:YES]; -} - -- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error -{ - [_currentController hideBannerView:_bannerView animated:YES]; -} - -- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave -{ - [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self]; - return YES; -} - -- (void)bannerViewActionDidFinish:(ADBannerView *)banner -{ - [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self]; -} - -- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController -{ - if (_currentController == viewController) { - return; - } - if (_bannerView.bannerLoaded) { - [_currentController hideBannerView:_bannerView animated:NO]; - [(UIViewController *)viewController showBannerView:_bannerView animated:YES]; - } - _currentController = (UIViewController *)viewController; -} - @end diff --git a/iAdSuite/TabbedBanner/TabbedBanner/BannerViewController.h b/iAdSuite/TabbedBanner/TabbedBanner/BannerViewController.h new file mode 100644 index 0000000..f538bf7 --- /dev/null +++ b/iAdSuite/TabbedBanner/TabbedBanner/BannerViewController.h @@ -0,0 +1,58 @@ +/* + File: BannerViewController.h +Abstract: A container view controller that manages an ADBannerView and a content view controller + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +extern NSString * const BannerViewActionWillBegin; +extern NSString * const BannerViewActionDidFinish; + +@interface BannerViewController : UIViewController + +- (instancetype)initWithContentViewController:(UIViewController *)contentController; + +@end diff --git a/iAdSuite/TabbedBanner/TabbedBanner/BannerViewController.m b/iAdSuite/TabbedBanner/TabbedBanner/BannerViewController.m new file mode 100644 index 0000000..fd0be91 --- /dev/null +++ b/iAdSuite/TabbedBanner/TabbedBanner/BannerViewController.m @@ -0,0 +1,243 @@ +/* + File: BannerViewController.m +Abstract: A container view controller that manages an ADBannerView and a content view controller + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ + +#import "BannerViewController.h" + +NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin"; +NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish"; + +@interface BannerViewController () + +// This method is used by BannerViewSingletonController to inform instances of BannerViewController that the banner has loaded/unloaded. +- (void)updateLayout; + +@end + +@interface BannerViewManager : NSObject + +@property (nonatomic, readonly) ADBannerView *bannerView; + ++ (BannerViewManager *)sharedInstance; + +- (void)addBannerViewController:(BannerViewController *)controller; +- (void)removeBannerViewController:(BannerViewController *)controller; + +@end + +@implementation BannerViewController { + UIViewController *_contentController; +} + +- (instancetype)initWithContentViewController:(UIViewController *)contentController +{ + self = [super init]; + if (self != nil) { + _contentController = contentController; + [[BannerViewManager sharedInstance] addBannerViewController:self]; + } + return self; +} + +- (void)dealloc +{ + [[BannerViewManager sharedInstance] removeBannerViewController:self]; +} + +- (void)loadView +{ + UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + [self addChildViewController:_contentController]; + [contentView addSubview:_contentController.view]; + [_contentController didMoveToParentViewController:self]; + self.view = contentView; +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; +} +#endif + +- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation +{ + return [_contentController preferredInterfaceOrientationForPresentation]; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + return [_contentController supportedInterfaceOrientations]; +} + +- (void)viewDidLayoutSubviews +{ + CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero; + ADBannerView *bannerView = [BannerViewManager sharedInstance].bannerView; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 + NSString *contentSizeIdentifier; + // If configured to support iOS <6.0, then we need to set the currentContentSizeIdentifier in order to resize the banner properly. + // This continues to work on iOS 6.0, so we won't need to do anything further to resize the banner. + if (contentFrame.size.width < contentFrame.size.height) { + contentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; + } else { + contentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; + } + bannerFrame.size = [ADBannerView sizeFromBannerContentSizeIdentifier:contentSizeIdentifier]; +#else + // If configured to support iOS >= 6.0 only, then we want to avoid currentContentSizeIdentifier as it is deprecated. + // Fortunately all we need to do is ask the banner for a size that fits into the layout area we are using. + // At this point in this method contentFrame=self.view.bounds, so we'll use that size for the layout. + bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size]; +#endif + + if (bannerView.bannerLoaded) { + contentFrame.size.height -= bannerFrame.size.height; + bannerFrame.origin.y = contentFrame.size.height; + } else { + bannerFrame.origin.y = contentFrame.size.height; + } + _contentController.view.frame = contentFrame; + // We only want to modify the banner view itself if this view controller is actually visible to the user. + // This prevents us from modifying it while it is being displayed elsewhere. + if (self.isViewLoaded && (self.view.window != nil)) { + [self.view addSubview:bannerView]; + bannerView.frame = bannerFrame; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 + bannerView.currentContentSizeIdentifier = contentSizeIdentifier; +#endif + } +} + +- (void)updateLayout +{ + [UIView animateWithDuration:0.25 animations:^{ + [self.view setNeedsLayout]; + [self.view layoutIfNeeded]; + }]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [self.view addSubview:[BannerViewManager sharedInstance].bannerView]; +} + +- (NSString *)title +{ + return _contentController.title; +} + +@end + +@implementation BannerViewManager { + ADBannerView *_bannerView; + NSMutableSet *_bannerViewControllers; +} + ++ (BannerViewManager *)sharedInstance +{ + static BannerViewManager *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[BannerViewManager alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init +{ + self = [super init]; + if (self != nil) { + // On iOS 6 ADBannerView introduces a new initializer, use it when available. + if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) { + _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner]; + } else { + _bannerView = [[ADBannerView alloc] init]; + } + _bannerView.delegate = self; + _bannerViewControllers = [[NSMutableSet alloc] init]; + } + return self; +} + +- (void)addBannerViewController:(BannerViewController *)controller +{ + [_bannerViewControllers addObject:controller]; +} + +- (void)removeBannerViewController:(BannerViewController *)controller +{ + [_bannerViewControllers removeObject:controller]; +} + +- (void)bannerViewDidLoadAd:(ADBannerView *)banner +{ + for (BannerViewController *bvc in _bannerViewControllers) { + [bvc updateLayout]; + } +} + +- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error +{ + for (BannerViewController *bvc in _bannerViewControllers) { + [bvc updateLayout]; + } +} + +- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave +{ + [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self]; + return YES; +} + +- (void)bannerViewActionDidFinish:(ADBannerView *)banner +{ + [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self]; +} + + +@end diff --git a/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Info.plist b/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Info.plist index bb6305d..16d208e 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Info.plist +++ b/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Info.plist @@ -19,11 +19,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 2.1 CFBundleSignature ???? CFBundleVersion - 1.0 + 2.1 LSRequiresIPhoneOS UIRequiredDeviceCapabilities @@ -36,5 +36,12 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + diff --git a/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Prefix.pch b/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Prefix.pch index 39abe8d..e1d9800 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Prefix.pch +++ b/iAdSuite/TabbedBanner/TabbedBanner/TabbedBanner-Prefix.pch @@ -4,10 +4,10 @@ #import -#ifndef __IPHONE_4_2 -#warning "This project uses features only available in iOS SDK 4.2 and later." -#elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_2 -#error "This project requires features only available in iOS 4.2 and later." +#ifndef __IPHONE_6_0 +#warning "This project uses features only available in iOS SDK 6.0 and later." +#elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 +#error "This project requires features only available in iOS 5.0 and later." #endif #ifdef __OBJC__ diff --git a/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.h b/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.h index 32fd27a..dbd8f94 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.h +++ b/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.h @@ -1,57 +1,55 @@ -/* File: TextViewController.h */ -/* Abstract: A simple view controller that manages a content view and an ADBannerView */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: TextViewController.h +Abstract: A simple view controller that manages a content view and an ADBannerView + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import #import -#import "AppDelegate.h" -@interface TextViewController : UIViewController +@interface TextViewController : UIViewController -@property(nonatomic, strong) IBOutlet UIView *contentView; -@property(nonatomic, strong) IBOutlet UITextView *textView; -@property(nonatomic, strong) IBOutlet UILabel *timerLabel; -@property(nonatomic, copy) NSString *text; +@property (nonatomic, copy) NSString *text; @end diff --git a/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.m b/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.m index 57aa6ce..08ab42c 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.m +++ b/iAdSuite/TabbedBanner/TabbedBanner/TextViewController.m @@ -1,107 +1,97 @@ -/* File: TextViewController.m */ -/* Abstract: A simple view controller that manages a content view and an ADBannerView */ -/* Version: 2.0 */ -/* */ -/* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple */ -/* Inc. ("Apple") in consideration of your agreement to the following */ -/* terms, and your use, installation, modification or redistribution of */ -/* this Apple software constitutes acceptance of these terms. If you do */ -/* not agree with these terms, please do not use, install, modify or */ -/* redistribute this Apple software. */ -/* */ -/* In consideration of your agreement to abide by the following terms, and */ -/* subject to these terms, Apple grants you a personal, non-exclusive */ -/* license, under Apple's copyrights in this original Apple software (the */ -/* "Apple Software"), to use, reproduce, modify and redistribute the Apple */ -/* Software, with or without modifications, in source and/or binary forms; */ -/* provided that if you redistribute the Apple Software in its entirety and */ -/* without modifications, you must retain this notice and the following */ -/* text and disclaimers in all such redistributions of the Apple Software. */ -/* Neither the name, trademarks, service marks or logos of Apple Inc. may */ -/* be used to endorse or promote products derived from the Apple Software */ -/* without specific prior written permission from Apple. Except as */ -/* expressly stated in this notice, no other rights or licenses, express or */ -/* implied, are granted by Apple herein, including but not limited to any */ -/* patent rights that may be infringed by your derivative works or by other */ -/* works in which the Apple Software may be incorporated. */ -/* */ -/* The Apple Software is provided by Apple on an "AS IS" basis. APPLE */ -/* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION */ -/* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND */ -/* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. */ -/* */ -/* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL */ -/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, */ -/* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED */ -/* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), */ -/* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* Copyright (C) 2011 Apple Inc. All Rights Reserved. */ -/* */ +/* + File: TextViewController.m +Abstract: A simple view controller that manages a content view and an ADBannerView + Version: 2.1 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import "TextViewController.h" +#import "BannerViewController.h" -@implementation TextViewController -{ - ADBannerView *_bannerView; +@interface TextViewController () + +@property (nonatomic, strong) IBOutlet UITextView *textView; +@property (nonatomic, strong) IBOutlet UILabel *timerLabel; + +@end + +@implementation TextViewController { NSTimer *_timer; CFTimeInterval _ticks; } -@synthesize contentView = _contentView; -@synthesize textView = _textView; -@synthesize timerLabel = _timerLabel; -@synthesize text = _text; - -- (id)init +- (instancetype)init { self = [super initWithNibName:@"TextViewController" bundle:nil]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willBeginBannerViewActionNotification:) name:BannerViewActionWillBegin object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishBannerViewActionNotification:) name:BannerViewActionDidFinish object:nil]; - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; } return self; } - (void)dealloc { - [_timer invalidate]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void)layoutAnimated:(BOOL)animated +- (void)setText:(NSString *)text { - if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait; - } else { - _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape; - } - - CGRect contentFrame = self.view.bounds; - CGRect bannerFrame = _bannerView.frame; - if (_bannerView.bannerLoaded) { - contentFrame.size.height -= _bannerView.frame.size.height; - bannerFrame.origin.y = contentFrame.size.height; - } else { - bannerFrame.origin.y = contentFrame.size.height; + _text = [text copy]; + self.textView.text = text; +} + +- (void)startTimer +{ + if (_timer == nil) { + _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; } - - [UIView animateWithDuration:animated ? 0.25 : 0.0 animations:^{ - _contentView.frame = contentFrame; - [_contentView layoutIfNeeded]; - _bannerView.frame = bannerFrame; - }]; } -- (void)setText:(NSString *)text +- (void)stopTimer { - _text = [text copy]; - self.textView.text = text; + [_timer invalidate]; + _timer = nil; } - (void)timerTick:(NSTimer *)timer @@ -121,50 +111,38 @@ - (void)viewDidLoad self.textView.text = self.text; } -- (void)viewDidUnload +- (void)viewDidAppear:(BOOL)animated { - [super viewDidUnload]; - self.contentView = nil; - self.textView = nil; - self.timerLabel = nil; + [super viewDidAppear:animated]; + [self startTimer]; } -- (void)viewDidAppear:(BOOL)animated +- (void)viewDidDisappear:(BOOL)animated { - [self layoutAnimated:NO]; + [super viewDidDisappear:animated]; + [self stopTimer]; } +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } +#endif -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +- (NSUInteger)supportedInterfaceOrientations { - [self layoutAnimated:duration > 0.0]; -} - -- (void)showBannerView:(ADBannerView *)bannerView animated:(BOOL)animated -{ - _bannerView = bannerView; - [self.view addSubview:_bannerView]; - [self layoutAnimated:animated]; -} - -- (void)hideBannerView:(ADBannerView *)bannerView animated:(BOOL)animated -{ - _bannerView = nil; - [self layoutAnimated:animated]; + return UIInterfaceOrientationMaskAll; } - (void)willBeginBannerViewActionNotification:(NSNotification *)notification { - [_timer invalidate]; + [self stopTimer]; } - (void)didFinishBannerViewActionNotification:(NSNotification *)notification { - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; + [self startTimer]; } @end diff --git a/iAdSuite/TabbedBanner/TabbedBanner/main.m b/iAdSuite/TabbedBanner/TabbedBanner/main.m index 4401416..1bf6484 100644 --- a/iAdSuite/TabbedBanner/TabbedBanner/main.m +++ b/iAdSuite/TabbedBanner/TabbedBanner/main.m @@ -1,10 +1,49 @@ -// -// main.m -// TabbedBanner -// -// Created by David Duncan on 8/22/11. -// Copyright (c) 2011 __MyCompanyName__. All rights reserved. -// +/* + File: main.m + Abstract: Main entry point + Version: 2.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2012 Apple Inc. All Rights Reserved. + +*/ #import diff --git a/iAdSuite/iAdSuite.xcworkspace/contents.xcworkspacedata b/iAdSuite/iAdSuite.xcworkspace/contents.xcworkspacedata index c407404..89b9f31 100644 --- a/iAdSuite/iAdSuite.xcworkspace/contents.xcworkspacedata +++ b/iAdSuite/iAdSuite.xcworkspace/contents.xcworkspacedata @@ -8,15 +8,15 @@ location = "group:BasicBanner/BasicBanner.xcodeproj"> + location = "group:ContainerBanner/ContainerBanner.xcodeproj"> + location = "group:SplitNavigationBanner/SplitNavigationBanner.xcodeproj"> + location = "group:TabbedBanner/TabbedBanner.xcodeproj"> + location = "group:MediumRectBanner/MediumRectBanner.xcodeproj"> diff --git a/iPhoneACFileConvertTest.zip b/iPhoneACFileConvertTest.zip new file mode 100644 index 0000000..a4aa7dd Binary files /dev/null and b/iPhoneACFileConvertTest.zip differ diff --git a/iPhoneACFileConvertTest/AudioConverterFileConvert.cpp b/iPhoneACFileConvertTest/AudioConverterFileConvert.cpp new file mode 100644 index 0000000..11b7c82 --- /dev/null +++ b/iPhoneACFileConvertTest/AudioConverterFileConvert.cpp @@ -0,0 +1,689 @@ +/* + File: AudioConverterFileConvert.cpp + Abstract: Demonstrates converting audio using AudioConverterFillComplexBuffer. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +// standard includes +#include + +// helpers +#include "CAXException.h" +#include "CAStreamBasicDescription.h" + +#include + +/* + +For more information on the importance of interruption handling and Audio Session setup when performing offline +encoding please see the Audio Session Programming Guide. + +Offline format conversion requires interruption handling. Specifically, you must handle interruptions at the audio data buffer level. + +By way of background, you can use a hardware assisted-codec—on certain devices—to encode linear PCM audio to AAC format. +The codec is available on the iPhone 3GS and on the iPod touch (2nd generation), but not on older models. You use the codec as part +of an Audio Converter object (of type AudioConverterRef). +For information on these opaque types, refer to Audio Converter Services Reference and Extended Audio File Services Reference. + +To handle an interruption during hardware-assisted encoding, take two things into account: + +1. The codec may or may not be able to resume encoding after the interruption ends. +2. The codec may be unavailable, probably due to an interruption. + +Encoding takes place as you repeatedly call the AudioConverterFillComplexBuffer function supplying new buffers of input audio data via the input data procedure +producing buffers of audio encoded in the output format. +To handle an interruption, you respond to the function’s result code, as described here: + +• kAudioConverterErr_HardwareInUse — This result code indicates that the underlying hardware codec has become unavailable, probably due to an interruption. +In this case, your application must stop calling AudioConverterFillComplexBuffer. If you can resume conversion, wait for an interruption-ended call from +the audio session. In your interruption-end handler, reactivate the session and then resume converting the audio data. + +To check if the AAC codec can resume, obtain the value of the associated converter’s kAudioConverterPropertyCanResumeFromInterruption property. +The value is 1 (can resume) or 0 (cannot resume). You can obtain this value any time after instantiating the converter—immediately after instantiation, +upon interruption, or after interruption ends. + +If the converter cannot resume, then on interruption you must abandon the conversion. After the interruption ends, or after the user relaunches your application +and indicates they want to resume conversion, re-instantiate the extended audio file object and perform the conversion again. + +*/ + +#pragma mark- Thread State +/* Since we perform conversion in a background thread, we must ensure that we handle interruptions appropriately. + In this sample we're using a mutex protected variable tracking thread states. The background conversion threads state transistions from Done to Running + to Done unless we've been interrupted in which case we are Paused blocking the conversion thread and preventing further calls + to AudioConverterFillComplexBuffer (since it would fail if we were using the hardware codec). + Once the interruption has ended, we unblock the background thread as the state transitions to Running once again. + Any errors returned from AudioConverterFillComplexBuffer must be handled appropriately. Additionally, if the Audio Converter cannot + resume conversion after an interruption, you should not call AudioConverterFillComplexBuffer again. +*/ + +static pthread_mutex_t sStateLock; // protects sState +static pthread_cond_t sStateChanged; // signals when interruption thread unblocks conversion thread +enum ThreadStates { + kStateRunning, + kStatePaused, + kStateDone +}; +static ThreadStates sState; + +// initialize the thread state +void ThreadStateInitalize() +{ + int rc; + + assert([NSThread isMainThread]); + + rc = pthread_mutex_init(&sStateLock, NULL); + assert(rc == 0); + + rc = pthread_cond_init(&sStateChanged, NULL); + assert(rc == 0); + + sState = kStateDone; +} + +// handle begin interruption - transition to kStatePaused +void ThreadStateBeginInterruption() +{ + int rc; + + assert([NSThread isMainThread]); + + rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + if (sState == kStateRunning) { + sState = kStatePaused; + } + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// handle end interruption - transition to kStateRunning +void ThreadStateEndInterruption() +{ + int rc; + + assert([NSThread isMainThread]); + + rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + if (sState == kStatePaused) { + sState = kStateRunning; + + rc = pthread_cond_signal(&sStateChanged); + assert(rc == 0); + } + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// set state to kStateRunning +void ThreadStateSetRunning() +{ + int rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + assert(sState == kStateDone); + sState = kStateRunning; + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// block for state change to kStateRunning +Boolean ThreadStatePausedCheck() +{ + Boolean wasInterrupted = false; + + int rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + assert(sState != kStateDone); + + while (sState == kStatePaused) { + rc = pthread_cond_wait(&sStateChanged, &sStateLock); + assert(rc == 0); + wasInterrupted = true; + } + + // we must be running or something bad has happened + assert(sState == kStateRunning); + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); + + return wasInterrupted; +} + +void ThreadStateSetDone() +{ + int rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + assert(sState != kStateDone); + sState = kStateDone; + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// *********************** +#pragma mark- Converter +/* The main Audio Conversion function using AudioConverter */ + +enum { + kMyAudioConverterErr_CannotResumeFromInterruptionError = 'CANT', + eofErr = -39 // End of file +}; + +typedef struct { + AudioFileID srcFileID; + SInt64 srcFilePos; + char * srcBuffer; + UInt32 srcBufferSize; + CAStreamBasicDescription srcFormat; + UInt32 srcSizePerPacket; + UInt32 numPacketsPerRead; + AudioStreamPacketDescription *packetDescriptions; +} AudioFileIO, *AudioFileIOPtr; + +#pragma mark- + +// Input data proc callback +static OSStatus EncoderDataProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) +{ + AudioFileIOPtr afio = (AudioFileIOPtr)inUserData; + OSStatus error; + + // figure out how much to read + UInt32 maxPackets = afio->srcBufferSize / afio->srcSizePerPacket; + if (*ioNumberDataPackets > maxPackets) *ioNumberDataPackets = maxPackets; + + // read from the file + UInt32 outNumBytes; + error = AudioFileReadPackets(afio->srcFileID, false, &outNumBytes, afio->packetDescriptions, afio->srcFilePos, ioNumberDataPackets, afio->srcBuffer); + if (eofErr == error) error = noErr; + if (error) { printf ("Input Proc Read error: %ld (%4.4s)\n", error, (char*)&error); return error; } + + //printf("Input Proc: Read %lu packets, at position %lld size %lu\n", *ioNumberDataPackets, afio->srcFilePos, outNumBytes); + + // advance input file packet position + afio->srcFilePos += *ioNumberDataPackets; + + // put the data pointer into the buffer list + ioData->mBuffers[0].mData = afio->srcBuffer; + ioData->mBuffers[0].mDataByteSize = outNumBytes; + ioData->mBuffers[0].mNumberChannels = afio->srcFormat.mChannelsPerFrame; + + // don't forget the packet descriptions if required + if (outDataPacketDescription) { + if (afio->packetDescriptions) { + *outDataPacketDescription = afio->packetDescriptions; + } else { + *outDataPacketDescription = NULL; + } + } + + return error; +} + +#pragma mark- + +// Some audio formats have a magic cookie associated with them which is required to decompress audio data +// When converting audio data you must check to see if the format of the data has a magic cookie +// If the audio data format has a magic cookie associated with it, you must add this information to anAudio Converter +// using AudioConverterSetProperty and kAudioConverterDecompressionMagicCookie to appropriately decompress the data +// http://developer.apple.com/mac/library/qa/qa2001/qa1318.html +static void ReadCookie(AudioFileID sourceFileID, AudioConverterRef converter) +{ + // grab the cookie from the source file and set it on the converter + UInt32 cookieSize = 0; + OSStatus error = AudioFileGetPropertyInfo(sourceFileID, kAudioFilePropertyMagicCookieData, &cookieSize, NULL); + + // if there is an error here, then the format doesn't have a cookie - this is perfectly fine as some formats do not + if (noErr == error && 0 != cookieSize) { + char* cookie = new char [cookieSize]; + + error = AudioFileGetProperty(sourceFileID, kAudioFilePropertyMagicCookieData, &cookieSize, cookie); + if (noErr == error) { + error = AudioConverterSetProperty(converter, kAudioConverterDecompressionMagicCookie, cookieSize, cookie); + if (error) printf("Could not Set kAudioConverterDecompressionMagicCookie on the Audio Converter!\n"); + } else { + printf("Could not Get kAudioFilePropertyMagicCookieData from source file!\n"); + } + + delete [] cookie; + } +} + +// Some audio formats have a magic cookie associated with them which is required to decompress audio data +// When converting audio, a magic cookie may be returned by the Audio Converter so that it may be stored along with +// the output data -- This is done so that it may then be passed back to the Audio Converter at a later time as required +static void WriteCookie(AudioConverterRef converter, AudioFileID destinationFileID) +{ + // grab the cookie from the converter and write it to the destinateion file + UInt32 cookieSize = 0; + OSStatus error = AudioConverterGetPropertyInfo(converter, kAudioConverterCompressionMagicCookie, &cookieSize, NULL); + + // if there is an error here, then the format doesn't have a cookie - this is perfectly fine as some formats do not + if (noErr == error && 0 != cookieSize) { + char* cookie = new char [cookieSize]; + + error = AudioConverterGetProperty(converter, kAudioConverterCompressionMagicCookie, &cookieSize, cookie); + if (noErr == error) { + error = AudioFileSetProperty(destinationFileID, kAudioFilePropertyMagicCookieData, cookieSize, cookie); + if (noErr == error) { + printf("Writing magic cookie to destination file: %ld\n", cookieSize); + } else { + printf("Even though some formats have cookies, some files don't take them and that's OK\n"); + } + } else { + printf("Could not Get kAudioConverterCompressionMagicCookie from Audio Converter!\n"); + } + + delete [] cookie; + } +} + +// Write output channel layout to destination file +static void WriteDestinationChannelLayout(AudioConverterRef converter, AudioFileID sourceFileID, AudioFileID destinationFileID) +{ + UInt32 layoutSize = 0; + bool layoutFromConverter = true; + + OSStatus error = AudioConverterGetPropertyInfo(converter, kAudioConverterOutputChannelLayout, &layoutSize, NULL); + + // if the Audio Converter doesn't have a layout see if the input file does + if (error || 0 == layoutSize) { + error = AudioFileGetPropertyInfo(sourceFileID, kAudioFilePropertyChannelLayout, &layoutSize, NULL); + layoutFromConverter = false; + } + + if (noErr == error && 0 != layoutSize) { + char* layout = new char[layoutSize]; + + if (layoutFromConverter) { + error = AudioConverterGetProperty(converter, kAudioConverterOutputChannelLayout, &layoutSize, layout); + if (error) printf("Could not Get kAudioConverterOutputChannelLayout from Audio Converter!\n"); + } else { + error = AudioFileGetProperty(sourceFileID, kAudioFilePropertyChannelLayout, &layoutSize, layout); + if (error) printf("Could not Get kAudioFilePropertyChannelLayout from source file!\n"); + } + + if (noErr == error) { + error = AudioFileSetProperty(destinationFileID, kAudioFilePropertyChannelLayout, layoutSize, layout); + if (noErr == error) { + printf("Writing channel layout to destination file: %ld\n", layoutSize); + } else { + printf("Even though some formats have layouts, some files don't take them and that's OK\n"); + } + } + + delete [] layout; + } +} + +// Sets the packet table containing information about the number of valid frames in a file and where they begin and end +// for the file types that support this information. +// Calling this function makes sure we write out the priming and remainder details to the destination file +static void WritePacketTableInfo(AudioConverterRef converter, AudioFileID destinationFileID) +{ + UInt32 isWritable; + UInt32 dataSize; + OSStatus error = AudioFileGetPropertyInfo(destinationFileID, kAudioFilePropertyPacketTableInfo, &dataSize, &isWritable); + if (noErr == error && isWritable) { + + AudioConverterPrimeInfo primeInfo; + dataSize = sizeof(primeInfo); + + // retrieve the leadingFrames and trailingFrames information from the converter, + error = AudioConverterGetProperty(converter, kAudioConverterPrimeInfo, &dataSize, &primeInfo); + if (noErr == error) { + // we have some priming information to write out to the destination file + /* The total number of packets in the file times the frames per packet (or counting each packet's + frames individually for a variable frames per packet format) minus mPrimingFrames, minus + mRemainderFrames, should equal mNumberValidFrames. + */ + AudioFilePacketTableInfo pti; + dataSize = sizeof(pti); + error = AudioFileGetProperty(destinationFileID, kAudioFilePropertyPacketTableInfo, &dataSize, &pti); + if (noErr == error) { + // there's priming to write out to the file + UInt64 totalFrames = pti.mNumberValidFrames + pti.mPrimingFrames + pti.mRemainderFrames; // get the total number of frames from the output file + printf("Total number of frames from output file: %lld\n", totalFrames); + + pti.mPrimingFrames = primeInfo.leadingFrames; + pti.mRemainderFrames = primeInfo.trailingFrames; + pti.mNumberValidFrames = totalFrames - pti.mPrimingFrames - pti.mRemainderFrames; + + error = AudioFileSetProperty(destinationFileID, kAudioFilePropertyPacketTableInfo, sizeof(pti), &pti); + if (noErr == error) { + printf("Writing packet table information to destination file: %ld\n", sizeof(pti)); + printf(" Total valid frames: %lld\n", pti.mNumberValidFrames); + printf(" Priming frames: %ld\n", pti.mPrimingFrames); + printf(" Remainder frames: %ld\n", pti.mRemainderFrames); + } else { + printf("Some audio files can't contain packet table information and that's OK\n"); + } + } else { + printf("Getting kAudioFilePropertyPacketTableInfo error: %ld\n", error); + } + } else { + printf("No kAudioConverterPrimeInfo available and that's OK\n"); + } + } else { + printf("GetPropertyInfo for kAudioFilePropertyPacketTableInfo error: %ld, isWritable: %ld\n", error, isWritable); + } +} + +#pragma mark- + +OSStatus DoConvertFile(CFURLRef sourceURL, CFURLRef destinationURL, OSType outputFormat, Float64 outputSampleRate) +{ + AudioFileID sourceFileID = 0; + AudioFileID destinationFileID = 0; + AudioConverterRef converter = NULL; + Boolean canResumeFromInterruption = true; // we can continue unless told otherwise + + CAStreamBasicDescription srcFormat, dstFormat; + AudioFileIO afio = {}; + + char *outputBuffer = NULL; + AudioStreamPacketDescription *outputPacketDescriptions = NULL; + + OSStatus error = noErr; + + // in this sample we should never be on the main thread here + assert(![NSThread isMainThread]); + + // transition thread state to kStateRunning before continuing + ThreadStateSetRunning(); + + printf("\nDoConvertFile\n"); + + try { + // get the source file + XThrowIfError(AudioFileOpenURL(sourceURL, kAudioFileReadPermission, 0, &sourceFileID), "AudioFileOpenURL failed"); + + // get the source data format + UInt32 size = sizeof(srcFormat); + XThrowIfError(AudioFileGetProperty(sourceFileID, kAudioFilePropertyDataFormat, &size, &srcFormat), "couldn't get source data format"); + + // setup the output file format + dstFormat.mSampleRate = (outputSampleRate == 0 ? srcFormat.mSampleRate : outputSampleRate); // set sample rate + if (outputFormat == kAudioFormatLinearPCM) { + // if the output format is PC create a 16-bit int PCM file format description as an example + dstFormat.mFormatID = outputFormat; + dstFormat.mChannelsPerFrame = srcFormat.NumberChannels(); + dstFormat.mBitsPerChannel = 16; + dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame; + dstFormat.mFramesPerPacket = 1; + dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian + } else { + // compressed format - need to set at least format, sample rate and channel fields for kAudioFormatProperty_FormatInfo + dstFormat.mFormatID = outputFormat; + dstFormat.mChannelsPerFrame = (outputFormat == kAudioFormatiLBC ? 1 : srcFormat.NumberChannels()); // for iLBC num channels must be 1 + + // use AudioFormat API to fill out the rest of the description + size = sizeof(dstFormat); + XThrowIfError(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &dstFormat), "couldn't create destination data format"); + } + + printf("Source File format: "); srcFormat.Print(); + printf("Destination format: "); dstFormat.Print(); + + // create the AudioConverter + + XThrowIfError(AudioConverterNew(&srcFormat, &dstFormat, &converter), "AudioConverterNew failed!"); + + // if the source has a cookie, get it and set it on the Audio Converter + ReadCookie(sourceFileID, converter); + + // get the actual formats back from the Audio Converter + size = sizeof(srcFormat); + XThrowIfError(AudioConverterGetProperty(converter, kAudioConverterCurrentInputStreamDescription, &size, &srcFormat), "AudioConverterGetProperty kAudioConverterCurrentInputStreamDescription failed!"); + + size = sizeof(dstFormat); + XThrowIfError(AudioConverterGetProperty(converter, kAudioConverterCurrentOutputStreamDescription, &size, &dstFormat), "AudioConverterGetProperty kAudioConverterCurrentOutputStreamDescription failed!"); + + printf("Formats returned from AudioConverter:\n"); + printf(" Source format: "); srcFormat.Print(); + printf(" Destination File format: "); dstFormat.Print(); + + // if encoding to AAC set the bitrate to 192k which is a nice value for this demo + // kAudioConverterEncodeBitRate is a UInt32 value containing the number of bits per second to aim for when encoding data + if (dstFormat.mFormatID == kAudioFormatMPEG4AAC) { + UInt32 outputBitRate = 192000; // 192k + UInt32 propSize = sizeof(outputBitRate); + + // ignore errors as setting may be invalid depending on format specifics such as samplerate + AudioConverterSetProperty(converter, kAudioConverterEncodeBitRate, propSize, &outputBitRate); + + // get it back and print it out + AudioConverterGetProperty(converter, kAudioConverterEncodeBitRate, &propSize, &outputBitRate); + printf ("AAC Encode Bitrate: %ld\n", outputBitRate); + } + + // can the Audio Converter resume conversion after an interruption? + // this property may be queried at any time after construction of the Audio Converter after setting its output format + // there's no clear reason to prefer construction time, interruption time, or potential resumption time but we prefer + // construction time since it means less code to execute during or after interruption time + UInt32 canResume = 0; + size = sizeof(canResume); + error = AudioConverterGetProperty(converter, kAudioConverterPropertyCanResumeFromInterruption, &size, &canResume); + if (noErr == error) { + // we recieved a valid return value from the GetProperty call + // if the property's value is 1, then the codec CAN resume work following an interruption + // if the property's value is 0, then interruptions destroy the codec's state and we're done + + if (0 == canResume) canResumeFromInterruption = false; + + printf("Audio Converter %s continue after interruption!\n", (canResumeFromInterruption == 0 ? "CANNOT" : "CAN")); + } else { + // if the property is unimplemented (kAudioConverterErr_PropertyNotSupported, or paramErr returned in the case of PCM), + // then the codec being used is not a hardware codec so we're not concerned about codec state + // we are always going to be able to resume conversion after an interruption + + if (kAudioConverterErr_PropertyNotSupported == error) { + printf("kAudioConverterPropertyCanResumeFromInterruption property not supported\n"); + } else { + printf("AudioConverterGetProperty kAudioConverterPropertyCanResumeFromInterruption result %ld, paramErr is OK if PCM\n", error); + } + + error = noErr; + } + + // create the destination file + XThrowIfError(AudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, kAudioFileFlags_EraseFile, &destinationFileID), "AudioFileCreateWithURL failed!"); + + // set up source buffers and data proc info struct + afio.srcFileID = sourceFileID; + afio.srcBufferSize = 32768; + afio.srcBuffer = new char [afio.srcBufferSize]; + afio.srcFilePos = 0; + afio.srcFormat = srcFormat; + + if (srcFormat.mBytesPerPacket == 0) { + // if the source format is VBR, we need to get the maximum packet size + // use kAudioFilePropertyPacketSizeUpperBound which returns the theoretical maximum packet size + // in the file (without actually scanning the whole file to find the largest packet, + // as may happen with kAudioFilePropertyMaximumPacketSize) + size = sizeof(afio.srcSizePerPacket); + XThrowIfError(AudioFileGetProperty(sourceFileID, kAudioFilePropertyPacketSizeUpperBound, &size, &afio.srcSizePerPacket), "AudioFileGetProperty kAudioFilePropertyPacketSizeUpperBound failed!"); + + // how many packets can we read for our buffer size? + afio.numPacketsPerRead = afio.srcBufferSize / afio.srcSizePerPacket; + + // allocate memory for the PacketDescription structures describing the layout of each packet + afio.packetDescriptions = new AudioStreamPacketDescription [afio.numPacketsPerRead]; + } else { + // CBR source format + afio.srcSizePerPacket = srcFormat.mBytesPerPacket; + afio.numPacketsPerRead = afio.srcBufferSize / afio.srcSizePerPacket; + afio.packetDescriptions = NULL; + } + + // set up output buffers + UInt32 outputSizePerPacket = dstFormat.mBytesPerPacket; // this will be non-zero if the format is CBR + UInt32 theOutputBufSize = 32768; + outputBuffer = new char[theOutputBufSize]; + + if (outputSizePerPacket == 0) { + // if the destination format is VBR, we need to get max size per packet from the converter + UInt32 size = sizeof(outputSizePerPacket); + XThrowIfError(AudioConverterGetProperty(converter, kAudioConverterPropertyMaximumOutputPacketSize, &size, &outputSizePerPacket), "AudioConverterGetProperty kAudioConverterPropertyMaximumOutputPacketSize failed!"); + + // allocate memory for the PacketDescription structures describing the layout of each packet + outputPacketDescriptions = new AudioStreamPacketDescription [theOutputBufSize / outputSizePerPacket]; + } + UInt32 numOutputPackets = theOutputBufSize / outputSizePerPacket; + + // if the destination format has a cookie, get it and set it on the output file + WriteCookie(converter, destinationFileID); + + // write destination channel layout + if (srcFormat.mChannelsPerFrame > 2) { + WriteDestinationChannelLayout(converter, sourceFileID, destinationFileID); + } + + UInt64 totalOutputFrames = 0; // used for debgging printf + SInt64 outputFilePos = 0; + + // loop to convert data + printf("Converting...\n"); + while (1) { + + // set up output buffer list + AudioBufferList fillBufList; + fillBufList.mNumberBuffers = 1; + fillBufList.mBuffers[0].mNumberChannels = dstFormat.mChannelsPerFrame; + fillBufList.mBuffers[0].mDataByteSize = theOutputBufSize; + fillBufList.mBuffers[0].mData = outputBuffer; + + // this will block if we're interrupted + Boolean wasInterrupted = ThreadStatePausedCheck(); + + if ((error || wasInterrupted) && (false == canResumeFromInterruption)) { + // this is our interruption termination condition + // an interruption has occured but the Audio Converter cannot continue + error = kMyAudioConverterErr_CannotResumeFromInterruptionError; + break; + } + + // convert data + UInt32 ioOutputDataPackets = numOutputPackets; + error = AudioConverterFillComplexBuffer(converter, EncoderDataProc, &afio, &ioOutputDataPackets, &fillBufList, outputPacketDescriptions); + // if interrupted in the process of the conversion call, we must handle the error appropriately + if (error) { + if (kAudioConverterErr_HardwareInUse == error) { + printf("Audio Converter returned kAudioConverterErr_HardwareInUse!\n"); + } else { + XThrowIfError(error, "AudioConverterFillComplexBuffer error!"); + } + } else { + if (ioOutputDataPackets == 0) { + // this is the EOF conditon + error = noErr; + break; + } + } + + if (noErr == error) { + // write to output file + UInt32 inNumBytes = fillBufList.mBuffers[0].mDataByteSize; + XThrowIfError(AudioFileWritePackets(destinationFileID, false, inNumBytes, outputPacketDescriptions, outputFilePos, &ioOutputDataPackets, outputBuffer), "AudioFileWritePackets failed!"); + + //printf("Convert Output: Write %lu packets at position %lld, size: %ld\n", ioOutputDataPackets, outputFilePos, inNumBytes); + + // advance output file packet position + outputFilePos += ioOutputDataPackets; + + if (dstFormat.mFramesPerPacket) { + // the format has constant frames per packet + totalOutputFrames += (ioOutputDataPackets * dstFormat.mFramesPerPacket); + } else { + // variable frames per packet require doing this for each packet (adding up the number of sample frames of data in each packet) + for (UInt32 i = 0; i < ioOutputDataPackets; ++i) + totalOutputFrames += outputPacketDescriptions[i].mVariableFramesInPacket; + } + } + } // while + + if (noErr == error) { + // write out any of the leading and trailing frames for compressed formats only + if (dstFormat.mBitsPerChannel == 0) { + // our output frame count should jive with + printf("Total number of output frames counted: %lld\n", totalOutputFrames); + WritePacketTableInfo(converter, destinationFileID); + } + + // write the cookie again - sometimes codecs will update cookies at the end of a conversion + WriteCookie(converter, destinationFileID); + } + } + catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + error = e.mError; + } + + // cleanup + if (converter) AudioConverterDispose(converter); + if (destinationFileID) AudioFileClose(destinationFileID); + if (sourceFileID) AudioFileClose(sourceFileID); + + if (afio.srcBuffer) delete [] afio.srcBuffer; + if (afio.packetDescriptions) delete [] afio.packetDescriptions; + if (outputBuffer) delete [] outputBuffer; + if (outputPacketDescriptions) delete [] outputPacketDescriptions; + + // transition thread state to kStateDone before continuing + ThreadStateSetDone(); + + return error; +} \ No newline at end of file diff --git a/iPhoneACFileConvertTest/Classes/MyViewController.h b/iPhoneACFileConvertTest/Classes/MyViewController.h new file mode 100755 index 0000000..c4fc7f9 --- /dev/null +++ b/iPhoneACFileConvertTest/Classes/MyViewController.h @@ -0,0 +1,96 @@ +/* + File: MyViewController.h + Abstract: The main view controller of this app. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +// includes +#import +#import +#import +#import + +// helpers +#include "CAXException.h" +#include "CAStreamBasicDescription.h" + +@interface MyViewController : UIViewController +{ + IBOutlet UIView *instructionsView; + IBOutlet UIWebView *webView; + IBOutlet UIView *contentView; + + IBOutlet UILabel *fileInfo; + + IBOutlet UISegmentedControl *outputFormatSelector; + IBOutlet UISegmentedControl *outputSampleRateSelector; + + IBOutlet UIButton *startButton; + IBOutlet UIActivityIndicatorView *activityIndicator; + + UIBarButtonItem *flipButton; + UIBarButtonItem *doneButton; + + NSString *destinationFilePath; + CFURLRef sourceURL; + CFURLRef destinationURL; + OSType outputFormat; + Float64 sampleRate; +} + +@property (readonly, nonatomic) IBOutlet UIView *instructionsView; +@property (readonly, nonatomic) IBOutlet UIWebView *webView; +@property (readonly, nonatomic) IBOutlet UIView *contentView; +@property (readonly, nonatomic) IBOutlet UISegmentedControl *outputFormatSelector; +@property (readonly, nonatomic) IBOutlet UISegmentedControl *outputSampleRateSelector; +@property (readonly, nonatomic) IBOutlet UIButton *startButton; +@property (readonly, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; + +@property (nonatomic, retain) UIBarButtonItem *flipButton; +@property (nonatomic, retain) UIBarButtonItem *doneButton; + +- (IBAction)segmentedControllerValueChanged:(id)sender; +- (IBAction)convertButtonPressed:(id)sender; + +@end \ No newline at end of file diff --git a/iPhoneACFileConvertTest/Classes/MyViewController.m b/iPhoneACFileConvertTest/Classes/MyViewController.m new file mode 100755 index 0000000..992be4d --- /dev/null +++ b/iPhoneACFileConvertTest/Classes/MyViewController.m @@ -0,0 +1,399 @@ +/* + File: MyViewController.m + Abstract: >The main view controller of this app. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MyViewController.h" + +extern OSStatus DoConvertFile(CFURLRef sourceURL, CFURLRef destinationURL, OSType outputFormat, Float64 outputSampleRate); + +#define kTransitionDuration 0.75 + +#pragma mark- + +static Boolean IsAACHardwareEncoderAvailable(void) +{ + Boolean isAvailable = false; + + // get an array of AudioClassDescriptions for all installed encoders for the given format + // the specifier is the format that we are interested in - this is 'aac ' in our case + UInt32 encoderSpecifier = kAudioFormatMPEG4AAC; + UInt32 size; + + OSStatus result = AudioFormatGetPropertyInfo(kAudioFormatProperty_Encoders, sizeof(encoderSpecifier), &encoderSpecifier, &size); + if (result) { printf("AudioFormatGetPropertyInfo kAudioFormatProperty_Encoders result %lu %4.4s\n", result, (char*)&result); return false; } + + UInt32 numEncoders = size / sizeof(AudioClassDescription); + AudioClassDescription encoderDescriptions[numEncoders]; + + result = AudioFormatGetProperty(kAudioFormatProperty_Encoders, sizeof(encoderSpecifier), &encoderSpecifier, &size, encoderDescriptions); + if (result) { printf("AudioFormatGetProperty kAudioFormatProperty_Encoders result %lu %4.4s\n", result, (char*)&result); return false; } + + for (UInt32 i=0; i < numEncoders; ++i) { + if (encoderDescriptions[i].mSubType == kAudioFormatMPEG4AAC && encoderDescriptions[i].mManufacturer == kAppleHardwareAudioCodecManufacturer) isAvailable = true; + } + + return isAvailable; +} + +static void UpdateFormatInfo(UILabel *inLabel, CFURLRef inFileURL) +{ + AudioFileID fileID; + + OSStatus result = AudioFileOpenURL(inFileURL, kAudioFileReadPermission, 0, &fileID); + if (noErr == result) { + CAStreamBasicDescription asbd; + UInt32 size = sizeof(asbd); + result = AudioFileGetProperty(fileID, kAudioFilePropertyDataFormat, &size, &asbd); + if (noErr == result) { + char formatID[5]; + CFStringRef lastPathComponent = CFURLCopyLastPathComponent(inFileURL); + *(UInt32 *)formatID = CFSwapInt32HostToBig(asbd.mFormatID); + + inLabel.text = [NSString stringWithFormat: @"%@ %4.4s %6.0f Hz (%d ch.)", lastPathComponent, formatID, asbd.mSampleRate, asbd.NumberChannels(), nil]; + CFRelease(lastPathComponent); + } else { + printf("AudioFileGetProperty kAudioFilePropertyDataFormat result %lu %4.4s\n", result, (char*)&result); + } + + AudioFileClose(fileID); + } else { + printf("AudioFileOpenURL failed! result %lu %4.4s\n", result, (char*)&result); + } +} + +#pragma mark- + +@implementation MyViewController + +@synthesize instructionsView, webView, contentView, outputFormatSelector, outputSampleRateSelector, startButton, activityIndicator, flipButton, doneButton; + +- (void)dealloc +{ + [instructionsView release]; + [webView release]; + [contentView release]; + + [fileInfo release]; + + [outputFormatSelector release]; + [outputSampleRateSelector release]; + + [startButton release]; + [activityIndicator release]; + + [flipButton release]; + [doneButton release]; + + [destinationFilePath release]; + CFRelease(sourceURL); + CFRelease(destinationURL); + + [super dealloc]; +} + +- (void)viewDidLoad +{ + // create the URLs we'll use for source and destination + NSString *source = [[NSBundle mainBundle] pathForResource:@"sourcePCM" ofType:@"aif"]; + sourceURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)source, kCFURLPOSIXPathStyle, false); + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory]; + destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); + + // load up the info text + NSString *infoSouceFile = [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]; + NSString *infoText = [NSString stringWithContentsOfFile:infoSouceFile encoding:NSUTF8StringEncoding error:nil]; + [self.webView loadHTMLString:infoText baseURL:nil]; + self.webView.backgroundColor = [UIColor whiteColor]; + + // set up start button + UIImage *greenImage = [[UIImage imageNamed:@"green_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + UIImage *redImage = [[UIImage imageNamed:@"red_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + + [startButton setBackgroundImage:greenImage forState:UIControlStateNormal]; + [startButton setBackgroundImage:redImage forState:UIControlStateDisabled]; + + // add the subview + [self.view addSubview:contentView]; + + // add our custom flip buttons as the nav bars custom right view + UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; + [infoButton addTarget:self action:@selector(flipAction:) forControlEvents:UIControlEventTouchUpInside]; + + flipButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + self.navigationItem.rightBarButtonItem = flipButton; + + // create our done button as the nav bar's custom right view for the flipped view (used later) + doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(flipAction:)]; + + // default output format + // sample rate of 0 indicates source file sample rate + outputFormat = kAudioFormatAppleLossless; + sampleRate = 0; + + // can we encode to AAC? + if (IsAACHardwareEncoderAvailable()) { + [self.outputFormatSelector setEnabled:YES forSegmentAtIndex:0]; + } else { + // even though not enabled in IB, this segment will still be enabled + // if not specifically turned off here which we'll assume is a bug + [self.outputFormatSelector setEnabled:NO forSegmentAtIndex:0]; + } + + UpdateFormatInfo(fileInfo, sourceURL); + +} + +- (void)didReceiveMemoryWarning +{ + // Invoke super's implementation to do the Right Thing, but also release the input controller since we can do that + // In practice this is unlikely to be used in this application, and it would be of little benefit, + // but the principle is the important thing. + + [super didReceiveMemoryWarning]; +} + +#pragma mark- Actions + +- (void)flipAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + + [UIView setAnimationTransition:([self.contentView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) + forView:self.view + cache:YES]; + + if ([self.instructionsView superview]) { + [self.instructionsView removeFromSuperview]; + [self.view addSubview:contentView]; + } else { + [self.contentView removeFromSuperview]; + [self.view addSubview:instructionsView]; + } + + [UIView commitAnimations]; + + // adjust our done/info buttons accordingly + if ([instructionsView superview]) { + self.navigationItem.rightBarButtonItem = doneButton; + } else { + self.navigationItem.rightBarButtonItem = flipButton; + } +} + +- (IBAction)convertButtonPressed:(id)sender +{ + // use kAudioSessionCategory_AudioProcessing category for offline conversion when not playing or recording audio at the same time + // if you are recording or playing audio at the same time you are encoding, use the same Audio Session category that you would normally + UInt32 audioCategory = kAudioSessionCategory_AudioProcessing; + OSStatus error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + if (error) { + printf("AudioSessionSetProperty kAudioSessionCategory_AudioProcessing failed! %ld\n", error); + + return; + } + + [self.startButton setTitle:@"Converting..." forState:UIControlStateDisabled]; + [startButton setEnabled:NO]; + + [self.activityIndicator startAnimating]; + + // run audio file code in a background thread + [self performSelectorInBackground:(@selector(convertAudio)) withObject:nil]; +} + +- (IBAction)segmentedControllerValueChanged:(id)sender +{ + switch ([sender tag]) { + case 0: + switch ([sender selectedSegmentIndex]) { + case 0: + outputFormat = kAudioFormatMPEG4AAC; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:2]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:3]; + break; + case 1: + outputFormat = kAudioFormatAppleIMA4; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:2]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:3]; + break; + case 2: + // iLBC sample rate is 8K + outputFormat = kAudioFormatiLBC; + [self.outputSampleRateSelector setSelectedSegmentIndex:2]; + [self.outputSampleRateSelector setEnabled:NO forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:NO forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:NO forSegmentAtIndex:3]; + break; + case 3: + outputFormat = kAudioFormatAppleLossless; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:2]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:3]; + break; + } + break; + case 1: + switch ([sender selectedSegmentIndex]) { + case 0: + sampleRate = 44100.0; + break; + case 1: + sampleRate = 22050.0; + break; + case 2: + sampleRate = 8000.0; + break; + case 3: + sampleRate = 0; + break; + } + break; + } +} + +#pragma mark- AVAudioPlayer + +- (void)updateUI +{ + [startButton setEnabled:YES]; + UpdateFormatInfo(fileInfo, sourceURL); +} + +- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error +{ + NSLog(@"audioPlayerDecodeErrorDidOccur %@", [error localizedDescription]); + [self audioPlayerDidFinishPlaying:player successfully:false]; +} + +- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player +{ + printf("Session interrupted! --- audioPlayerBeginInterruption ---\n"); + + // if the player was interrupted during playback we don't continue + [self audioPlayerDidFinishPlaying:player successfully:true]; +} + +- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag +{ + if (flag == NO) NSLog(@"Playback finished unsuccessfully!"); + + printf("audioPlayerDidFinishPlaying\n"); + + [player setDelegate:nil]; + [player release]; + + [self updateUI]; +} + +- (void)playAudio +{ + printf("playAudio\n"); + + UpdateFormatInfo(fileInfo, destinationURL); + [self.startButton setTitle:@"Playing Output File..." forState:UIControlStateDisabled]; + + // set category back to something that will allow us to play audio since kAudioSessionCategory_AudioProcessing will not + UInt32 audioCategory = kAudioSessionCategory_MediaPlayback; + OSStatus error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + if (error) { + printf("AudioSessionSetProperty kAudioSessionCategory_SoloAmbientSound failed! %ld\n", error); + + [self updateUI]; + + return; + } + + // play the result + AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:(NSURL *)destinationURL error:nil]; + if (nil == player) { + printf("AVAudioPlayer alloc failed! %ld\n", error); + + [self updateUI]; + + return; + } + + [player setDelegate:self]; + [player play]; +} + +#pragma mark- ExtAudioFile + +- (void)convertAudio +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + OSStatus error = DoConvertFile(sourceURL, destinationURL, outputFormat, sampleRate); + + [self.activityIndicator stopAnimating]; + + if (error) { + // delete output file if it exists since an error was returned during the conversion process + if ([[NSFileManager defaultManager] fileExistsAtPath:destinationFilePath]) { + [[NSFileManager defaultManager] removeItemAtPath:destinationFilePath error:nil]; + } + + printf("DoConvertFile failed! %ld\n", error); + [self performSelectorOnMainThread:(@selector(updateUI)) withObject:nil waitUntilDone:NO]; + } else { + [self performSelectorOnMainThread:(@selector(playAudio)) withObject:nil waitUntilDone:NO]; + } + + [pool release]; +} + +@end \ No newline at end of file diff --git a/iPhoneACFileConvertTest/Classes/iPhoneACFileConvertTest.h b/iPhoneACFileConvertTest/Classes/iPhoneACFileConvertTest.h new file mode 100644 index 0000000..57c8926 --- /dev/null +++ b/iPhoneACFileConvertTest/Classes/iPhoneACFileConvertTest.h @@ -0,0 +1,65 @@ +/* + File: iPhoneACFileConvertTest.h + Abstract: The application delegate. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "MyViewController.h" + +@interface ACFileConvertAppDelegate : NSObject { + UIWindow *window; + + IBOutlet UINavigationController *navigationController; + IBOutlet MyViewController *myViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet MyViewController *myViewController; + +@end + diff --git a/iPhoneACFileConvertTest/Classes/iPhoneACFileConvertTest.mm b/iPhoneACFileConvertTest/Classes/iPhoneACFileConvertTest.mm new file mode 100644 index 0000000..3a1170a --- /dev/null +++ b/iPhoneACFileConvertTest/Classes/iPhoneACFileConvertTest.mm @@ -0,0 +1,186 @@ +/* + File: iPhoneACFileConvertTest.mm + Abstract: The application delegate. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "iPhoneACFileConvertTest.h" + +extern void ThreadStateInitalize(); +extern void ThreadStateBeginInterruption(); +extern void ThreadStateEndInterruption(); + +@implementation ACFileConvertAppDelegate + +@synthesize window, navigationController, myViewController; + +#pragma mark -Audio Session Interruption Listener + +static void interruptionListener(void *inClientData, UInt32 inInterruption) +{ + printf("Session interrupted! --- %s ---\n", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + if (inInterruption == kAudioSessionBeginInterruption) { + ThreadStateBeginInterruption(); + } + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + AudioSessionSetActive(true); + ThreadStateEndInterruption(); + } +} + +#pragma mark -Audio Session Property Listener + +static void propertyListener(void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) +{ + if (inID == kAudioSessionProperty_AudioRouteChange) { + try { + CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inData; + + UInt32 routeChangeReason; + CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); + CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); + printf("Audio Route Change, Reason: %lu\n", routeChangeReason); + + CFStringRef routeChangeOldRouteRef = (CFStringRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute)); + printf("Old Route: "); + CFShow(routeChangeOldRouteRef); + + CFStringRef newRoute; + UInt32 size = sizeof(newRoute); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute), "couldn't get new audio route"); + if (newRoute) { + printf("New Route: "); + CFShow(newRoute); + } + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + } +} + +#pragma mark - +#pragma mark Application lifecycle + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after application launch + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; + + ThreadStateInitalize(); + + try { + // Initialize and configure the audio session + XThrowIfError(AudioSessionInitialize(NULL, NULL, interruptionListener, self), "couldn't initialize audio session"); + + // our default category -- we change this for conversion and playback appropriately + UInt32 audioCategory = kAudioSessionCategory_SoloAmbientSound; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory), "couldn't set audio category"); + + // we don't do anything special + XThrowIfError(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propertyListener, self), "couldn't set property listener"); + + // the session must be active for conversion including after an audio interruption + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active\n"); + + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + /* + Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + If your application supports background execution, called instead of applicationWillTerminate: when the user quits. + */ + + printf("applicationDidEnterBackground\n"); +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + /* + Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. + */ + + printf("applicationWillEnterForeground\n"); +} + +- (void)applicationWillResignActive:(UIApplication *)application { + /* + Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + */ + + ThreadStateBeginInterruption(); + OSStatus status = AudioSessionSetActive(false); + if (kAudioSessionNotActiveError == status) status = noErr; // system could have made us not active already if we're just playing back the test file for example, so ignore + printf("applicationWillResignActive Audio Session Deactivate error: %ld\n", status); +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + /* + Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + */ + + OSStatus status = AudioSessionSetActive(true); + ThreadStateEndInterruption(); + printf("applicationDidBecomeActive Audio Session Activate error: %ld\n", status); +} + +- (void)dealloc { + self.window = nil; + self.navigationController = nil; + self.myViewController = nil; + + [super dealloc]; +} + +@end diff --git a/iPhoneACFileConvertTest/Icon.png b/iPhoneACFileConvertTest/Icon.png new file mode 100644 index 0000000..88003bb Binary files /dev/null and b/iPhoneACFileConvertTest/Icon.png differ diff --git a/iPhoneACFileConvertTest/Info.plist b/iPhoneACFileConvertTest/Info.plist new file mode 100644 index 0000000..a50fcca --- /dev/null +++ b/iPhoneACFileConvertTest/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Icon.png + CFBundleIdentifier + ${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + eDTS + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/iPhoneACFileConvertTest/MainWindow.xib b/iPhoneACFileConvertTest/MainWindow.xib new file mode 100644 index 0000000..0bfe061 --- /dev/null +++ b/iPhoneACFileConvertTest/MainWindow.xib @@ -0,0 +1,821 @@ + + + + 768 + 9L30 + 680 + 949.54 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MCAwIDAAA + + NO + NO + YES + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 436} + + 1 + MSAxIDEAA + + NO + + + ACAudioFile Convert + + + + + + + + 268 + + YES + + + 268 + {{-2250, 100}, {42, 21}} + + NO + YES + NO + Label + + + 1 + 1.000000e+01 + + + + 292 + {{20, 20}, {280, 420}} + + + YES + YES + YES + + + {320, 460} + + 3 + MQA + + 2 + + + NO + + + + 292 + + YES + + + 292 + {{59, 283}, {201, 40}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + NO + + + + Q29udmVydCAmIFBsYXkgRmlsZS4uLg + + + + + 3 + MAA + + + + + -2147483356 + {{141, 348}, {37, 37}} + + NO + NO + NO + 0 + + + + 292 + {{59, 220}, {201, 30}} + + NO + NO + 1 + 2 + 4 + 3 + + YES + 44.1k + 22k + 8k + Source + + + YES + + + + + + + YES + + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + + 292 + {{59, 191}, {155, 21}} + + NO + YES + NO + Output Sample Rate: + + Helvetica + 1.200000e+01 + 16 + + + + 1 + 1.000000e+01 + + + + 292 + {{59, 149}, {201, 30}} + + NO + NO + 2 + 4 + 3 + + YES + AAC + IMA + iLBC + ALAC + + + YES + + + + + + + YES + + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + + 292 + {{59, 120}, {177, 21}} + + NO + YES + NO + Output Encoding Format: + + + + 1 + 1.000000e+01 + + + + 292 + {{20, 91}, {280, 21}} + + NO + YES + NO + Select the format and sample rate for output.caf file. + + + + 1 + 1.000000e+01 + + + + 292 + {{63, 20}, {194, 21}} + + NO + YES + NO + Audio File Format Information + + Helvetica + 1.400000e+01 + 16 + + + + 1 + 1.000000e+01 + + + + 292 + {{20, 49}, {280, 22}} + + NO + YES + NO + + + + + 1 + 1.000000e+01 + 1 + + + {320, 460} + + NO + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + instructionsView + + + + 26 + + + + contentView + + + + 27 + + + + navigationController + + + + 28 + + + + myViewController + + + + 29 + + + + activityIndicator + + + + 31 + + + + webView + + + + 32 + + + + startButton + + + + 33 + + + + outputFormatSelector + + + + 42 + + + + outputSampleRateSelector + + + + 43 + + + + segmentedControllerValueChanged: + + + 13 + + 44 + + + + segmentedControllerValueChanged: + + + 13 + + 45 + + + + fileInfo + + + + 50 + + + + convertButtonPressed: + + + 7 + + 51 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 10 + + + YES + + + + + + + 11 + + + YES + + + + + + + 12 + + + + + 13 + + + + + 14 + + + YES + + + + + InstructionsView + + + 18 + + + + + 19 + + + YES + + + + + + + + + + + + ContentView + + + 20 + + + + + 21 + + + + + 22 + + + YES + + + + + 30 + + + + + 38 + + + + + 39 + + + + + 40 + + + + + 41 + + + + + 47 + + + + + 48 + + + + + 49 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 10.IBViewEditorWindowController.showingLayoutRectangles + 11.CustomClassName + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBEditorWindowLastContentRect + 14.IBPluginDependency + 14.IBViewEditorWindowController.showingLayoutRectangles + 18.IBPluginDependency + 19.IBEditorWindowLastContentRect + 19.IBPluginDependency + 19.IBViewEditorWindowController.showingBoundsRectangles + 19.IBViewEditorWindowController.showingLayoutRectangles + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 30.IBPluginDependency + 38.IBPluginDependency + 39.IBPluginDependency + 40.IBPluginDependency + 41.IBPluginDependency + 47.IBPluginDependency + 48.IBPluginDependency + 49.IBPluginDependency + + + YES + UIApplication + UIResponder + {{143, 326}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + MyViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{113, 401}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{136, 396}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + {{789, 411}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ACFileConvertAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 51 + + + + YES + + ACFileConvertAppDelegate + NSObject + + YES + + YES + myViewController + navigationController + window + + + YES + MyViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/iPhoneACFileConvertTest.h + + + + MyViewController + UIViewController + + YES + + YES + convertButtonPressed: + segmentedControllerValueChanged: + + + YES + id + id + + + + YES + + YES + activityIndicator + contentView + fileInfo + instructionsView + outputFormatSelector + outputSampleRateSelector + startButton + webView + + + YES + UIActivityIndicatorView + UIView + UILabel + UIView + UISegmentedControl + UISegmentedControl + UIButton + UIWebView + + + + IBProjectSource + Classes/MyViewController.h + + + + UIView + UIResponder + + IBUserSource + + + + + + 0 + iPhoneACFileConvertTest.xcodeproj + 3 + 3.1 + + diff --git a/iPhoneACFileConvertTest/ReadMe.txt b/iPhoneACFileConvertTest/ReadMe.txt new file mode 100755 index 0000000..a1fbf3c --- /dev/null +++ b/iPhoneACFileConvertTest/ReadMe.txt @@ -0,0 +1,73 @@ +iPhoneACFileConvertTest + +=========================================================================== +DESCRIPTION: + +iPhoneACFileConvertTest demonstrates the use of the Audio Converter APIs to convert from a PCM audio format to a compressed format. + +All the relevant code is in the file AudioConverterFileConvert.cpp. + +Touching the "Convert" button calls the function DoConvertFile() producing an output.caf file using the +encoding and sample rate chosen in the UI. The output.caf file is then played back after conversion using AVAudioPlayer +to confirm success. + +Audio format information for the source file and output file are also displayed. + +Interruption handling during audio processing (conversion) is also demonstrated. + +=========================================================================== +RELATED INFORMATION: + +Core Audio Overview +Audio Session Programming Guide +Audio Converter Services Reference + +=========================================================================== +SPECIAL CONSIDERATIONS: + +AAC encoding using the Audio Converter requires iPhone OS 4.1 and a hardware capable device such +as the iPhone 3GS. See IsAACHardwareEncoderAvailable function in MyViewController.m + +=========================================================================== +BUILD REQUIREMENTS: + +Mac OS X v10.5.8, Xcode 3.1.4, iPhone OS 4.1 + +=========================================================================== +RUNTIME REQUIREMENTS: + +Simulator: Mac OS X v10.6.5 +iPhone: iPhone OS 4.1 + +=========================================================================== +PACKAGING LIST: + +iPhoneACFileConvertTest.h +iPhoneACFileConvertTest.m + +The ACFileConvertAppDelegate class defines the application delegate object, responsible for adding the navigation +controllers view to the application window. + +MyViewController.h +MyViewController.m + +The MyViewController class defines the controller object for the application. The object helps set up the user interface, +responds to and manages user interaction, and implements sound playback. + +AudioConverterFileConvert.cpp + +This file implements the DoConvertFile function which is called on a background thread from the MyViewController class. + +All the code demonstrating how to perform conversion is contained in this one file, the rest of the sample may be thought of +as a simple framework for the demonstration code in this file. + +Audio Format and Sample Rate choices presented in the UI are simply used for testing purposes, developers are free to choose any other +supported file type or encoding format and present these choices however they wish. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.0, tested with iPhone OS 4.1 First public release. + +================================================================================ +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/iPhoneACFileConvertTest/Resources/green_button.png b/iPhoneACFileConvertTest/Resources/green_button.png new file mode 100755 index 0000000..6c8b20e Binary files /dev/null and b/iPhoneACFileConvertTest/Resources/green_button.png differ diff --git a/iPhoneACFileConvertTest/Resources/info.html b/iPhoneACFileConvertTest/Resources/info.html new file mode 100644 index 0000000..a715d76 --- /dev/null +++ b/iPhoneACFileConvertTest/Resources/info.html @@ -0,0 +1,37 @@ + + +

Audio Converter File Converter Test

+ +

iPhoneACFileConvertTest demonstrates the use of the Audio Converter APIs to +convert from a PCM audio format in an .aif file to a compressed format in a .caf file +and will support AAC encode on appropriate hardware such as the iPhone 3GS. +

+ +

All the relevant code is in the file AudioConverterFileConvert.cpp.

+ +

Touching the "Convert" button calls the function DoConvertFile() producing an output.caf +file using the encoding and sample rate chosen in the UI.

+ +

The output.caf file is then played back after conversion using AVAudioPlayer to confirm success and +Audio format information for both the sournce and output file is displayed.

+ +

Interruption handling during audio processing (conversion) is also demonstrated.

+ +


+ +

Audio converter objects convert between various linear PCM audio formats. +They can also convert between linear PCM and compressed formats.

+ +

Supported transformations include the following:

+
    + +
  • PCM bit depth
  • +
  • PCM sample rate
  • +
  • PCM fixed point to and from PCM integer
  • +
  • PCM interleaved to and from PCM deinterleaved
  • +
  • PCM to and from compressed formats
  • +
+ +

A single Audio Converter may perform more than one of the listed transformations.

+
+
\ No newline at end of file diff --git a/iPhoneACFileConvertTest/Resources/red_button.png b/iPhoneACFileConvertTest/Resources/red_button.png new file mode 100755 index 0000000..42de34e Binary files /dev/null and b/iPhoneACFileConvertTest/Resources/red_button.png differ diff --git a/iPhoneACFileConvertTest/Resources/sourcePCM.aif b/iPhoneACFileConvertTest/Resources/sourcePCM.aif new file mode 100644 index 0000000..1384314 Binary files /dev/null and b/iPhoneACFileConvertTest/Resources/sourcePCM.aif differ diff --git a/iPhoneACFileConvertTest/iPhoneACFileConvertTest.xcodeproj/project.pbxproj b/iPhoneACFileConvertTest/iPhoneACFileConvertTest.xcodeproj/project.pbxproj new file mode 100755 index 0000000..1ad1212 --- /dev/null +++ b/iPhoneACFileConvertTest/iPhoneACFileConvertTest.xcodeproj/project.pbxproj @@ -0,0 +1,312 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 2B08753D1050741D0051DE52 /* AudioConverterFileConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B08753C1050741D0051DE52 /* AudioConverterFileConvert.cpp */; }; + 2B087542105074370051DE52 /* sourcePCM.aif in Resources */ = {isa = PBXBuildFile; fileRef = 2B087541105074370051DE52 /* sourcePCM.aif */; }; + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C70F5383D30033DE8C /* AVFoundation.framework */; }; + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */; }; + 2B5F57F11045D68900B2688C /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B5F57EF1045D68900B2688C /* CAXException.cpp */; }; + 2B8A00741087ECA000B2FE82 /* iPhoneACFileConvertTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2B8A00731087ECA000B2FE82 /* iPhoneACFileConvertTest.mm */; }; + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */; }; + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1C0F59F67E00D63998 /* green_button.png */; }; + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1D0F59F67E00D63998 /* red_button.png */; }; + 2BE30B230F59F67E00D63998 /* info.html in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1F0F59F67E00D63998 /* info.html */; }; + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */; }; + 2BFBE1AC0F5C9C54003ECC4F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BFBE1AB0F5C9C54003ECC4F /* Icon.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* AudioConverterFileConvertTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AudioConverterFileConvertTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B08753C1050741D0051DE52 /* AudioConverterFileConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioConverterFileConvert.cpp; sourceTree = ""; }; + 2B08753E105074280051DE52 /* iPhoneACFileConvertTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneACFileConvertTest.h; sourceTree = ""; }; + 2B087541105074370051DE52 /* sourcePCM.aif */ = {isa = PBXFileReference; lastKnownFileType = file; name = sourcePCM.aif; path = Resources/sourcePCM.aif; sourceTree = ""; }; + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2B5F57EF1045D68900B2688C /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = ""; }; + 2B5F57F01045D68900B2688C /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = ""; }; + 2B8A00731087ECA000B2FE82 /* iPhoneACFileConvertTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iPhoneACFileConvertTest.mm; sourceTree = ""; }; + 2BC28156105700A200131AF6 /* iPhoneACFileConvertTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneACFileConvertTest_Prefix.pch; sourceTree = ""; }; + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = ""; }; + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = ""; }; + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + 2BE30B1C0F59F67E00D63998 /* green_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = green_button.png; path = Resources/green_button.png; sourceTree = ""; }; + 2BE30B1D0F59F67E00D63998 /* red_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = red_button.png; path = Resources/red_button.png; sourceTree = ""; }; + 2BE30B1F0F59F67E00D63998 /* info.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = info.html; path = Resources/info.html; sourceTree = ""; }; + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 2BFBE1AB0F5C9C54003ECC4F /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */, + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 2B08753E105074280051DE52 /* iPhoneACFileConvertTest.h */, + 2B8A00731087ECA000B2FE82 /* iPhoneACFileConvertTest.mm */, + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */, + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* AudioConverterFileConvertTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */, + 2B08753C1050741D0051DE52 /* AudioConverterFileConvert.cpp */, + 080E96DDFE201D6D7F000001 /* Classes */, + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 2BC28156105700A200131AF6 /* iPhoneACFileConvertTest_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 2BFBE1AB0F5C9C54003ECC4F /* Icon.png */, + 2BE30B1C0F59F67E00D63998 /* green_button.png */, + 2BE30B1D0F59F67E00D63998 /* red_button.png */, + 2BE30B1F0F59F67E00D63998 /* info.html */, + 2B087541105074370051DE52 /* sourcePCM.aif */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */, + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */ = { + isa = PBXGroup; + children = ( + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */, + 2B5F57F01045D68900B2688C /* CAXException.h */, + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */, + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */, + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */, + 2B5F57EF1045D68900B2688C /* CAXException.cpp */, + ); + path = iPublicUtility; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* AudioConverterFileConvertTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AudioConverterFileConvertTest" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AudioConverterFileConvertTest; + productName = AQOffilineRenderTest; + productReference = 1D6058910D05DD3D006BFB54 /* AudioConverterFileConvertTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneACFileConvertTest" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* AudioConverterFileConvertTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */, + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */, + 2BE30B230F59F67E00D63998 /* info.html in Resources */, + 2BFBE1AC0F5C9C54003ECC4F /* Icon.png in Resources */, + 2B087542105074370051DE52 /* sourcePCM.aif in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */, + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */, + 2B5F57F11045D68900B2688C /* CAXException.cpp in Sources */, + 2B08753D1050741D0051DE52 /* AudioConverterFileConvert.cpp in Sources */, + 2B8A00741087ECA000B2FE82 /* iPhoneACFileConvertTest.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneACFileConvertTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = AudioConverterFileConvertTest; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneACFileConvertTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = AudioConverterFileConvertTest; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos; + STRIP_INSTALLED_PRODUCT = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "AudioConverterFileConvertTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneACFileConvertTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/iPhoneACFileConvertTest/iPhoneACFileConvertTest_Prefix.pch b/iPhoneACFileConvertTest/iPhoneACFileConvertTest_Prefix.pch new file mode 100644 index 0000000..a17209c --- /dev/null +++ b/iPhoneACFileConvertTest/iPhoneACFileConvertTest_Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iPhoneACFileConvertTest/iPublicUtility/CADebugMacros.h b/iPhoneACFileConvertTest/iPublicUtility/CADebugMacros.h new file mode 100755 index 0000000..3c697ae --- /dev/null +++ b/iPhoneACFileConvertTest/iPublicUtility/CADebugMacros.h @@ -0,0 +1,440 @@ +/* + + File: CADebugMacros.h +Abstract: Helper class for printing debug messages + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#if !defined(__CADebugMacros_h__) +#define __CADebugMacros_h__ + +//============================================================================= +// Includes +//============================================================================= + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CADebugMacros +//============================================================================= + +//#define CoreAudio_StopOnFailure 1 +//#define CoreAudio_TimeStampMessages 1 +//#define CoreAudio_ThreadStampMessages 1 +//#define CoreAudio_FlushDebugMessages 1 + +#if TARGET_RT_BIG_ENDIAN + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } +#else + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } +#endif + +#pragma mark Basic Definitions + +#if DEBUG || CoreAudio_Debug + + // can be used to break into debugger immediately, also see CADebugger + #define BusError() (*(long *)0 = 0) + + // basic debugging print routines + #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON + extern void DebugStr(const unsigned char* debuggerMsg); + #define DebugMessage(msg) DebugStr("\p"msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #else + #include "CADebugPrintf.h" + + #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) + #define FlushRtn ,fflush(DebugPrintfFile) + #else + #define FlushRtn + #endif + + #if CoreAudio_ThreadStampMessages + #include + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #elif CoreAudio_TimeStampMessages + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #else + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%s"DebugPrintfLineEnding, msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #endif + #endif + void DebugPrint(const char *fmt, ...); // can be used like printf + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) + #endif + #if VERBOSE + #define vprint(msg) DEBUGPRINT(msg) + #else + #define vprint(msg) + #endif + + #if CoreAudio_StopOnFailure + #include "CADebugger.h" + #define STOP CADebuggerStop() + #else + #define STOP + #endif + +#else + #define DebugMessage(msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #define DebugMessageN4(msg, N1, N2, N3, N4) + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) + #define DEBUGPRINT(msg) + #define vprint(msg) + #define STOP +#endif + +void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) +void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) + +#if DEBUG || CoreAudio_Debug + +#pragma mark Debug Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + DebugMessage(inMethodName": Subclasses must implement this method"); \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#else + +#pragma mark Release Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + if((inKernelError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + if((inError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#endif // DEBUG || CoreAudio_Debug + +#endif diff --git a/iPhoneACFileConvertTest/iPublicUtility/CAMath.h b/iPhoneACFileConvertTest/iPublicUtility/CAMath.h new file mode 100755 index 0000000..def9151 --- /dev/null +++ b/iPhoneACFileConvertTest/iPublicUtility/CAMath.h @@ -0,0 +1,71 @@ +/* + + File: CAMath.h +Abstract: Helper class for various math functions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#ifndef __CAMath_h__ +#define __CAMath_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +inline bool fiszero(Float64 f) { return (f == 0.); } +inline bool fiszero(Float32 f) { return (f == 0.f); } + +inline bool fnonzero(Float64 f) { return !fiszero(f); } +inline bool fnonzero(Float32 f) { return !fiszero(f); } + +inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } +inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } + +inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } +inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } + +#endif // __CAMath_h__ diff --git a/iPhoneACFileConvertTest/iPublicUtility/CAStreamBasicDescription.cpp b/iPhoneACFileConvertTest/iPublicUtility/CAStreamBasicDescription.cpp new file mode 100755 index 0000000..6307741 --- /dev/null +++ b/iPhoneACFileConvertTest/iPublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,552 @@ +/* + + File: CAStreamBasicDescription.cpp +Abstract: Helper class for audio stream descriptions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#include "CAStreamBasicDescription.h" +#include "CAMath.h" + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +#if TARGET_OS_WIN32 + #include +#endif + +#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; + mReserved = 0; +} + +char *CAStreamBasicDescription::AsString(char *buf, size_t bufsize) const +{ + char *theBuffer = buf; + int nc; + char formatID[5]; + *(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID); + formatID[4] = '\0'; + nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); + buf += nc; bufsize -= nc; + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (wordSize > 0 && PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + sprintf(packed, "packed in %d bytes", wordSize); + else + sprintf(packed, "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + char bitdepth[20]; + +#if CA_PREFER_FIXED_POINT + int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; + if (fracbits > 0) + sprintf(bitdepth, "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); + else +#endif + sprintf(bitdepth, "%d", (int)mBitsPerChannel); + + nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s", + bitdepth, endian, sign, floatInt, + commaSpace, packed, align, deinter); + //buf += nc; bufsize -= nc; + } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless + int sourceBits = 0; + switch (mFormatFlags) + { + case 1: // kAppleLosslessFormatFlag_16BitSourceData + sourceBits = 16; + break; + case 2: // kAppleLosslessFormatFlag_20BitSourceData + sourceBits = 20; + break; + case 3: // kAppleLosslessFormatFlag_24BitSourceData + sourceBits = 24; + break; + case 4: // kAppleLosslessFormatFlag_32BitSourceData + sourceBits = 32; + break; + } + if (sourceBits) + nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits); + else + nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, "); + buf += nc; bufsize -= nc; + nc = snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket); + //buf += nc; bufsize -= nc; + } + else + nc = snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", + (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); + return theBuffer; +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format + if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) + { + // the canonical linear PCM format + ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; + ioDescription.mBytesPerPacket = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerFrame = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType); + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(fiszero(ioDescription.mSampleRate)) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + const char* theMixabilityString = NULL; + if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) + { + theMixabilityString = "Mixable"; + } + else + { + theMixabilityString = "Unmixable"; + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strcpy(outName, "AC-3"); + break; + + case kAudioFormat60958AC3: + strcpy(outName, "AC-3 for SPDIF"); + break; + + default: + CACopy4CCToCString(outName, inDescription.mFormatID); + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + + // mixable is always better than non-mixable for linear PCM and should be the second order sort item + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) + { + theAnswer = true; + isDone = true; + } + else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) + { + theAnswer = false; + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) + { + if(fnotequal(x.mSampleRate, y.mSampleRate)) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + + // if the number of channels is 0 or 1, we don't care about non-interleavedness + if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) { + xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const +{ + if (interpretingWildcards) + return *this == other; + return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0.) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024); +} diff --git a/iPhoneACFileConvertTest/iPublicUtility/CAStreamBasicDescription.h b/iPhoneACFileConvertTest/iPublicUtility/CAStreamBasicDescription.h new file mode 100755 index 0000000..dcbe051 --- /dev/null +++ b/iPhoneACFileConvertTest/iPublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,310 @@ +/* + + File: CAStreamBasicDescription.h +Abstract: Helper class for audio stream descriptions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CoreFoundation.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it + +// define Leopard specific symbols for backward compatibility if applicable +#if COREAUDIOTYPES_VERSION < 1050 +typedef Float32 AudioSampleType; +enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; +#endif +#if COREAUDIOTYPES_VERSION < 1051 +typedef Float32 AudioUnitSampleType; +#endif + +// define the IsMixable format flag for all versions of the system +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; +#else + enum { kIsNonMixableFlag = (1L << 6) }; +#endif + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { + return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; + } + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; +#if CA_ENV_MACOSX + int sampleSize = sizeof(Float32); + mFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + int sampleSize = sizeof(AudioSampleType); + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mBitsPerChannel = 8 * sampleSize; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; + else { + mBytesPerPacket = mBytesPerFrame = sampleSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + bool IsCanonical() const + { + if (mFormatID != kAudioFormatLinearPCM) return false; + UInt32 reqFormatFlags; +#if (COREAUDIOTYPES_VERSION <= 1050) + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh); +#else + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); +#endif + bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; +#if CA_ENV_MACOSX + unsigned sampleSize = sizeof(Float32); + reqFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + unsigned sampleSize = sizeof(AudioSampleType); + reqFormatFlags = kAudioFormatFlagsCanonical; +#endif + UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; + + return ((mFormatFlags & flagsMask) == reqFormatFlags + && mBitsPerChannel == 8 * sampleSize + && mFramesPerPacket == 1 + && mBytesPerFrame == reqFrameSize + && mBytesPerPacket == reqFrameSize); + } + + void SetAUCanonical(UInt32 nChannels, bool interleaved) + { + mFormatID = kAudioFormatLinearPCM; +#if CA_PREFER_FIXED_POINT + mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); +#else + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); + else { + mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + if (wordSize == 0) + wordSize = (mBitsPerChannel + 7) / 8; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; + + void Print() const { + Print (stdout); + } + + void Print(FILE* file) const { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const { + char buf[256]; + fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); + } + + void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline + char buf[256]; + fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); + } + + char * AsString(char *buf, size_t bufsize) const; + + static void Print (const AudioStreamBasicDescription &inDesc) + { + CAStreamBasicDescription desc(inDesc); + desc.Print (); + } + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__ diff --git a/iPhoneACFileConvertTest/iPublicUtility/CAXException.cpp b/iPhoneACFileConvertTest/iPublicUtility/CAXException.cpp new file mode 100644 index 0000000..da39296 --- /dev/null +++ b/iPhoneACFileConvertTest/iPublicUtility/CAXException.cpp @@ -0,0 +1,43 @@ +/* Copyright � 2007 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#include "CAXException.h" + +CAXException::WarningHandler CAXException::sWarningHandler = NULL; diff --git a/iPhoneACFileConvertTest/iPublicUtility/CAXException.h b/iPhoneACFileConvertTest/iPublicUtility/CAXException.h new file mode 100644 index 0000000..623b32f --- /dev/null +++ b/iPhoneACFileConvertTest/iPublicUtility/CAXException.h @@ -0,0 +1,189 @@ +/* Copyright � 2007 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef __CAXException_h__ +#define __CAXException_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif +#include "CADebugMacros.h" +#include +#include +#include + +// An extended exception class that includes the name of the failed operation +class CAXException { +public: + CAXException(const char *operation, OSStatus err) : + mError(err) + { + if (operation == NULL) + mOperation[0] = '\0'; + else if (strlen(operation) >= sizeof(mOperation)) { + memcpy(mOperation, operation, sizeof(mOperation) - 1); + mOperation[sizeof(mOperation) - 1] = '\0'; + } else + strcpy(mOperation, operation); + } + + char *FormatError(char *str) const + { + return FormatError(str, mError); + } + + char mOperation[256]; + const OSStatus mError; + + // ------------------------------------------------- + + typedef void (*WarningHandler)(const char *msg, OSStatus err); + + /*static void Throw(const char *operation, OSStatus err) + { + throw CAXException(operation, err); + }*/ + + static char *FormatError(char *str, OSStatus error) + { + // see if it appears to be a 4-char-code + *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); + if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { + str[0] = str[5] = '\''; + str[6] = '\0'; + } else + // no, format it as an integer + sprintf(str, "%d", (int)error); + return str; + } + + static void Warning(const char *s, OSStatus error) + { + if (sWarningHandler) + (*sWarningHandler)(s, error); + } + + static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } +private: + static WarningHandler sWarningHandler; +}; + +#if DEBUG || CoreAudio_Debug + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + } \ + } while (0) + +#else + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + /*OSStatus __err =*/ error; \ + } while (0) +#endif + +#define XThrow(error, operation) XThrowIf(true, error, operation) +#define XThrowIfErr(error) XThrowIfError(error, #error) + +#endif // __CAXException_h__ diff --git a/iPhoneACFileConvertTest/main.m b/iPhoneACFileConvertTest/main.m new file mode 100644 index 0000000..cbb8456 --- /dev/null +++ b/iPhoneACFileConvertTest/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: main + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/iPhoneExtAudioFileConvertTest.zip b/iPhoneExtAudioFileConvertTest.zip new file mode 100644 index 0000000..b170e61 Binary files /dev/null and b/iPhoneExtAudioFileConvertTest.zip differ diff --git a/iPhoneExtAudioFileConvertTest/Classes/MyViewController.h b/iPhoneExtAudioFileConvertTest/Classes/MyViewController.h new file mode 100755 index 0000000..c4fc7f9 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/Classes/MyViewController.h @@ -0,0 +1,96 @@ +/* + File: MyViewController.h + Abstract: The main view controller of this app. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +// includes +#import +#import +#import +#import + +// helpers +#include "CAXException.h" +#include "CAStreamBasicDescription.h" + +@interface MyViewController : UIViewController +{ + IBOutlet UIView *instructionsView; + IBOutlet UIWebView *webView; + IBOutlet UIView *contentView; + + IBOutlet UILabel *fileInfo; + + IBOutlet UISegmentedControl *outputFormatSelector; + IBOutlet UISegmentedControl *outputSampleRateSelector; + + IBOutlet UIButton *startButton; + IBOutlet UIActivityIndicatorView *activityIndicator; + + UIBarButtonItem *flipButton; + UIBarButtonItem *doneButton; + + NSString *destinationFilePath; + CFURLRef sourceURL; + CFURLRef destinationURL; + OSType outputFormat; + Float64 sampleRate; +} + +@property (readonly, nonatomic) IBOutlet UIView *instructionsView; +@property (readonly, nonatomic) IBOutlet UIWebView *webView; +@property (readonly, nonatomic) IBOutlet UIView *contentView; +@property (readonly, nonatomic) IBOutlet UISegmentedControl *outputFormatSelector; +@property (readonly, nonatomic) IBOutlet UISegmentedControl *outputSampleRateSelector; +@property (readonly, nonatomic) IBOutlet UIButton *startButton; +@property (readonly, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; + +@property (nonatomic, retain) UIBarButtonItem *flipButton; +@property (nonatomic, retain) UIBarButtonItem *doneButton; + +- (IBAction)segmentedControllerValueChanged:(id)sender; +- (IBAction)convertButtonPressed:(id)sender; + +@end \ No newline at end of file diff --git a/iPhoneExtAudioFileConvertTest/Classes/MyViewController.m b/iPhoneExtAudioFileConvertTest/Classes/MyViewController.m new file mode 100755 index 0000000..70d3155 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/Classes/MyViewController.m @@ -0,0 +1,399 @@ +/* + File: MyViewController.m + Abstract: The main view controller of this app. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MyViewController.h" + +extern OSStatus DoConvertFile(CFURLRef sourceURL, CFURLRef destinationURL, OSType outputFormat, Float64 outputSampleRate); + +#define kTransitionDuration 0.75 + +#pragma mark- + +static Boolean IsAACHardwareEncoderAvailable(void) +{ + Boolean isAvailable = false; + + // get an array of AudioClassDescriptions for all installed encoders for the given format + // the specifier is the format that we are interested in - this is 'aac ' in our case + UInt32 encoderSpecifier = kAudioFormatMPEG4AAC; + UInt32 size; + + OSStatus result = AudioFormatGetPropertyInfo(kAudioFormatProperty_Encoders, sizeof(encoderSpecifier), &encoderSpecifier, &size); + if (result) { printf("AudioFormatGetPropertyInfo kAudioFormatProperty_Encoders result %lu %4.4s\n", result, (char*)&result); return false; } + + UInt32 numEncoders = size / sizeof(AudioClassDescription); + AudioClassDescription encoderDescriptions[numEncoders]; + + result = AudioFormatGetProperty(kAudioFormatProperty_Encoders, sizeof(encoderSpecifier), &encoderSpecifier, &size, encoderDescriptions); + if (result) { printf("AudioFormatGetProperty kAudioFormatProperty_Encoders result %lu %4.4s\n", result, (char*)&result); return false; } + + for (UInt32 i=0; i < numEncoders; ++i) { + if (encoderDescriptions[i].mSubType == kAudioFormatMPEG4AAC && encoderDescriptions[i].mManufacturer == kAppleHardwareAudioCodecManufacturer) isAvailable = true; + } + + return isAvailable; +} + +static void UpdateFormatInfo(UILabel *inLabel, CFURLRef inFileURL) +{ + AudioFileID fileID; + + OSStatus result = AudioFileOpenURL(inFileURL, kAudioFileReadPermission, 0, &fileID); + if (noErr == result) { + CAStreamBasicDescription asbd; + UInt32 size = sizeof(asbd); + result = AudioFileGetProperty(fileID, kAudioFilePropertyDataFormat, &size, &asbd); + if (noErr == result) { + char formatID[5]; + CFStringRef lastPathComponent = CFURLCopyLastPathComponent(inFileURL); + *(UInt32 *)formatID = CFSwapInt32HostToBig(asbd.mFormatID); + + inLabel.text = [NSString stringWithFormat: @"%@ %4.4s %6.0f Hz (%d ch.)", lastPathComponent, formatID, asbd.mSampleRate, asbd.NumberChannels(), nil]; + CFRelease(lastPathComponent); + } else { + printf("AudioFileGetProperty kAudioFilePropertyDataFormat result %lu %4.4s\n", result, (char*)&result); + } + + AudioFileClose(fileID); + } else { + printf("AudioFileOpenURL failed! result %lu %4.4s\n", result, (char*)&result); + } +} + +#pragma mark- + +@implementation MyViewController + +@synthesize instructionsView, webView, contentView, outputFormatSelector, outputSampleRateSelector, startButton, activityIndicator, flipButton, doneButton; + +- (void)dealloc +{ + [instructionsView release]; + [webView release]; + [contentView release]; + + [fileInfo release]; + + [outputFormatSelector release]; + [outputSampleRateSelector release]; + + [startButton release]; + [activityIndicator release]; + + [flipButton release]; + [doneButton release]; + + [destinationFilePath release]; + CFRelease(sourceURL); + CFRelease(destinationURL); + + [super dealloc]; +} + +- (void)viewDidLoad +{ + // create the URLs we'll use for source and destination + NSString *source = [[NSBundle mainBundle] pathForResource:@"sourceALAC" ofType:@"caf"]; + sourceURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)source, kCFURLPOSIXPathStyle, false); + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory]; + destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); + + // load up the info text + NSString *infoSouceFile = [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]; + NSString *infoText = [NSString stringWithContentsOfFile:infoSouceFile encoding:NSUTF8StringEncoding error:nil]; + [self.webView loadHTMLString:infoText baseURL:nil]; + self.webView.backgroundColor = [UIColor whiteColor]; + + // set up start button + UIImage *greenImage = [[UIImage imageNamed:@"green_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + UIImage *redImage = [[UIImage imageNamed:@"red_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + + [startButton setBackgroundImage:greenImage forState:UIControlStateNormal]; + [startButton setBackgroundImage:redImage forState:UIControlStateDisabled]; + + // add the subview + [self.view addSubview:contentView]; + + // add our custom flip buttons as the nav bars custom right view + UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; + [infoButton addTarget:self action:@selector(flipAction:) forControlEvents:UIControlEventTouchUpInside]; + + flipButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + self.navigationItem.rightBarButtonItem = flipButton; + + // create our done button as the nav bar's custom right view for the flipped view (used later) + doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(flipAction:)]; + + // default output format + // sample rate of 0 indicates source file sample rate + outputFormat = kAudioFormatLinearPCM; + sampleRate = 0; + + // can we encode to AAC? + if (IsAACHardwareEncoderAvailable()) { + [self.outputFormatSelector setEnabled:YES forSegmentAtIndex:0]; + } else { + // even though not enabled in IB, this segment will still be enabled + // if not specifically turned off here which we'll assume is a bug + [self.outputFormatSelector setEnabled:NO forSegmentAtIndex:0]; + } + + UpdateFormatInfo(fileInfo, sourceURL); + +} + +- (void)didReceiveMemoryWarning +{ + // Invoke super's implementation to do the Right Thing, but also release the input controller since we can do that + // In practice this is unlikely to be used in this application, and it would be of little benefit, + // but the principle is the important thing. + + [super didReceiveMemoryWarning]; +} + +#pragma mark- Actions + +- (void)flipAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + + [UIView setAnimationTransition:([self.contentView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) + forView:self.view + cache:YES]; + + if ([self.instructionsView superview]) { + [self.instructionsView removeFromSuperview]; + [self.view addSubview:contentView]; + } else { + [self.contentView removeFromSuperview]; + [self.view addSubview:instructionsView]; + } + + [UIView commitAnimations]; + + // adjust our done/info buttons accordingly + if ([instructionsView superview]) { + self.navigationItem.rightBarButtonItem = doneButton; + } else { + self.navigationItem.rightBarButtonItem = flipButton; + } +} + +- (IBAction)convertButtonPressed:(id)sender +{ + // use kAudioSessionCategory_AudioProcessing category for offline conversion when not playing or recording audio at the same time + // if you are recording or playing audio at the same time you are encoding, use the same Audio Session category that you would normally + UInt32 audioCategory = kAudioSessionCategory_AudioProcessing; + OSStatus error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + if (error) { + printf("AudioSessionSetProperty kAudioSessionCategory_AudioProcessing failed! %ld\n", error); + + return; + } + + [self.startButton setTitle:@"Converting..." forState:UIControlStateDisabled]; + [startButton setEnabled:NO]; + + [self.activityIndicator startAnimating]; + + // run audio file code in a background thread + [self performSelectorInBackground:(@selector(convertAudio)) withObject:nil]; +} + +- (IBAction)segmentedControllerValueChanged:(id)sender +{ + switch ([sender tag]) { + case 0: + switch ([sender selectedSegmentIndex]) { + case 0: + outputFormat = kAudioFormatMPEG4AAC; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:2]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:3]; + break; + case 1: + outputFormat = kAudioFormatAppleIMA4; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:2]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:3]; + break; + case 2: + // iLBC sample rate is 8K + outputFormat = kAudioFormatiLBC; + [self.outputSampleRateSelector setSelectedSegmentIndex:2]; + [self.outputSampleRateSelector setEnabled:NO forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:NO forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:NO forSegmentAtIndex:3]; + break; + case 3: + outputFormat = kAudioFormatLinearPCM; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:0]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:1]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:2]; + [self.outputSampleRateSelector setEnabled:YES forSegmentAtIndex:3]; + break; + } + break; + case 1: + switch ([sender selectedSegmentIndex]) { + case 0: + sampleRate = 44100.0; + break; + case 1: + sampleRate = 22050.0; + break; + case 2: + sampleRate = 8000.0; + break; + case 3: + sampleRate = 0; + break; + } + break; + } +} + +#pragma mark- AVAudioPlayer + +- (void)updateUI +{ + [startButton setEnabled:YES]; + UpdateFormatInfo(fileInfo, sourceURL); +} + +- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error +{ + NSLog(@"%@", [error localizedDescription]); + [self audioPlayerDidFinishPlaying:player successfully:false]; +} + +- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player +{ + printf("Session interrupted! --- audioPlayerBeginInterruption ---\n"); + + // if the player was interrupted during playback we don't continue + [self audioPlayerDidFinishPlaying:player successfully:true]; +} + +- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag +{ + if (flag == NO) NSLog(@"Playback finished unsuccessfully!"); + + printf("audioPlayerDidFinishPlaying\n"); + + [player setDelegate:nil]; + [player release]; + + [self updateUI]; +} + +- (void)playAudio +{ + printf("playAudio\n"); + + UpdateFormatInfo(fileInfo, destinationURL); + [self.startButton setTitle:@"Playing Output File..." forState:UIControlStateDisabled]; + + // set category back to something that will allow us to play audio since kAudioSessionCategory_AudioProcessing will not + UInt32 audioCategory = kAudioSessionCategory_MediaPlayback; + OSStatus error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + if (error) { + printf("AudioSessionSetProperty kAudioSessionCategory_SoloAmbientSound failed! %ld\n", error); + + [self updateUI]; + + return; + } + + // play the result + AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:(NSURL *)destinationURL error:nil]; + if (nil == player) { + printf("AVAudioPlayer alloc failed! %ld\n", error); + + [self updateUI]; + + return; + } + + [player setDelegate:self]; + [player play]; +} + +#pragma mark- ExtAudioFile + +- (void)convertAudio +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + OSStatus error = DoConvertFile(sourceURL, destinationURL, outputFormat, sampleRate); + + [self.activityIndicator stopAnimating]; + + if (error) { + // delete output file if it exists since an error was returned during the conversion process + if ([[NSFileManager defaultManager] fileExistsAtPath:destinationFilePath]) { + [[NSFileManager defaultManager] removeItemAtPath:destinationFilePath error:nil]; + } + + printf("DoConvertFile failed! %ld\n", error); + [self performSelectorOnMainThread:(@selector(updateUI)) withObject:nil waitUntilDone:NO]; + } else { + [self performSelectorOnMainThread:(@selector(playAudio)) withObject:nil waitUntilDone:NO]; + } + + [pool release]; +} + +@end \ No newline at end of file diff --git a/iPhoneExtAudioFileConvertTest/Classes/iPhoneExtAudioFileConvertTest.h b/iPhoneExtAudioFileConvertTest/Classes/iPhoneExtAudioFileConvertTest.h new file mode 100644 index 0000000..b9fdb4d --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/Classes/iPhoneExtAudioFileConvertTest.h @@ -0,0 +1,65 @@ +/* + File: iPhoneExtAudioFileConvertTest.h + Abstract: The application delegate. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "MyViewController.h" + +@interface ExtAudioFileConvertAppDelegate : NSObject { + UIWindow *window; + + IBOutlet UINavigationController *navigationController; + IBOutlet MyViewController *myViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet MyViewController *myViewController; + +@end + diff --git a/iPhoneExtAudioFileConvertTest/Classes/iPhoneExtAudioFileConvertTest.m b/iPhoneExtAudioFileConvertTest/Classes/iPhoneExtAudioFileConvertTest.m new file mode 100644 index 0000000..f01b496 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/Classes/iPhoneExtAudioFileConvertTest.m @@ -0,0 +1,142 @@ +/* + File: iPhoneExtAudioFileConvertTest.m + Abstract: The application delegate. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "iPhoneExtAudioFileConvertTest.h" + +extern void ThreadStateInitalize(); +extern void ThreadStateBeginInterruption(); +extern void ThreadStateEndInterruption(); + +@implementation ExtAudioFileConvertAppDelegate + +@synthesize window, navigationController, myViewController; + +#pragma mark -Audio Session Interruption Listener + +static void interruptionListener(void *inClientData, UInt32 inInterruption) +{ + printf("Session interrupted! --- %s ---\n", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + if (inInterruption == kAudioSessionBeginInterruption) { + ThreadStateBeginInterruption(); + } + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + AudioSessionSetActive(true); + ThreadStateEndInterruption(); + } +} + +#pragma mark -Audio Session Property Listener + +static void propertyListener(void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) +{ + if (inID == kAudioSessionProperty_AudioRouteChange) { + try { + CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inData; + + UInt32 routeChangeReason; + CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); + CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); + printf("Audio Route Change, Reason: %lu\n", routeChangeReason); + + CFStringRef routeChangeOldRouteRef = (CFStringRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute)); + printf("Old Route: "); + CFShow(routeChangeOldRouteRef); + + CFStringRef newRoute; + UInt32 size = sizeof(newRoute); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute), "couldn't get new audio route"); + if (newRoute) { + printf("New Route: "); + CFShow(newRoute); + } + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + } +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after application launch + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; + + ThreadStateInitalize(); + + try { + // Initialize and configure the audio session + XThrowIfError(AudioSessionInitialize(NULL, NULL, interruptionListener, self), "couldn't initialize audio session"); + + // our default category -- we change this for conversion and playback appropriately + UInt32 audioCategory = kAudioSessionCategory_SoloAmbientSound; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory), "couldn't set audio category"); + + // we don't do anything special + XThrowIfError(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propertyListener, self), "couldn't set property listener"); + + // the session must be active for offline conversion including after an an audio interruption + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active\n"); + + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } +} + +- (void)dealloc { + self.window = nil; + self.navigationController = nil; + self.myViewController = nil; + + [super dealloc]; +} + +@end diff --git a/iPhoneExtAudioFileConvertTest/ExtAudioFileConvert.cpp b/iPhoneExtAudioFileConvertTest/ExtAudioFileConvert.cpp new file mode 100644 index 0000000..f0c9498 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/ExtAudioFileConvert.cpp @@ -0,0 +1,427 @@ +/* + File: ExtAudioFileConvert.cpp + Abstract: Demonstrates converting audio using ExtAudioFile. + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +// standard includes +#include + +// helpers +#include "CAXException.h" +#include "CAStreamBasicDescription.h" + +#include + +/* + +For more information on the importance of interruption handling and Audio Session setup when performing offline +encoding please see the Audio Session Programming Guide. + +Offline format conversion requires interruption handling. Specifically, you must handle interruptions at the audio data buffer level. + +By way of background, you can use a hardware assisted-codec—on certain devices—to encode linear PCM audio to AAC format. +The codec is available on the iPhone 3GS and on the iPod touch (2nd generation), but not on older models. You use the codec as part +of an audio converter object (of type AudioConverterRef), which in turn is part of an extended audio file object (of type ExtAudioFileRef). +For information on these opaque types, refer to Audio Converter Services Reference and Extended Audio File Services Reference. + +To handle an interruption during hardware-assisted encoding, take two things into account: + +1. The codec may or may not be able to resume encoding after the interruption ends. +2. The last buffer that you sent to the codec, before the interruption, may or may not have been successfully written to disk. + +Encoding takes place as you repeatedly call the ExtAudioFileWrite function with new buffers of audio data. To handle an interruption, +you respond to the function’s result code, as described here: + +• kExtAudioFileError_CodecUnavailableInputConsumed — This result code indicates that the last buffer you provided, prior to interruption, +was successfully written to disk. On receiving this result code, stop calling the ExtAudioFileWrite function. If you can resume conversion, +wait for an interruption-ended call from the audio session. In your interruption-end handler, reactivate the session and then resume writing the file. +Because the last buffer (before interruption) was successfully written to disk, proceed by writing the next buffer. + +• kExtAudioFileError_CodecUnavailableInputNotConsumed — This result code indicates that the last buffer you provided, prior to interruption, was not +successfully written to disk. Exactly as for the other result code, on receiving this error, stop calling the ExtAudioFileWrite function. If you can +resume conversion, wait for an interruption-ended call from the audio session. In your interruption-end handler, reactivate the session and then resume +writing the file. Here is where your interruption handling differs from the other result code: Because the last buffer (before interruption) was not +successfully written to disk, begin by writing that buffer again. + +To check if the AAC codec can resume, obtain the value of the associated converter’s kAudioConverterPropertyCanResumeFromInterruption property. +The value is 1 (can resume) or 0 (cannot resume). You can obtain this value any time after instantiating the converter—immediately after instantiation, +upon interruption, or after interruption ends. + +If the converter cannot resume, then on interruption you must abandon the conversion. After the interruption ends, or after the user relaunches your application +and indicates they want to resume conversion, re-instantiate the extended audio file object and perform the conversion again. + +*/ + +#pragma mark- Thread State +/* Since we perform conversion in a background thread, we must ensure that we handle interruptions appropriately. + In this sample we're using a mutex protected variable tracking thread states. The background conversion threads state transistions from Done to Running + to Done unless we've been interrupted in which case we are Paused blocking the conversion thread and preventing further calls + to ExtAudioFileWrite (since it would fail if we were using the hardware codec). + Once the interruption has ended, we unblock the background thread as the state transitions to Running once again. + Any errors returned from ExtAudioFileWrite must be handled appropriately for example, if the input buffers were not consumed + by the write call, you would need to read source audio data from the previous position and try again. Additionally, if the Audio Converter cannot + resume conversion after an interruption, you should not call ExtAudioFileWrite again. +*/ + +static pthread_mutex_t sStateLock; // protects sState +static pthread_cond_t sStateChanged; // signals when interruption thread unblocks conversion thread +enum ThreadStates { + kStateRunning, + kStatePaused, + kStateDone +}; +static ThreadStates sState; + +// initialize the thread state +void ThreadStateInitalize() +{ + int rc; + + assert([NSThread isMainThread]); + + rc = pthread_mutex_init(&sStateLock, NULL); + assert(rc == 0); + + rc = pthread_cond_init(&sStateChanged, NULL); + assert(rc == 0); + + sState = kStateDone; +} + +// handle begin interruption - transition to kStatePaused +void ThreadStateBeginInterruption() +{ + int rc; + + assert([NSThread isMainThread]); + + rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + if (sState == kStateRunning) { + sState = kStatePaused; + } + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// handle end interruption - transition to kStateRunning +void ThreadStateEndInterruption() +{ + int rc; + + assert([NSThread isMainThread]); + + rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + if (sState == kStatePaused) { + sState = kStateRunning; + + rc = pthread_cond_signal(&sStateChanged); + assert(rc == 0); + } + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// set state to kStateRunning +void ThreadStateSetRunning() +{ + int rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + assert(sState == kStateDone); + sState = kStateRunning; + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// block for state change to kStateRunning +Boolean ThreadStatePausedCheck() +{ + Boolean wasInterrupted = false; + + int rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + assert(sState != kStateDone); + + while (sState == kStatePaused) { + rc = pthread_cond_wait(&sStateChanged, &sStateLock); + assert(rc == 0); + wasInterrupted = true; + } + + // we must be running or something bad has happened + assert(sState == kStateRunning); + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); + + return wasInterrupted; +} + +void ThreadStateSetDone() +{ + int rc = pthread_mutex_lock(&sStateLock); + assert(rc == 0); + + assert(sState != kStateDone); + sState = kStateDone; + + rc = pthread_mutex_unlock(&sStateLock); + assert(rc == 0); +} + +// *********************** +#pragma mark- Convert +/* The main Audio Conversion function using ExtAudioFile APIs */ + +// our own error code when we cannot continue from an interruption +enum { + kMyAudioConverterErr_CannotResumeFromInterruptionError = 'CANT' +}; + +OSStatus DoConvertFile(CFURLRef sourceURL, CFURLRef destinationURL, OSType outputFormat, Float64 outputSampleRate) +{ + ExtAudioFileRef sourceFile = 0; + ExtAudioFileRef destinationFile = 0; + Boolean canResumeFromInterruption = true; // we can continue unless told otherwise + OSStatus error = noErr; + + // in this sample we should never be on the main thread here + assert(![NSThread isMainThread]); + + // transition thread state to kStateRunning before continuing + ThreadStateSetRunning(); + + printf("DoConvertFile\n"); + + try { + CAStreamBasicDescription srcFormat, dstFormat; + + // open the source file + XThrowIfError(ExtAudioFileOpenURL(sourceURL, &sourceFile), "ExtAudioFileOpenURL failed"); + + // get the source data format + UInt32 size = sizeof(srcFormat); + XThrowIfError(ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &size, &srcFormat), "couldn't get source data format"); + + printf("Source file format: "); srcFormat.Print(); + + // setup the output file format + dstFormat.mSampleRate = (outputSampleRate == 0 ? srcFormat.mSampleRate : outputSampleRate); // set sample rate + if (outputFormat == kAudioFormatLinearPCM) { + // if PCM was selected as the destination format, create a 16-bit int PCM file format description + dstFormat.mFormatID = outputFormat; + dstFormat.mChannelsPerFrame = srcFormat.NumberChannels(); + dstFormat.mBitsPerChannel = 16; + dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame; + dstFormat.mFramesPerPacket = 1; + dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian + } else { + // compressed format - need to set at least format, sample rate and channel fields for kAudioFormatProperty_FormatInfo + dstFormat.mFormatID = outputFormat; + dstFormat.mChannelsPerFrame = (outputFormat == kAudioFormatiLBC ? 1 : srcFormat.NumberChannels()); // for iLBC num channels must be 1 + + // use AudioFormat API to fill out the rest of the description + size = sizeof(dstFormat); + XThrowIfError(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &dstFormat), "couldn't create destination data format"); + } + + printf("Destination file format: "); dstFormat.Print(); + + // create the destination file + XThrowIfError(ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &destinationFile), "ExtAudioFileCreateWithURL failed!"); + + // set the client format - The format must be linear PCM (kAudioFormatLinearPCM) + // You must set this in order to encode or decode a non-PCM file data format + // You may set this on PCM files to specify the data format used in your calls to read/write + CAStreamBasicDescription clientFormat; + if (outputFormat == kAudioFormatLinearPCM) { + clientFormat = dstFormat; + } else { + clientFormat.SetCanonical(srcFormat.NumberChannels(), true); + clientFormat.mSampleRate = srcFormat.mSampleRate; + } + + size = sizeof(clientFormat); + XThrowIfError(ExtAudioFileSetProperty(sourceFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat), "couldn't set source client format"); + + size = sizeof(clientFormat); + XThrowIfError(ExtAudioFileSetProperty(destinationFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat), "couldn't set destination client format"); + + // can the audio converter (which in this case is owned by an ExtAudioFile object) resume conversion after an interruption? + AudioConverterRef audioConverter; + + size = sizeof(audioConverter); + XThrowIfError(ExtAudioFileGetProperty(destinationFile, kExtAudioFileProperty_AudioConverter, &size, &audioConverter), "Couldn't get Audio Converter!"); + + // this property may be queried at any time after construction of the audio converter (which in this case is owned by an ExtAudioFile object) + // after setting the output format -- there's no clear reason to prefer construction time, interruption time, or potential resumption time but we prefer + // construction time since it means less code to execute during or after interruption time + UInt32 canResume = 0; + size = sizeof(canResume); + error = AudioConverterGetProperty(audioConverter, kAudioConverterPropertyCanResumeFromInterruption, &size, &canResume); + if (noErr == error) { + // we recieved a valid return value from the GetProperty call + // if the property's value is 1, then the codec CAN resume work following an interruption + // if the property's value is 0, then interruptions destroy the codec's state and we're done + + if (0 == canResume) canResumeFromInterruption = false; + + printf("Audio Converter %s continue after interruption!\n", (canResumeFromInterruption == 0 ? "CANNOT" : "CAN")); + } else { + // if the property is unimplemented (kAudioConverterErr_PropertyNotSupported, or paramErr returned in the case of PCM), + // then the codec being used is not a hardware codec so we're not concerned about codec state + // we are always going to be able to resume conversion after an interruption + + if (kAudioConverterErr_PropertyNotSupported == error) { + printf("kAudioConverterPropertyCanResumeFromInterruption property not supported!\n"); + } else { + printf("AudioConverterGetProperty kAudioConverterPropertyCanResumeFromInterruption result %ld\n", error); + } + + error = noErr; + } + + // set up buffers + UInt32 bufferByteSize = 32768; + char srcBuffer[bufferByteSize]; + + // keep track of the source file offset so we know where to reset the source for + // reading if interrupted and input was not consumed by the audio converter + SInt64 sourceFrameOffset = 0; + + //***** do the read and write - the conversion is done on and by the write call *****// + printf("Converting...\n"); + while (1) { + + AudioBufferList fillBufList; + fillBufList.mNumberBuffers = 1; + fillBufList.mBuffers[0].mNumberChannels = clientFormat.NumberChannels(); + fillBufList.mBuffers[0].mDataByteSize = bufferByteSize; + fillBufList.mBuffers[0].mData = srcBuffer; + + // client format is always linear PCM - so here we determine how many frames of lpcm + // we can read/write given our buffer size + UInt32 numFrames = clientFormat.BytesToFrames(bufferByteSize); // (bufferByteSize / clientFormat.mBytesPerFrame); + + XThrowIfError(ExtAudioFileRead(sourceFile, &numFrames, &fillBufList), "ExtAudioFileRead failed!"); + if (!numFrames) { + // this is our termination condition + error = noErr; + break; + } + sourceFrameOffset += numFrames; + + // this will block if we're interrupted + Boolean wasInterrupted = ThreadStatePausedCheck(); + + if ((error || wasInterrupted) && (false == canResumeFromInterruption)) { + // this is our interruption termination condition + // an interruption has occured but the audio converter cannot continue + error = kMyAudioConverterErr_CannotResumeFromInterruptionError; + break; + } + + error = ExtAudioFileWrite(destinationFile, numFrames, &fillBufList); + // if interrupted in the process of the write call, we must handle the errors appropriately + if (error) { + if (kExtAudioFileError_CodecUnavailableInputConsumed == error) { + + printf("ExtAudioFileWrite kExtAudioFileError_CodecUnavailableInputConsumed error %ld\n", error); + + /* + Returned when ExtAudioFileWrite was interrupted. You must stop calling + ExtAudioFileWrite. If the underlying audio converter can resume after an + interruption (see kAudioConverterPropertyCanResumeFromInterruption), you must + wait for an EndInterruption notification from AudioSession, and call AudioSessionSetActive(true) + before resuming. In this situation, the buffer you provided to ExtAudioFileWrite was successfully + consumed and you may proceed to the next buffer + */ + + } else if (kExtAudioFileError_CodecUnavailableInputNotConsumed == error) { + + printf("ExtAudioFileWrite kExtAudioFileError_CodecUnavailableInputNotConsumed error %ld\n", error); + + /* + Returned when ExtAudioFileWrite was interrupted. You must stop calling + ExtAudioFileWrite. If the underlying audio converter can resume after an + interruption (see kAudioConverterPropertyCanResumeFromInterruption), you must + wait for an EndInterruption notification from AudioSession, and call AudioSessionSetActive(true) + before resuming. In this situation, the buffer you provided to ExtAudioFileWrite was not + successfully consumed and you must try to write it again + */ + + // seek back to last offset before last read so we can try again after the interruption + sourceFrameOffset -= numFrames; + XThrowIfError(ExtAudioFileSeek(sourceFile, sourceFrameOffset), "ExtAudioFileSeek failed!"); + + } else { + XThrowIfError(error, "ExtAudioFileWrite error!"); + } + } // if + } // while + } + catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + error = e.mError; + } + + // close + if (destinationFile) ExtAudioFileDispose(destinationFile); + if (sourceFile) ExtAudioFileDispose(sourceFile); + + // transition thread state to kStateDone before continuing + ThreadStateSetDone(); + + return error; +} \ No newline at end of file diff --git a/iPhoneExtAudioFileConvertTest/Info.plist b/iPhoneExtAudioFileConvertTest/Info.plist new file mode 100644 index 0000000..bc34a6e --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + eDTS + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/iPhoneExtAudioFileConvertTest/MainWindow.xib b/iPhoneExtAudioFileConvertTest/MainWindow.xib new file mode 100644 index 0000000..7b19647 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/MainWindow.xib @@ -0,0 +1,821 @@ + + + + 768 + 9L30 + 680 + 949.54 + 353.00 + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MCAwIDAAA + + NO + NO + YES + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 436} + + 1 + MSAxIDEAA + + NO + + + ExtAudioFile Convert + + + + + + + + 268 + + YES + + + 268 + {{-2250, 100}, {42, 21}} + + NO + YES + NO + Label + + + 1 + 1.000000e+01 + + + + 292 + {{20, 20}, {280, 420}} + + + YES + YES + YES + + + {320, 460} + + 3 + MQA + + 2 + + + NO + + + + 292 + + YES + + + 292 + {{59, 283}, {201, 40}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + NO + + + + Q29udmVydCAmIFBsYXkgRmlsZS4uLg + + + + + 3 + MAA + + + + + -2147483356 + {{141, 348}, {37, 37}} + + NO + NO + NO + 0 + + + + 292 + {{59, 220}, {201, 30}} + + NO + NO + 1 + 2 + 4 + 3 + + YES + 44.1k + 22k + 8k + Source + + + YES + + + + + + + YES + + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + + 292 + {{59, 191}, {155, 21}} + + NO + YES + NO + Output Sample Rate: + + Helvetica + 1.200000e+01 + 16 + + + + 1 + 1.000000e+01 + + + + 292 + {{59, 149}, {201, 30}} + + NO + NO + 2 + 4 + 3 + + YES + AAC + IMA + iLBC + PCM + + + YES + + + + + + + YES + + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + + 292 + {{59, 120}, {177, 21}} + + NO + YES + NO + Output Encoding Format: + + + + 1 + 1.000000e+01 + + + + 292 + {{20, 91}, {280, 21}} + + NO + YES + NO + Select the format and sample rate for output.caf file. + + + + 1 + 1.000000e+01 + + + + 292 + {{63, 20}, {194, 21}} + + NO + YES + NO + Audio File Format Information + + Helvetica + 1.400000e+01 + 16 + + + + 1 + 1.000000e+01 + + + + 292 + {{20, 49}, {280, 22}} + + NO + YES + NO + + + + + 1 + 1.000000e+01 + 1 + + + {320, 460} + + NO + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + instructionsView + + + + 26 + + + + contentView + + + + 27 + + + + navigationController + + + + 28 + + + + myViewController + + + + 29 + + + + activityIndicator + + + + 31 + + + + webView + + + + 32 + + + + startButton + + + + 33 + + + + outputFormatSelector + + + + 42 + + + + outputSampleRateSelector + + + + 43 + + + + segmentedControllerValueChanged: + + + 13 + + 44 + + + + segmentedControllerValueChanged: + + + 13 + + 45 + + + + fileInfo + + + + 50 + + + + convertButtonPressed: + + + 7 + + 51 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 10 + + + YES + + + + + + + 11 + + + YES + + + + + + + 12 + + + + + 13 + + + + + 14 + + + YES + + + + + InstructionsView + + + 18 + + + + + 19 + + + YES + + + + + + + + + + + + ContentView + + + 20 + + + + + 21 + + + + + 22 + + + YES + + + + + 30 + + + + + 38 + + + + + 39 + + + + + 40 + + + + + 41 + + + + + 47 + + + + + 48 + + + + + 49 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 10.IBViewEditorWindowController.showingLayoutRectangles + 11.CustomClassName + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBEditorWindowLastContentRect + 14.IBPluginDependency + 14.IBViewEditorWindowController.showingLayoutRectangles + 18.IBPluginDependency + 19.IBEditorWindowLastContentRect + 19.IBPluginDependency + 19.IBViewEditorWindowController.showingBoundsRectangles + 19.IBViewEditorWindowController.showingLayoutRectangles + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 30.IBPluginDependency + 38.IBPluginDependency + 39.IBPluginDependency + 40.IBPluginDependency + 41.IBPluginDependency + 47.IBPluginDependency + 48.IBPluginDependency + 49.IBPluginDependency + + + YES + UIApplication + UIResponder + {{143, 326}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + MyViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{113, 401}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{136, 396}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + {{789, 411}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ExtAudioFileConvertAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 51 + + + + YES + + ExtAudioFileConvertAppDelegate + NSObject + + YES + + YES + myViewController + navigationController + window + + + YES + MyViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/iPhoneExtAudioFileConvertTest.h + + + + MyViewController + UIViewController + + YES + + YES + convertButtonPressed: + segmentedControllerValueChanged: + + + YES + id + id + + + + YES + + YES + activityIndicator + contentView + fileInfo + instructionsView + outputFormatSelector + outputSampleRateSelector + startButton + webView + + + YES + UIActivityIndicatorView + UIView + UILabel + UIView + UISegmentedControl + UISegmentedControl + UIButton + UIWebView + + + + IBProjectSource + Classes/MyViewController.h + + + + UIView + UIResponder + + IBUserSource + + + + + + 0 + iPhoneExtAudioFileConvertTest.xcodeproj + 3 + 3.1 + + diff --git a/iPhoneExtAudioFileConvertTest/ReadMe.txt b/iPhoneExtAudioFileConvertTest/ReadMe.txt new file mode 100755 index 0000000..3699019 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/ReadMe.txt @@ -0,0 +1,72 @@ +iPhoneExtAudioFileConvertTest + +=========================================================================== +DESCRIPTION: + +iPhoneExtAudioFileConvertTest demonstrates the use of the ExtAudioFile API to convert from one audio format and file type to another. + +All the relevant code is in the file ExtAudioFileConvert.cpp. + +Touching the "Convert" button calls the function DoConvertFile() producing an output.caf file using the +encoding and sample rate chosen in the UI. The output.caf file is then played back after conversion using AVAudioPlayer +to confirm success. + +Audio format information for the source file and output file are also displayed. + +Interruption handling during audio processing (conversion) is also demonstrated. + +=========================================================================== +RELATED INFORMATION: + +Core Audio Overview +Extended Audio File Services Reference + +=========================================================================== +SPECIAL CONSIDERATIONS: + +AAC encoding requires iPhone OS 3.1 and a hardware capable device such as the iPhone 3GS. See IsAACHardwareEncoderAvailable +function in MyViewController.m + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iOS 4.0 or later + +=========================================================================== +PACKAGING LIST: + +iPhoneExtAudioFileConvertTest.h +iPhoneExtAudioFileConvertTest.m + +The ExtAudioFileConvertAppDelegate class defines the application delegate object, responsible for adding the navigation +controllers view to the application window. + +MyViewController.h +MyViewController.m + +The MyViewController class defines the controller object for the application. The object helps set up the user interface, +responds to and manages user interaction, and implements sound playback. + +ExtAudioFileConvert.cpp + +This file implements the DoConvertFile function which is called on a background thread from the MyViewController class. + +All the code demonstrating how to perform conversion is contained in this one file, the rest of the sample may be thought of +as a simple framework for the demonstration code in this file. + +Audio Format and Sample Rate choices presented in the UI are simply used for testing purposes, developers are free to choose any other +supported file type or encoding format and present these choices however they wish. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.0, tested with iPhone OS 3.1. First public release. +Version 1.1, tested with iPhone OS 4.0. Upgraded project to build with the iOS 4.0 SDK. + +================================================================================ +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/iPhoneExtAudioFileConvertTest/Resources/green_button.png b/iPhoneExtAudioFileConvertTest/Resources/green_button.png new file mode 100755 index 0000000..6c8b20e Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/Resources/green_button.png differ diff --git a/iPhoneExtAudioFileConvertTest/Resources/info.html b/iPhoneExtAudioFileConvertTest/Resources/info.html new file mode 100644 index 0000000..ea8b411 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/Resources/info.html @@ -0,0 +1,26 @@ + + +

Extended Audio File Converter Test

+ +

iPhoneExtAudioFileConvertTest demonstrates the use of the ExtAudioFile API to +convert from one audio format and file type to another and will support AAC encode +on appropriate hardware such as the iPhone 3GS. +

+ +

All the relevant code is in the file ExtAudioFileConvert.cpp.

+ +

Touching the "Convert" button calls the function DoConvertFile() producing an output.caf +file using the encoding and sample rate chosen in the UI.

+ +

The output.caf file is then played back after conversion using AVAudioPlayer to confirm success and +Audio format information for both the sournce and output file is displayed.

+ +

Interruption handling during audio processing (conversion) is also demonstrated.

+ +


+ +

Extended Audio File Services provides simplified audio file access, combining features of +Audio File Services and Audio Converter Services. It provides a unified interface for reading +and writing compressed as well as linear PCM audio files.

+
+
\ No newline at end of file diff --git a/iPhoneExtAudioFileConvertTest/Resources/red_button.png b/iPhoneExtAudioFileConvertTest/Resources/red_button.png new file mode 100755 index 0000000..42de34e Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/Resources/red_button.png differ diff --git a/iPhoneExtAudioFileConvertTest/Resources/sourceALAC.caf b/iPhoneExtAudioFileConvertTest/Resources/sourceALAC.caf new file mode 100644 index 0000000..c86b093 Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/Resources/sourceALAC.caf differ diff --git a/iPhoneExtAudioFileConvertTest/iPhoneExtAudioFileConvertTest.xcodeproj/project.pbxproj b/iPhoneExtAudioFileConvertTest/iPhoneExtAudioFileConvertTest.xcodeproj/project.pbxproj new file mode 100755 index 0000000..b56f3b9 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPhoneExtAudioFileConvertTest.xcodeproj/project.pbxproj @@ -0,0 +1,331 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 2B10C16F11F78BB000478519 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16811F78BB000478519 /* Icon-72.png */; }; + 2B10C17011F78BB000478519 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16911F78BB000478519 /* Icon-Small-50.png */; }; + 2B10C17111F78BB000478519 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16A11F78BB000478519 /* Icon-Small.png */; }; + 2B10C17211F78BB000478519 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16B11F78BB000478519 /* Icon-Small@2x.png */; }; + 2B10C17311F78BB000478519 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16C11F78BB000478519 /* Icon.png */; }; + 2B10C17411F78BB000478519 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16D11F78BB000478519 /* Icon@2x.png */; }; + 2B10C17511F78BB000478519 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 2B10C16E11F78BB000478519 /* iTunesArtwork */; }; + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C70F5383D30033DE8C /* AVFoundation.framework */; }; + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */; }; + 2B5F57F11045D68900B2688C /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B5F57EF1045D68900B2688C /* CAXException.cpp */; }; + 2B7C4896103733CC00139C02 /* sourceALAC.caf in Resources */ = {isa = PBXBuildFile; fileRef = 2B7C4895103733CC00139C02 /* sourceALAC.caf */; }; + 2BCFBF5C1037238200416C77 /* iPhoneExtAudioFileConvertTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCFBF5A1037238200416C77 /* iPhoneExtAudioFileConvertTest.m */; }; + 2BCFBF5E1037238A00416C77 /* ExtAudioFileConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BCFBF5D1037238A00416C77 /* ExtAudioFileConvert.cpp */; }; + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */; }; + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1C0F59F67E00D63998 /* green_button.png */; }; + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1D0F59F67E00D63998 /* red_button.png */; }; + 2BE30B230F59F67E00D63998 /* info.html in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1F0F59F67E00D63998 /* info.html */; }; + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* ExtAudioFileConvertTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExtAudioFileConvertTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B10C16811F78BB000478519 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 2B10C16911F78BB000478519 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 2B10C16A11F78BB000478519 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 2B10C16B11F78BB000478519 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 2B10C16C11F78BB000478519 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 2B10C16D11F78BB000478519 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 2B10C16E11F78BB000478519 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2B5F57EF1045D68900B2688C /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = ""; }; + 2B5F57F01045D68900B2688C /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = ""; }; + 2B7C4895103733CC00139C02 /* sourceALAC.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = sourceALAC.caf; path = Resources/sourceALAC.caf; sourceTree = ""; }; + 2BCFBF5A1037238200416C77 /* iPhoneExtAudioFileConvertTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iPhoneExtAudioFileConvertTest.m; sourceTree = ""; }; + 2BCFBF5B1037238200416C77 /* iPhoneExtAudioFileConvertTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneExtAudioFileConvertTest.h; sourceTree = ""; }; + 2BCFBF5D1037238A00416C77 /* ExtAudioFileConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtAudioFileConvert.cpp; sourceTree = ""; }; + 2BCFBF5F1037239A00416C77 /* iPhoneExtAudioFileConvertTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneExtAudioFileConvertTest_Prefix.pch; sourceTree = ""; }; + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = ""; }; + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = ""; }; + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + 2BE30B1C0F59F67E00D63998 /* green_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = green_button.png; path = Resources/green_button.png; sourceTree = ""; }; + 2BE30B1D0F59F67E00D63998 /* red_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = red_button.png; path = Resources/red_button.png; sourceTree = ""; }; + 2BE30B1F0F59F67E00D63998 /* info.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = info.html; path = Resources/info.html; sourceTree = ""; }; + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */, + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 2BCFBF5B1037238200416C77 /* iPhoneExtAudioFileConvertTest.h */, + 2BCFBF5A1037238200416C77 /* iPhoneExtAudioFileConvertTest.m */, + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */, + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ExtAudioFileConvertTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */, + 2BCFBF5D1037238A00416C77 /* ExtAudioFileConvert.cpp */, + 080E96DDFE201D6D7F000001 /* Classes */, + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 2BCFBF5F1037239A00416C77 /* iPhoneExtAudioFileConvertTest_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 2BE30B1C0F59F67E00D63998 /* green_button.png */, + 2BE30B1D0F59F67E00D63998 /* red_button.png */, + 2B7C4895103733CC00139C02 /* sourceALAC.caf */, + 2BE30B1F0F59F67E00D63998 /* info.html */, + 2B10C16811F78BB000478519 /* Icon-72.png */, + 2B10C16911F78BB000478519 /* Icon-Small-50.png */, + 2B10C16A11F78BB000478519 /* Icon-Small.png */, + 2B10C16B11F78BB000478519 /* Icon-Small@2x.png */, + 2B10C16C11F78BB000478519 /* Icon.png */, + 2B10C16D11F78BB000478519 /* Icon@2x.png */, + 2B10C16E11F78BB000478519 /* iTunesArtwork */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */, + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */ = { + isa = PBXGroup; + children = ( + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */, + 2B5F57F01045D68900B2688C /* CAXException.h */, + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */, + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */, + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */, + 2B5F57EF1045D68900B2688C /* CAXException.cpp */, + ); + path = iPublicUtility; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ExtAudioFileConvertTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ExtAudioFileConvertTest" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ExtAudioFileConvertTest; + productName = AQOffilineRenderTest; + productReference = 1D6058910D05DD3D006BFB54 /* ExtAudioFileConvertTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneExtAudioFileConvertTest" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ExtAudioFileConvertTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */, + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */, + 2BE30B230F59F67E00D63998 /* info.html in Resources */, + 2B7C4896103733CC00139C02 /* sourceALAC.caf in Resources */, + 2B10C16F11F78BB000478519 /* Icon-72.png in Resources */, + 2B10C17011F78BB000478519 /* Icon-Small-50.png in Resources */, + 2B10C17111F78BB000478519 /* Icon-Small.png in Resources */, + 2B10C17211F78BB000478519 /* Icon-Small@2x.png in Resources */, + 2B10C17311F78BB000478519 /* Icon.png in Resources */, + 2B10C17411F78BB000478519 /* Icon@2x.png in Resources */, + 2B10C17511F78BB000478519 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */, + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */, + 2BCFBF5C1037238200416C77 /* iPhoneExtAudioFileConvertTest.m in Sources */, + 2BCFBF5E1037238A00416C77 /* ExtAudioFileConvert.cpp in Sources */, + 2B5F57F11045D68900B2688C /* CAXException.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneExtAudioFileConvertTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = ExtAudioFileConvertTest; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneExtAudioFileConvertTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = ExtAudioFileConvertTest; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + STRIP_INSTALLED_PRODUCT = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ExtAudioFileConvertTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneExtAudioFileConvertTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/iPhoneExtAudioFileConvertTest/iPhoneExtAudioFileConvertTest_Prefix.pch b/iPhoneExtAudioFileConvertTest/iPhoneExtAudioFileConvertTest_Prefix.pch new file mode 100644 index 0000000..a17209c --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPhoneExtAudioFileConvertTest_Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iPhoneExtAudioFileConvertTest/iPublicUtility/CADebugMacros.h b/iPhoneExtAudioFileConvertTest/iPublicUtility/CADebugMacros.h new file mode 100755 index 0000000..3c697ae --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPublicUtility/CADebugMacros.h @@ -0,0 +1,440 @@ +/* + + File: CADebugMacros.h +Abstract: Helper class for printing debug messages + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#if !defined(__CADebugMacros_h__) +#define __CADebugMacros_h__ + +//============================================================================= +// Includes +//============================================================================= + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CADebugMacros +//============================================================================= + +//#define CoreAudio_StopOnFailure 1 +//#define CoreAudio_TimeStampMessages 1 +//#define CoreAudio_ThreadStampMessages 1 +//#define CoreAudio_FlushDebugMessages 1 + +#if TARGET_RT_BIG_ENDIAN + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } +#else + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } +#endif + +#pragma mark Basic Definitions + +#if DEBUG || CoreAudio_Debug + + // can be used to break into debugger immediately, also see CADebugger + #define BusError() (*(long *)0 = 0) + + // basic debugging print routines + #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON + extern void DebugStr(const unsigned char* debuggerMsg); + #define DebugMessage(msg) DebugStr("\p"msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #else + #include "CADebugPrintf.h" + + #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) + #define FlushRtn ,fflush(DebugPrintfFile) + #else + #define FlushRtn + #endif + + #if CoreAudio_ThreadStampMessages + #include + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #elif CoreAudio_TimeStampMessages + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #else + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%s"DebugPrintfLineEnding, msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #endif + #endif + void DebugPrint(const char *fmt, ...); // can be used like printf + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) + #endif + #if VERBOSE + #define vprint(msg) DEBUGPRINT(msg) + #else + #define vprint(msg) + #endif + + #if CoreAudio_StopOnFailure + #include "CADebugger.h" + #define STOP CADebuggerStop() + #else + #define STOP + #endif + +#else + #define DebugMessage(msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #define DebugMessageN4(msg, N1, N2, N3, N4) + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) + #define DEBUGPRINT(msg) + #define vprint(msg) + #define STOP +#endif + +void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) +void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) + +#if DEBUG || CoreAudio_Debug + +#pragma mark Debug Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + DebugMessage(inMethodName": Subclasses must implement this method"); \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#else + +#pragma mark Release Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + if((inKernelError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + if((inError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#endif // DEBUG || CoreAudio_Debug + +#endif diff --git a/iPhoneExtAudioFileConvertTest/iPublicUtility/CAMath.h b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAMath.h new file mode 100755 index 0000000..def9151 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAMath.h @@ -0,0 +1,71 @@ +/* + + File: CAMath.h +Abstract: Helper class for various math functions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#ifndef __CAMath_h__ +#define __CAMath_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +inline bool fiszero(Float64 f) { return (f == 0.); } +inline bool fiszero(Float32 f) { return (f == 0.f); } + +inline bool fnonzero(Float64 f) { return !fiszero(f); } +inline bool fnonzero(Float32 f) { return !fiszero(f); } + +inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } +inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } + +inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } +inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } + +#endif // __CAMath_h__ diff --git a/iPhoneExtAudioFileConvertTest/iPublicUtility/CAStreamBasicDescription.cpp b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAStreamBasicDescription.cpp new file mode 100755 index 0000000..6307741 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,552 @@ +/* + + File: CAStreamBasicDescription.cpp +Abstract: Helper class for audio stream descriptions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#include "CAStreamBasicDescription.h" +#include "CAMath.h" + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +#if TARGET_OS_WIN32 + #include +#endif + +#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; + mReserved = 0; +} + +char *CAStreamBasicDescription::AsString(char *buf, size_t bufsize) const +{ + char *theBuffer = buf; + int nc; + char formatID[5]; + *(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID); + formatID[4] = '\0'; + nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); + buf += nc; bufsize -= nc; + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (wordSize > 0 && PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + sprintf(packed, "packed in %d bytes", wordSize); + else + sprintf(packed, "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + char bitdepth[20]; + +#if CA_PREFER_FIXED_POINT + int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; + if (fracbits > 0) + sprintf(bitdepth, "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); + else +#endif + sprintf(bitdepth, "%d", (int)mBitsPerChannel); + + nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s", + bitdepth, endian, sign, floatInt, + commaSpace, packed, align, deinter); + //buf += nc; bufsize -= nc; + } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless + int sourceBits = 0; + switch (mFormatFlags) + { + case 1: // kAppleLosslessFormatFlag_16BitSourceData + sourceBits = 16; + break; + case 2: // kAppleLosslessFormatFlag_20BitSourceData + sourceBits = 20; + break; + case 3: // kAppleLosslessFormatFlag_24BitSourceData + sourceBits = 24; + break; + case 4: // kAppleLosslessFormatFlag_32BitSourceData + sourceBits = 32; + break; + } + if (sourceBits) + nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits); + else + nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, "); + buf += nc; bufsize -= nc; + nc = snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket); + //buf += nc; bufsize -= nc; + } + else + nc = snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", + (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); + return theBuffer; +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format + if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) + { + // the canonical linear PCM format + ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; + ioDescription.mBytesPerPacket = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerFrame = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType); + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(fiszero(ioDescription.mSampleRate)) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + const char* theMixabilityString = NULL; + if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) + { + theMixabilityString = "Mixable"; + } + else + { + theMixabilityString = "Unmixable"; + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strcpy(outName, "AC-3"); + break; + + case kAudioFormat60958AC3: + strcpy(outName, "AC-3 for SPDIF"); + break; + + default: + CACopy4CCToCString(outName, inDescription.mFormatID); + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + + // mixable is always better than non-mixable for linear PCM and should be the second order sort item + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) + { + theAnswer = true; + isDone = true; + } + else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) + { + theAnswer = false; + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) + { + if(fnotequal(x.mSampleRate, y.mSampleRate)) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + + // if the number of channels is 0 or 1, we don't care about non-interleavedness + if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) { + xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const +{ + if (interpretingWildcards) + return *this == other; + return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0.) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024); +} diff --git a/iPhoneExtAudioFileConvertTest/iPublicUtility/CAStreamBasicDescription.h b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAStreamBasicDescription.h new file mode 100755 index 0000000..dcbe051 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,310 @@ +/* + + File: CAStreamBasicDescription.h +Abstract: Helper class for audio stream descriptions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CoreFoundation.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it + +// define Leopard specific symbols for backward compatibility if applicable +#if COREAUDIOTYPES_VERSION < 1050 +typedef Float32 AudioSampleType; +enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; +#endif +#if COREAUDIOTYPES_VERSION < 1051 +typedef Float32 AudioUnitSampleType; +#endif + +// define the IsMixable format flag for all versions of the system +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; +#else + enum { kIsNonMixableFlag = (1L << 6) }; +#endif + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { + return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; + } + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; +#if CA_ENV_MACOSX + int sampleSize = sizeof(Float32); + mFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + int sampleSize = sizeof(AudioSampleType); + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mBitsPerChannel = 8 * sampleSize; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; + else { + mBytesPerPacket = mBytesPerFrame = sampleSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + bool IsCanonical() const + { + if (mFormatID != kAudioFormatLinearPCM) return false; + UInt32 reqFormatFlags; +#if (COREAUDIOTYPES_VERSION <= 1050) + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh); +#else + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); +#endif + bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; +#if CA_ENV_MACOSX + unsigned sampleSize = sizeof(Float32); + reqFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + unsigned sampleSize = sizeof(AudioSampleType); + reqFormatFlags = kAudioFormatFlagsCanonical; +#endif + UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; + + return ((mFormatFlags & flagsMask) == reqFormatFlags + && mBitsPerChannel == 8 * sampleSize + && mFramesPerPacket == 1 + && mBytesPerFrame == reqFrameSize + && mBytesPerPacket == reqFrameSize); + } + + void SetAUCanonical(UInt32 nChannels, bool interleaved) + { + mFormatID = kAudioFormatLinearPCM; +#if CA_PREFER_FIXED_POINT + mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); +#else + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); + else { + mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + if (wordSize == 0) + wordSize = (mBitsPerChannel + 7) / 8; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; + + void Print() const { + Print (stdout); + } + + void Print(FILE* file) const { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const { + char buf[256]; + fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); + } + + void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline + char buf[256]; + fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); + } + + char * AsString(char *buf, size_t bufsize) const; + + static void Print (const AudioStreamBasicDescription &inDesc) + { + CAStreamBasicDescription desc(inDesc); + desc.Print (); + } + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__ diff --git a/iPhoneExtAudioFileConvertTest/iPublicUtility/CAXException.cpp b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAXException.cpp new file mode 100644 index 0000000..da39296 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAXException.cpp @@ -0,0 +1,43 @@ +/* Copyright � 2007 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#include "CAXException.h" + +CAXException::WarningHandler CAXException::sWarningHandler = NULL; diff --git a/iPhoneExtAudioFileConvertTest/iPublicUtility/CAXException.h b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAXException.h new file mode 100644 index 0000000..623b32f --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/iPublicUtility/CAXException.h @@ -0,0 +1,189 @@ +/* Copyright � 2007 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef __CAXException_h__ +#define __CAXException_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif +#include "CADebugMacros.h" +#include +#include +#include + +// An extended exception class that includes the name of the failed operation +class CAXException { +public: + CAXException(const char *operation, OSStatus err) : + mError(err) + { + if (operation == NULL) + mOperation[0] = '\0'; + else if (strlen(operation) >= sizeof(mOperation)) { + memcpy(mOperation, operation, sizeof(mOperation) - 1); + mOperation[sizeof(mOperation) - 1] = '\0'; + } else + strcpy(mOperation, operation); + } + + char *FormatError(char *str) const + { + return FormatError(str, mError); + } + + char mOperation[256]; + const OSStatus mError; + + // ------------------------------------------------- + + typedef void (*WarningHandler)(const char *msg, OSStatus err); + + /*static void Throw(const char *operation, OSStatus err) + { + throw CAXException(operation, err); + }*/ + + static char *FormatError(char *str, OSStatus error) + { + // see if it appears to be a 4-char-code + *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); + if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { + str[0] = str[5] = '\''; + str[6] = '\0'; + } else + // no, format it as an integer + sprintf(str, "%d", (int)error); + return str; + } + + static void Warning(const char *s, OSStatus error) + { + if (sWarningHandler) + (*sWarningHandler)(s, error); + } + + static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } +private: + static WarningHandler sWarningHandler; +}; + +#if DEBUG || CoreAudio_Debug + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + } \ + } while (0) + +#else + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + /*OSStatus __err =*/ error; \ + } while (0) +#endif + +#define XThrow(error, operation) XThrowIf(true, error, operation) +#define XThrowIfErr(error) XThrowIfError(error, #error) + +#endif // __CAXException_h__ diff --git a/iPhoneExtAudioFileConvertTest/images/Icon-72.png b/iPhoneExtAudioFileConvertTest/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/Icon-72.png differ diff --git a/iPhoneExtAudioFileConvertTest/images/Icon-Small-50.png b/iPhoneExtAudioFileConvertTest/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/Icon-Small-50.png differ diff --git a/iPhoneExtAudioFileConvertTest/images/Icon-Small.png b/iPhoneExtAudioFileConvertTest/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/Icon-Small.png differ diff --git a/iPhoneExtAudioFileConvertTest/images/Icon-Small@2x.png b/iPhoneExtAudioFileConvertTest/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/Icon-Small@2x.png differ diff --git a/iPhoneExtAudioFileConvertTest/images/Icon.png b/iPhoneExtAudioFileConvertTest/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/Icon.png differ diff --git a/iPhoneExtAudioFileConvertTest/images/Icon@2x.png b/iPhoneExtAudioFileConvertTest/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/Icon@2x.png differ diff --git a/iPhoneExtAudioFileConvertTest/images/iTunesArtwork b/iPhoneExtAudioFileConvertTest/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/iPhoneExtAudioFileConvertTest/images/iTunesArtwork differ diff --git a/iPhoneExtAudioFileConvertTest/main.m b/iPhoneExtAudioFileConvertTest/main.m new file mode 100644 index 0000000..cbb8456 --- /dev/null +++ b/iPhoneExtAudioFileConvertTest/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: main + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/iPhoneMixerEQGraphTest.zip b/iPhoneMixerEQGraphTest.zip new file mode 100644 index 0000000..b87b0ae Binary files /dev/null and b/iPhoneMixerEQGraphTest.zip differ diff --git a/iPhoneMixerEQGraphTest/Classes/AUGraphController.h b/iPhoneMixerEQGraphTest/Classes/AUGraphController.h new file mode 100755 index 0000000..4dde279 --- /dev/null +++ b/iPhoneMixerEQGraphTest/Classes/AUGraphController.h @@ -0,0 +1,101 @@ +/* + File: AUGraphController.h + Abstract: Sets up the AUGraph, loading up the audio data using ExtAudioFile, the input render procedure and so on. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import +#import +#import + +#import "CAStreamBasicDescription.h" +#import "CAComponentDescription.h" + +#define MAXBUFS 2 +#define NUMFILES 2 + +typedef struct { + AudioStreamBasicDescription asbd; + AudioSampleType *data; + UInt32 numFrames; +} SoundBuffer, *SoundBufferPtr; + +typedef struct { + UInt32 frameNum; + UInt32 maxNumFrames; + SoundBuffer soundBuffer[MAXBUFS]; +} SourceAudioBufferData, *SourceAudioBufferDataPtr; + +@interface AUGraphController : NSObject +{ + CFURLRef sourceURL[2]; + + AUGraph mGraph; + AudioUnit mEQ; + AudioUnit mMixer; + + CAStreamBasicDescription mClientFormat; + CAStreamBasicDescription mOutputFormat; + + CFArrayRef mEQPresetsArray; + + SourceAudioBufferData mUserData; + + Boolean mIsPlaying; +} + +@property (readonly, nonatomic, getter=isPlaying) Boolean mIsPlaying; +@property (readonly, nonatomic, getter=iPodEQPresetsArray) CFArrayRef mEQPresetsArray; + +- (void)initializeAUGraph; + +- (void)enableInput:(UInt32)inputNum isOn:(AudioUnitParameterValue)isONValue; +- (void)setInputVolume:(UInt32)inputNum value:(AudioUnitParameterValue)value; +- (void)setOutputVolume:(AudioUnitParameterValue)value; +- (void)selectEQPreset:(NSInteger)value; + +- (void)startAUGraph; +- (void)stopAUGraph; + +@end diff --git a/iPhoneMixerEQGraphTest/Classes/AUGraphController.mm b/iPhoneMixerEQGraphTest/Classes/AUGraphController.mm new file mode 100755 index 0000000..c904c11 --- /dev/null +++ b/iPhoneMixerEQGraphTest/Classes/AUGraphController.mm @@ -0,0 +1,431 @@ +/* + File: AUGraphController.mm +Abstract: Sets up the AUGraph, loading up the audio data using ExtAudioFile, the input render procedure and so on. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "AUGraphController.h" + +const Float64 kGraphSampleRate = 44100.0; + +#pragma mark- Render + +// render some silence +static void SilenceData(AudioBufferList *inData) +{ + for (UInt32 i=0; i < inData->mNumberBuffers; i++) + memset(inData->mBuffers[i].mData, 0, inData->mBuffers[i].mDataByteSize); +} + +// audio render procedure to render our client data format +// 2 ch 'lpcm' 16-bit little-endian signed integer interleaved this is mClientFormat data, see CAStreamBasicDescription SetCanonical() +static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) +{ + SourceAudioBufferDataPtr userData = (SourceAudioBufferDataPtr)inRefCon; + + AudioSampleType *in = userData->soundBuffer[inBusNumber].data; + AudioSampleType *out = (AudioSampleType *)ioData->mBuffers[0].mData; + + UInt32 sample = userData->frameNum * userData->soundBuffer[inBusNumber].asbd.mChannelsPerFrame; + + // make sure we don't attempt to render more data than we have available in the source buffers + // if one buffer is larger than the other, just render silence for that bus until we loop around again + if ((userData->frameNum + inNumberFrames) > userData->soundBuffer[inBusNumber].numFrames) { + UInt32 offset = (userData->frameNum + inNumberFrames) - userData->soundBuffer[inBusNumber].numFrames; + if (offset < inNumberFrames) { + // copy the last bit of source + SilenceData(ioData); + memcpy(out, &in[sample], ((inNumberFrames - offset) * userData->soundBuffer[inBusNumber].asbd.mBytesPerFrame)); + return noErr; + } else { + // got no source data + SilenceData(ioData); + *ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence; + return noErr; + } + } + + memcpy(out, &in[sample], ioData->mBuffers[0].mDataByteSize); + + //printf("render input bus %ld sample %ld\n", inBusNumber, sample); + + return noErr; +} + +// the render notification is used to keep track of the frame number position in the source audio +static OSStatus renderNotification(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) +{ + SourceAudioBufferDataPtr userData = (SourceAudioBufferDataPtr)inRefCon; + + if (*ioActionFlags & kAudioUnitRenderAction_PostRender) { + + //printf("post render notification frameNum %ld inNumberFrames %ld\n", userData->frameNum, inNumberFrames); + + userData->frameNum += inNumberFrames; + if (userData->frameNum >= userData->maxNumFrames) { + userData->frameNum = 0; + } + } + + return noErr; +} + +#pragma mark- AUGraphController + +@interface AUGraphController (hidden) + +- (void)loadFiles; + +@end + +@implementation AUGraphController + +@synthesize mIsPlaying, mEQPresetsArray; + +- (void)dealloc +{ + printf("AUGraphController dealloc\n"); + + DisposeAUGraph(mGraph); + + free(mUserData.soundBuffer[0].data); + free(mUserData.soundBuffer[1].data); + + CFRelease(sourceURL[0]); + CFRelease(sourceURL[1]); + + CFRelease(mEQPresetsArray); + + [super dealloc]; +} + +- (void)awakeFromNib +{ + printf("AUGraphController awakeFromNib\n"); + + mIsPlaying = false; + + // clear the mSoundBuffer struct + memset(&mUserData.soundBuffer, 0, sizeof(mUserData.soundBuffer)); + + // create the URLs we'll use for source A and B + NSString *sourceA = [[NSBundle mainBundle] pathForResource:@"Track1" ofType:@"mp4"]; + NSString *sourceB = [[NSBundle mainBundle] pathForResource:@"Track2" ofType:@"mp4"]; + sourceURL[0] = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)sourceA, kCFURLPOSIXPathStyle, false); + sourceURL[1] = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)sourceB, kCFURLPOSIXPathStyle, false); +} + +- (void)initializeAUGraph +{ + printf("initializeAUGraph\n"); + + AUNode outputNode; + AUNode eqNode; + AUNode mixerNode; + + printf("create client ASBD\n"); + + // client format audio goes into the mixer + mClientFormat.SetCanonical(2, true); + mClientFormat.mSampleRate = kGraphSampleRate; + mClientFormat.Print(); + + printf("create output ASBD\n"); + + // output format + mOutputFormat.SetAUCanonical(2, false); + mOutputFormat.mSampleRate = kGraphSampleRate; + mOutputFormat.Print(); + + OSStatus result = noErr; + + // load up the audio data + [self performSelectorInBackground:@selector(loadFiles) withObject:nil]; + + printf("new AUGraph\n"); + + // create a new AUGraph + result = NewAUGraph(&mGraph); + if (result) { printf("NewAUGraph result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + // create three CAComponentDescription for the AUs we want in the graph + + // output unit + CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple); + + // iPodEQ unit + CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple); + + // multichannel mixer unit + CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple); + + printf("add nodes\n"); + + // create a node in the graph that is an AudioUnit, using the supplied AudioComponentDescription to find and open that unit + result = AUGraphAddNode(mGraph, &output_desc, &outputNode); + if (result) { printf("AUGraphNewNode 1 result %lu %4.4s\n", result, (char*)&result); return; } + + result = AUGraphAddNode(mGraph, &eq_desc, &eqNode); + if (result) { printf("AUGraphNewNode 2 result %lu %4.4s\n", result, (char*)&result); return; } + + result = AUGraphAddNode(mGraph, &mixer_desc, &mixerNode); + if (result) { printf("AUGraphNewNode 3 result %lu %4.4s\n", result, (char*)&result); return; } + + // connect a node's output to a node's input + // mixer -> eq -> output + result = AUGraphConnectNodeInput(mGraph, mixerNode, 0, eqNode, 0); + if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; } + + result = AUGraphConnectNodeInput(mGraph, eqNode, 0, outputNode, 0); + if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; } + + // open the graph AudioUnits are open but not initialized (no resource allocation occurs here) + result = AUGraphOpen(mGraph); + if (result) { printf("AUGraphOpen result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + // grab the audio unit instances from the nodes + result = AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer); + if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + result = AUGraphNodeInfo(mGraph, eqNode, NULL, &mEQ); + if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + // set bus count + UInt32 numbuses = 2; + + printf("set input bus count %lu\n", numbuses); + + result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &numbuses, sizeof(numbuses)); + if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + for (int i = 0; i < numbuses; ++i) { + // setup render callback struct + AURenderCallbackStruct rcbs; + rcbs.inputProc = &renderInput; + rcbs.inputProcRefCon = &mUserData; + + printf("set AUGraphSetNodeInputCallback\n"); + + // set a callback for the specified node's specified input + result = AUGraphSetNodeInputCallback(mGraph, mixerNode, i, &rcbs); + if (result) { printf("AUGraphSetNodeInputCallback result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + printf("set input bus %d, client kAudioUnitProperty_StreamFormat\n", i); + + // set the input stream format, this is the format of the audio for mixer input + result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, i, &mClientFormat, sizeof(mClientFormat)); + if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + } + + printf("get EQ kAudioUnitProperty_FactoryPresets\n"); + + // get the eq's factory preset list -- this is a read-only CFArray array of AUPreset structures + // host owns the retuned array and should release it when no longer needed + UInt32 size = sizeof(mEQPresetsArray); + result = AudioUnitGetProperty(mEQ, kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, &mEQPresetsArray, &size); + if (result) { printf("AudioUnitGetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + /* this code can be used if you're interested in dumping out the preset list + printf("iPodEQ Factory Preset List:\n"); + UInt8 count = CFArrayGetCount(mEQPresetsArray); + for (int i = 0; i < count; ++i) { + AUPreset *aPreset = (AUPreset*)CFArrayGetValueAtIndex(mEQPresetsArray, i); + CFShow(aPreset->presetName); + }*/ + + printf("set output kAudioUnitProperty_StreamFormat\n"); + + // set the output stream format of the mixer + result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat)); + if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + printf("set render notification\n"); + + // add a render notification, this is a callback that the graph will call every time the graph renders + // the callback will be called once before the graph’s render operation, and once after the render operation is complete + result = AUGraphAddRenderNotify(mGraph, renderNotification, &mUserData); + if (result) { printf("AUGraphAddRenderNotify result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + printf("AUGraphInitialize\n"); + + // now that we've set everything up we can initialize the graph, this will also validate the connections + result = AUGraphInitialize(mGraph); + if (result) { printf("AUGraphInitialize result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + CAShow(mGraph); +} + +// load up audio data from the demo files into mSoundBuffer.data used in the render proc +- (void)loadFiles +{ + mUserData.frameNum = 0; + mUserData.maxNumFrames = 0; + + for (int i = 0; i < NUMFILES && i < MAXBUFS; i++) { + printf("loadFiles, %d\n", i); + + ExtAudioFileRef xafref = 0; + + // open one of the two source files + OSStatus result = ExtAudioFileOpenURL(sourceURL[i], &xafref); + if (result || !xafref) { printf("ExtAudioFileOpenURL result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + // get the file data format, this represents the file's actual data format + // for informational purposes only -- the client format set on ExtAudioFile is what we really want back + CAStreamBasicDescription fileFormat; + UInt32 propSize = sizeof(fileFormat); + + result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileDataFormat, &propSize, &fileFormat); + if (result) { printf("ExtAudioFileGetProperty kExtAudioFileProperty_FileDataFormat result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + printf("file %d, native file format\n", i); + fileFormat.Print(); + + // set the client format to be what we want back + // this is the same format audio we're giving to the the mixer input + result = ExtAudioFileSetProperty(xafref, kExtAudioFileProperty_ClientDataFormat, sizeof(mClientFormat), &mClientFormat); + if (result) { printf("ExtAudioFileSetProperty kExtAudioFileProperty_ClientDataFormat %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + // get the file's length in sample frames + UInt64 numFrames = 0; + propSize = sizeof(numFrames); + result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileLengthFrames, &propSize, &numFrames); + if (result) { printf("ExtAudioFileGetProperty kExtAudioFileProperty_FileLengthFrames result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + // keep track of the largest number of source frames + if (numFrames > mUserData.maxNumFrames) mUserData.maxNumFrames = numFrames; + + // set up our buffer + mUserData.soundBuffer[i].numFrames = numFrames; + mUserData.soundBuffer[i].asbd = mClientFormat; + + UInt32 samples = numFrames * mUserData.soundBuffer[i].asbd.mChannelsPerFrame; + mUserData.soundBuffer[i].data = (AudioSampleType *)calloc(samples, sizeof(AudioSampleType)); + + // set up a AudioBufferList to read data into + AudioBufferList bufList; + bufList.mNumberBuffers = 1; + bufList.mBuffers[0].mNumberChannels = mUserData.soundBuffer[i].asbd.mChannelsPerFrame; + bufList.mBuffers[0].mData = mUserData.soundBuffer[i].data; + bufList.mBuffers[0].mDataByteSize = samples * sizeof(AudioSampleType); + + // perform a synchronous sequential read of the audio data out of the file into our allocated data buffer + UInt32 numPackets = numFrames; + result = ExtAudioFileRead(xafref, &numPackets, &bufList); + if (result) { + printf("ExtAudioFileRead result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); + free(mUserData.soundBuffer[i].data); + mUserData.soundBuffer[i].data = 0; + return; + } + + // close the file and dispose the ExtAudioFileRef + ExtAudioFileDispose(xafref); + } +} + +#pragma mark- + +// enable or disables a specific bus +- (void)enableInput:(UInt32)inputNum isOn:(AudioUnitParameterValue)isONValue +{ + printf("BUS %ld isON %f\n", inputNum, isONValue); + + OSStatus result = AudioUnitSetParameter(mMixer, kMultiChannelMixerParam_Enable, kAudioUnitScope_Input, inputNum, isONValue, 0); + if (result) { printf("AudioUnitSetParameter kMultiChannelMixerParam_Enable result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + +} + +// sets the input volume for a specific bus +- (void)setInputVolume:(UInt32)inputNum value:(AudioUnitParameterValue)value +{ + OSStatus result = AudioUnitSetParameter(mMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, inputNum, value, 0); + if (result) { printf("AudioUnitSetParameter kMultiChannelMixerParam_Volume Input result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } +} + +// sets the overall mixer output volume +- (void)setOutputVolume:(AudioUnitParameterValue)value +{ + OSStatus result = AudioUnitSetParameter(mMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, 0, value, 0); + if (result) { printf("AudioUnitSetParameter kMultiChannelMixerParam_Volume Output result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } +} + +- (void)selectEQPreset:(NSInteger)value; +{ + AUPreset *aPreset = (AUPreset*)CFArrayGetValueAtIndex(mEQPresetsArray, value); + OSStatus result = AudioUnitSetProperty(mEQ, kAudioUnitProperty_PresentPreset, kAudioUnitScope_Global, 0, aPreset, sizeof(AUPreset)); + if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }; + + printf("SET EQ PRESET %d ", value); + CFShow(aPreset->presetName); +} + +// stars render +- (void)startAUGraph +{ + printf("PLAY\n"); + + OSStatus result = AUGraphStart(mGraph); + if (result) { printf("AUGraphStart result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + mIsPlaying = true; +} + +// stops render +- (void)stopAUGraph +{ + printf("STOP\n"); + + Boolean isRunning = false; + + OSStatus result = AUGraphIsRunning(mGraph, &isRunning); + if (result) { printf("AUGraphIsRunning result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + + if (isRunning) { + result = AUGraphStop(mGraph); + if (result) { printf("AUGraphStop result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; } + mIsPlaying = false; + } +} + +@end \ No newline at end of file diff --git a/iPhoneMixerEQGraphTest/Classes/MixerEQGraphTestDelegate.h b/iPhoneMixerEQGraphTest/Classes/MixerEQGraphTestDelegate.h new file mode 100644 index 0000000..378b662 --- /dev/null +++ b/iPhoneMixerEQGraphTest/Classes/MixerEQGraphTestDelegate.h @@ -0,0 +1,65 @@ +/* + File: MixerEQGraphTestDelegate.h +Abstract: The application delegate class. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +#import "MyViewController.h"file +#import "CAXException.h" + +@interface MixerEQGraphTestDelegate : NSObject { + UIWindow *window; + + UINavigationController *navigationController; + MyViewController *myViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet MyViewController *myViewController; + +@end + diff --git a/iPhoneMixerEQGraphTest/Classes/MixerEQGraphTestDelegate.m b/iPhoneMixerEQGraphTest/Classes/MixerEQGraphTestDelegate.m new file mode 100644 index 0000000..a57f27c --- /dev/null +++ b/iPhoneMixerEQGraphTest/Classes/MixerEQGraphTestDelegate.m @@ -0,0 +1,160 @@ +/* + File: MixerEQGraphTestDelegate.m +Abstract: The application delegate class. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MixerEQGraphTestDelegate.h" + +@implementation MixerEQGraphTestDelegate + +@synthesize window, navigationController, myViewController; + +#pragma mark -Audio Session Interruption Listener + +static void interruptionListener(void *inClientData, UInt32 inInterruption) +{ + printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + MixerEQGraphTestDelegate *THIS = (MixerEQGraphTestDelegate *)inClientData; + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + AudioSessionSetActive(true); + } + + if (inInterruption == kAudioSessionBeginInterruption) { + // session is already set to not active so if we're playing stop + [THIS->myViewController stopForInterruption]; + } +} + +#pragma mark -Audio Session Property Listener + +static void propertyListener(void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) +{ + if (inID == kAudioSessionProperty_AudioRouteChange) { + try { + CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inData; + + UInt32 routeChangeReason; + CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); + CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); + printf("Audio Route Change, Reason: %ld\n", routeChangeReason); + + CFStringRef routeChangeOldRouteRef = (CFStringRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute)); + printf("Old Route: "); + CFShow(routeChangeOldRouteRef); + + CFStringRef newRoute; + UInt32 size = sizeof(newRoute); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute), "couldn't get new audio route"); + if (newRoute) { + printf("New Route: "); + CFShow(newRoute); + } + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + } +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after application launch + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; + + try { + // initialize and configure the audio session + XThrowIfError(AudioSessionInitialize(NULL, NULL, interruptionListener, self), "couldn't initialize audio session"); + + UInt32 audioCategory = kAudioSessionCategory_MediaPlayback; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory), "couldn't set audio category"); + XThrowIfError(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propertyListener, self), "couldn't set property listener"); + + // 5ms preferred buffer size + Float32 bufferDuration = .005; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(bufferDuration), &bufferDuration), "couldn't set i/o buffer duration"); + + // 44.1kHz preferred hardware sample rate + Float64 hwSampleRate = 44100.0; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(hwSampleRate), &hwSampleRate), "couldn't set hw sample rate"); + + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active\n"); + + UInt32 size = sizeof(bufferDuration); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &size, &bufferDuration), "couldn't get iobuffer duration"); + printf("Current IOBufferDuration: %fms\n", bufferDuration * 1000); + + size = sizeof(hwSampleRate); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &hwSampleRate), "couldn't get hw sample rate"); + printf("Current Hardware Sample Rate: %.fHz\n", hwSampleRate); + + Float32 outputLatency; + size = sizeof(outputLatency); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputLatency, &size, &outputLatency), "couldn't get output latency"); + printf("Current Hardware Output Latency: %fms\n", outputLatency * 1000); + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + + // initialize the graphController object + [myViewController.graphController initializeAUGraph]; + + // set up the mixer according to our interface defaults + [myViewController setUIDefaults]; +} + +- (void)dealloc { + self.window = nil; + self.navigationController = nil; + self.myViewController = nil; + + [super dealloc]; +} + +@end diff --git a/iPhoneMixerEQGraphTest/Classes/MyViewController.h b/iPhoneMixerEQGraphTest/Classes/MyViewController.h new file mode 100755 index 0000000..0e706b4 --- /dev/null +++ b/iPhoneMixerEQGraphTest/Classes/MyViewController.h @@ -0,0 +1,108 @@ +/* + File: MyViewController.h +Abstract: The main view controller. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "AUGraphController.h" + +@interface MyViewController : UIViewController +{ + UIView *instructionsView; + UIView *eqView; + UIWebView *webView; + UIView *contentView; + + UIBarButtonItem *infoButtonItem; + UIBarButtonItem *eqButtonItem; + UIBarButtonItem *doneButtonItem; + + IBOutlet UIButton *startButton; + + UISwitch *bus0Switch; + UISlider *bus0VolumeSlider; + UISwitch *bus1Switch; + UISlider *bus1VolumeSlider; + UISlider *outputVolumeSlider; + UISwitch *eqSwitch; + + UInt8 selectedEQPresetIndex; + + AUGraphController *graphController; +} + +@property (readonly, nonatomic) IBOutlet UIView *instructionsView; +@property (readonly, nonatomic) IBOutlet UIView *eqView; +@property (readonly, nonatomic) IBOutlet UIWebView *webView; +@property (readonly, nonatomic) IBOutlet UIView *contentView; + +@property (nonatomic, retain) UIBarButtonItem *infoButtonItem; +@property (nonatomic, retain) UIBarButtonItem *eqButtonItem; +@property (nonatomic, retain) UIBarButtonItem *doneButtonItem; + +@property (readonly, nonatomic) IBOutlet UIButton *startButton; + +@property (readonly, nonatomic) IBOutlet UISwitch *bus0Switch; +@property (readonly, nonatomic) IBOutlet UISlider *bus0VolumeSlider; +@property (readonly, nonatomic) IBOutlet UISwitch *bus1Switch; +@property (readonly, nonatomic) IBOutlet UISlider *bus1VolumeSlider; +@property (readonly, nonatomic) IBOutlet UISlider *outputVolumeSlider; +@property (readonly, nonatomic) IBOutlet UISwitch *eqSwitch; + +@property (readonly, nonatomic) IBOutlet AUGraphController *graphController; + +- (void)setUIDefaults; +- (void)stopForInterruption; + +- (IBAction)enableInput:(UISwitch *)sender; +- (IBAction)setInputVolume:(UISlider *)sender; +- (IBAction)setOutputVolume:(UISlider *)sender; +- (IBAction)enableEQ:(UISwitch *)sender; + +- (IBAction)buttonPressedAction:(id)sender; + +@end \ No newline at end of file diff --git a/iPhoneMixerEQGraphTest/Classes/MyViewController.m b/iPhoneMixerEQGraphTest/Classes/MyViewController.m new file mode 100755 index 0000000..bce2855 --- /dev/null +++ b/iPhoneMixerEQGraphTest/Classes/MyViewController.m @@ -0,0 +1,320 @@ +/* + File: MyViewController.m +Abstract: The main view controller. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MyViewController.h" + +#define kTransitionDuration 0.75 + +@implementation MyViewController + +@synthesize instructionsView, eqView, webView, contentView, infoButtonItem, eqButtonItem, doneButtonItem, startButton, bus0Switch, bus0VolumeSlider, bus1Switch, bus1VolumeSlider, outputVolumeSlider, eqSwitch, graphController; + +#pragma mark- UIView + +- (void)viewDidLoad +{ + // load up the info text + NSString *infoSouceFile = [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]; + NSString *infoText = [NSString stringWithContentsOfFile:infoSouceFile encoding:NSUTF8StringEncoding error:nil]; + [self.webView loadHTMLString:infoText baseURL:nil]; + + // set up start button + UIImage *greenImage = [[UIImage imageNamed:@"green_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + UIImage *redImage = [[UIImage imageNamed:@"red_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + + [startButton setBackgroundImage:greenImage forState:UIControlStateNormal]; + [startButton setBackgroundImage:redImage forState:UIControlStateSelected]; + + // add the subview + [self.view addSubview:contentView]; + + // add our custom buttons as the nav bars custom views + UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; + [infoButton addTarget:self action:@selector(flipInfoAction:) forControlEvents:UIControlEventTouchUpInside]; + + UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; + [disclosureButton addTarget:self action:@selector(flipEQAction:) forControlEvents:UIControlEventTouchUpInside]; + + infoButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + self.navigationItem.leftBarButtonItem = infoButtonItem; + + eqButtonItem = [[UIBarButtonItem alloc] initWithCustomView:disclosureButton]; + self.navigationItem.rightBarButtonItem = nil; // eqButtonItem; + + // create our done button for the flipped views (used later) + doneButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:nil]; +} + +- (void)didReceiveMemoryWarning +{ + // invoke super's implementation to do the Right Thing. In practice this is unlikely to be used in this application, + // and it would be of little benefit, but the principle is the important thing. + [super didReceiveMemoryWarning]; +} + +- (void)dealloc +{ + [instructionsView release]; + [eqView release]; + [webView release]; + [contentView release]; + + self.infoButtonItem = nil; + self.eqButtonItem = nil; + self.doneButtonItem = nil; + + [startButton release]; + + [bus0Switch release]; + [bus0VolumeSlider release]; + [bus1Switch release]; + [bus1VolumeSlider release]; + [outputVolumeSlider release]; + [eqSwitch release]; + + [graphController release]; + + [super dealloc]; +} + +#pragma mark- + +// set the mixers values according to the UI state +- (void)setUIDefaults +{ + [graphController enableInput:0 isOn:bus0Switch.isOn]; + [graphController enableInput:1 isOn:bus1Switch.isOn]; + [graphController setInputVolume:0 value:bus0VolumeSlider.value]; + [graphController setInputVolume:1 value:bus1VolumeSlider.value]; + [graphController setOutputVolume:outputVolumeSlider.value]; + + bus0VolumeSlider.continuous = YES; + bus1VolumeSlider.continuous = YES; + outputVolumeSlider.continuous = YES; + + // the ipod eq has a list of presets, the first at index 0 is called "Disabled" + // and is selected by default when the EQ instance is created -- we don't need + // to specifically do anything since our default UI has the EQ turned off + // however we do want to pick the "Flat" preset when the EQ is initially enabled + // after that, it will represent what the user has selected from the list + selectedEQPresetIndex = 8; // index 8 is the "Flat" preset + + // set the picker view UI to represent the initial preset value + // this is offset by 1 since we don't display the 0th "Disabled" preset + UIPickerView *thePickerView = (UIPickerView*)[eqView viewWithTag:100]; + [thePickerView selectRow:(selectedEQPresetIndex - 1) inComponent:0 animated:NO]; +} + +// do the info button flip +- (void)flipInfoAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + + [UIView setAnimationTransition:([self.contentView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) + forView:self.view + cache:YES]; + + if ([self.instructionsView superview]) { + [self.instructionsView removeFromSuperview]; + [self.view addSubview:contentView]; + self.navigationItem.title = @"MixerEQGraph Test"; + } else { + [self.contentView removeFromSuperview]; + [self.view addSubview:instructionsView]; + self.navigationItem.title = @"Read Me eh?"; + } + + [UIView commitAnimations]; + + // adjust our done/info buttons accordingly + if ([instructionsView superview]) { + self.navigationItem.leftBarButtonItem = doneButtonItem; + self.navigationItem.rightBarButtonItem = nil; + } else { + self.navigationItem.leftBarButtonItem = infoButtonItem; + if (eqSwitch.isOn) { + self.navigationItem.rightBarButtonItem = eqButtonItem; + } + } + + doneButtonItem.action = @selector(flipInfoAction:); +} + +// do the eq button flip +- (void)flipEQAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + + [UIView setAnimationTransition:([self.contentView superview] ? UIViewAnimationTransitionFlipFromRight : UIViewAnimationTransitionFlipFromLeft) + forView:self.view + cache:YES]; + + if ([self.eqView superview]) { + [self.eqView removeFromSuperview]; + [self.view addSubview:contentView]; + self.navigationItem.title = @"MixerEQGraph Test"; + } else { + [self.contentView removeFromSuperview]; + [self.view addSubview:eqView]; + self.navigationItem.title = @"iPod Equalizer"; + } + + [UIView commitAnimations]; + + // adjust our done/eq buttons accordingly + if ([eqView superview]) { + self.navigationItem.leftBarButtonItem = nil; + self.navigationItem.rightBarButtonItem = doneButtonItem; + } else { + self.navigationItem.leftBarButtonItem = infoButtonItem; + self.navigationItem.rightBarButtonItem = eqButtonItem; + } + + doneButtonItem.action = @selector(flipEQAction:); +} + +// called if we've been interrupted and if we're playing, stop +- (void)stopForInterruption +{ + if (graphController.isPlaying) { + [graphController stopAUGraph]; + self.startButton.selected = NO; + } +} + +#pragma mark- Actions + +// handle input on/off switch action +- (IBAction)enableInput:(UISwitch *)sender +{ + UInt32 inputNum = [sender tag]; + AudioUnitParameterValue isOn = (AudioUnitParameterValue)sender.isOn; + + if (0 == inputNum) self.bus0VolumeSlider.enabled = isOn; + if (1 == inputNum) self.bus1VolumeSlider.enabled = isOn; + + [graphController enableInput:inputNum isOn:isOn]; +} + +// handle input volume changes +- (IBAction)setInputVolume:(UISlider *)sender +{ + UInt32 inputNum = [sender tag]; + AudioUnitParameterValue value = sender.value; + + [graphController setInputVolume:inputNum value:value]; +} + +// handle output volume changes +- (IBAction)setOutputVolume:(UISlider *)sender +{ + AudioUnitParameterValue value = sender.value; + + [graphController setOutputVolume:value]; +} + +// turns on/off the EQ by selecting the "Disabled" preset when off +// and whatever the user has selected when on +- (IBAction)enableEQ:(UISwitch *)sender +{ + if (sender.isOn) { + [graphController selectEQPreset:selectedEQPresetIndex]; + self.navigationItem.rightBarButtonItem = eqButtonItem; + } else { + [graphController selectEQPreset:0]; + self.navigationItem.rightBarButtonItem = nil; + } +} + +// handle the button press +- (IBAction)buttonPressedAction:(id)sender +{ + if (graphController.isPlaying) { + [graphController stopAUGraph]; + self.startButton.selected = NO; + } else { + [graphController startAUGraph]; + self.startButton.selected = YES; + } +} + +#pragma mark - UIPickerView + +// methods to implement the picker view +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView { + + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component { + + return (CFArrayGetCount(graphController.iPodEQPresetsArray) - 1); +} + +- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { + + AUPreset *currentPreset; + + currentPreset = (AUPreset *)CFArrayGetValueAtIndex(graphController.iPodEQPresetsArray, row + 1); + + return (NSString *)currentPreset->presetName; +} + +- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { + + selectedEQPresetIndex = row + 1; + + [graphController selectEQPreset:selectedEQPresetIndex]; +} + +@end \ No newline at end of file diff --git a/iPhoneMixerEQGraphTest/Info.plist b/iPhoneMixerEQGraphTest/Info.plist new file mode 100644 index 0000000..5da033d --- /dev/null +++ b/iPhoneMixerEQGraphTest/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.dts.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + eDTS + CFBundleVersion + 1.2 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/iPhoneMixerEQGraphTest/ReadMe.txt b/iPhoneMixerEQGraphTest/ReadMe.txt new file mode 100755 index 0000000..fe787f4 --- /dev/null +++ b/iPhoneMixerEQGraphTest/ReadMe.txt @@ -0,0 +1,82 @@ +iPhoneMixerEQGraphTest + +=========================================================================== +DESCRIPTION: + +iPhoneMixerEQGraphTest demonstrates how to build an Audio Unit Graph connecting a MultiChannel Mixer to the iPodEQ unit then to the RemoteIO unit. + +Two input busses are created each with input volume controls. An overall mixer output volume control is also provided and each bus may be enabled or disabled. + +The iPodEQ may be enabled or disabled and a preset EQ curve may be chosen via a picker in the iPod Equalizer view. iPhoneMixerEQGraphTest uses 44.1kHz source and sets the hardware sample rate to 44.1kHz to avoid any extraneous sample rate conversions. + +All the relevant code is in the file AUGraphController.mm while the supporting UI code is in MyViewController.m + +Touching the "Play Audio" button simply calls AUGraphStart while "Stop Audio" calls AUGraphStop. Changing AU volume is performed via AudioUnitSetParameter. + +The EQ presets are returned by using AudioUnitGetProperty asking for the kAudioUnitProperty_FactoryPresets CFArrayRef. A current preset is then selected calling AudioUnitSetProperty using the kAudioUnitProperty_PresentPreset property and passing in the appropriate AUPreset. Note that the AU Host owns the returned CFArray and should release it when done. + +Audio data is provided from two stereo audio files. The audio data is AAC compressed and ExtAudioFile is used to convert this data to the Core Audio Canonical uncompressed LPCM client format for input to the multichannel mixer. + +A lot of information about what's going on in the sample is dumped out to the console and can be used to understand how everything is being configured. Methods such as CAShow and the Print() method of the CAStreamBasicDescription helper class are invaluable if you're confused about how stream formats and the AUGraph are being configured. + +=========================================================================== +RELATED INFORMATION: + +Audio Session Programming Guide +Core Audio Overview +Audio Unit Processing Graph Services Reference +Output Audio Unit Services Reference +System Audio Unit Access Guide +Audio Component Services Reference +Audio File Services Reference + +AudioToolbox/AUGraph.h +AudioToolbox/ExtendedAudioFile.h + +=========================================================================== +SPECIAL CONSIDERATIONS: + +None + + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPHone OS 3.2 or later + + +=========================================================================== +PACKAGING LIST: + +MixerEQGraphTestDelegate.h +MixerEQGraphTestDelegate.m + +The MixerEQGraphTestDelegate class defines the application delegate object, responsible for adding the navigation +controllers view to the application window, setting up the Audio Session and so on. + +MyViewController.h +MyViewController.m + +The MyViewController class defines the controller object for the application. The object helps set up the user interface, +responds to and manages user interaction, and communicates with the AUGraphController. + +AUGraphController.h +AUGraphController.mm + +This file implements setting up the AUGraph, loading up the audio data using ExtAudioFile, the input render procedure and so on. All the code demonstrating interacting with Core Audio is in this one file, the rest of the sample can be thought of as a simple framework for the demonstration code in this file. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.2, Changed deployment target back to iPhone OS 3.2 and added CFBundleIconFiles in Info.plist. +Version 1.1, Upgraded project to build with the iOS 4 SDK. +Version 1.0, Tested with iPhone OS 3.1.3. First public release. + + +=========================================================================== +Copyright (C) 2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/iPhoneMixerEQGraphTest/Resources/Track1.mp4 b/iPhoneMixerEQGraphTest/Resources/Track1.mp4 new file mode 100644 index 0000000..4cadfdb Binary files /dev/null and b/iPhoneMixerEQGraphTest/Resources/Track1.mp4 differ diff --git a/iPhoneMixerEQGraphTest/Resources/Track2.mp4 b/iPhoneMixerEQGraphTest/Resources/Track2.mp4 new file mode 100644 index 0000000..6707fcc Binary files /dev/null and b/iPhoneMixerEQGraphTest/Resources/Track2.mp4 differ diff --git a/iPhoneMixerEQGraphTest/Resources/green_button.png b/iPhoneMixerEQGraphTest/Resources/green_button.png new file mode 100755 index 0000000..6c8b20e Binary files /dev/null and b/iPhoneMixerEQGraphTest/Resources/green_button.png differ diff --git a/iPhoneMixerEQGraphTest/Resources/info.html b/iPhoneMixerEQGraphTest/Resources/info.html new file mode 100644 index 0000000..9dc708a --- /dev/null +++ b/iPhoneMixerEQGraphTest/Resources/info.html @@ -0,0 +1,43 @@ + + +

+ +

This sample demonstrates the use of an AUGraph and related APIs as well as demonstrating how +to use the iPodEQ Audio Unit. All the relevant code is in the file AUGraphController.mm. +Touching the "Play Audio" button simply calls AUGraphStart starting the graph initialized by the +class, while "Stop Audio" will call AUGraphStop. Audio data from each file is provided to the +appropriate bus via the renderInput Render Procedure. Each of the two input busses may be enabled +or disabled and gain controls are provided for both inputs and the mixer output.

+ +

The iPodEQ can be enabled or disabled and a preset EQ curve may be chosen via a picker in +the iPod Equalizer view. The iPod EQ requires a sample rate of either 48kHz or 44.1kHz. +iPhoneMixerEQGraphTest uses 44.1kHz source and sets the hardware sample rate to 44.1kHz to +avoid any extraneous sample rate conversions.

+ +


+ +

Audio Unit Processing Graph Services provide interfaces for representing a set of +audio units, connections between their inputs and outputs, and callbacks used to provide +inputs. It also enables the embedding of sub (or child) processing graphs within parent +graphs to allow for a logical organization of parts of an overall signal chain.

+ +

An audio processing graph object (of type AUGraph) is a complete description of an +audio signal processing network. Audio Unit Processing Graph Services may manage the +instantiated audio units if the AUGraphOpen function is called.

+ +

An audio processing graph object may be introspected to get complete information +about all of the audio units in the graph. The various node objects (each of type AUNode) +in the graph, each representing an audio unit or a sub graph, may be added or removed, +and the interactions between them modified.

+ + +

A graph object’s state can be manipulated in both the rendering thread and in other +threads. Consequently, any activities that affect the state of the graph are guarded with +locks and a messaging model between any calling thread and the thread upon which the +graph object’s output unit is called (the render thread).

+ +

A graph object will have a single head node-an output unit. The output unit is used to +both start and stop the rendering operations of a graph, and is the dispatch point for +the safe manipulation of the state of the graph while it is running.

+
+
\ No newline at end of file diff --git a/iPhoneMixerEQGraphTest/Resources/moof.png b/iPhoneMixerEQGraphTest/Resources/moof.png new file mode 100644 index 0000000..5f28092 Binary files /dev/null and b/iPhoneMixerEQGraphTest/Resources/moof.png differ diff --git a/iPhoneMixerEQGraphTest/Resources/red_button.png b/iPhoneMixerEQGraphTest/Resources/red_button.png new file mode 100755 index 0000000..42de34e Binary files /dev/null and b/iPhoneMixerEQGraphTest/Resources/red_button.png differ diff --git a/iPhoneMixerEQGraphTest/en.lproj/MainWindow.xib b/iPhoneMixerEQGraphTest/en.lproj/MainWindow.xib new file mode 100644 index 0000000..9e02c0e --- /dev/null +++ b/iPhoneMixerEQGraphTest/en.lproj/MainWindow.xib @@ -0,0 +1,1235 @@ + + + + 784 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MCAwIDAAA + + NO + NO + YES + + + + + 256 + {0, 0} + NO + YES + YES + + + + + + 274 + {320, 436} + + 1 + MSAxIDEAA + + NO + + + MixerEQGraph Test + + + + + + + + 268 + + + + 268 + {{-2250, 100}, {42, 21}} + + NO + YES + NO + Label + + + 1 + 10 + + + + 292 + {{20, 20}, {280, 420}} + + + YES + YES + YES + + + {320, 460} + + 3 + MQA + + 2 + + + NO + + + + 292 + + + + 292 + {{59, 28}, {201, 40}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + NO + + + Stop Audio + Play Audio + + + + + 3 + MAA + + + + + 292 + {{59, 124}, {94, 27}} + + NO + YES + 0 + 0 + YES + + + + 292 + {{59, 95}, {80, 21}} + + NO + YES + NO + Input Bus 0 + + Arial-BoldMT + 14 + 16 + + + + 1 + 10 + + + + 292 + {{30, 188}, {264, 23}} + + NO + YES + 0 + 0 + 0.5 + NO + + + + 292 + {{166, 124}, {94, 27}} + + NO + YES + 1 + 0 + 0 + YES + + + + 292 + {{30, 247}, {264, 23}} + + NO + YES + 1 + 0 + 0 + 0.5 + NO + + + + 292 + {{28, 295}, {264, 23}} + + NO + YES + 0 + 0 + 1 + NO + + + + 292 + {{180, 95}, {80, 21}} + + NO + YES + NO + Input Bus 1 + + + + 1 + 10 + + + + 292 + {{105, 159}, {114, 21}} + + NO + YES + NO + Input Bus 0 Gain + + + + 1 + 10 + + + + 292 + {{139, 76}, {45, 21}} + + NO + YES + NO + MIXER + + + + 1 + 10 + + + + 292 + {{105, 218}, {114, 21}} + + NO + YES + NO + Input Bus 1 Gain + + + + 1 + 10 + + + + 292 + {{115, 353}, {94, 27}} + + NO + YES + 0 + 0 + + + + 292 + {{113, 325}, {98, 21}} + + NO + YES + NO + iPod Equalizer + + + + 1 + 10 + + + + 292 + {{117, 277}, {89, 21}} + + NO + YES + NO + Mixer Output + + + + 1 + 10 + + + {320, 460} + + NO + + + + 292 + + + + 268 + {{0, 200}, {320, 216}} + + + + 3 + MCAwAA + + NO + YES + YES + 100 + YES + + + + 292 + {{93, 163}, {134, 29}} + + + NO + YES + NO + Select A Preset + + Arial-BoldMT + 18 + 16 + + + + 1 + 10 + + + + 292 + {{69, 20}, {181, 135}} + + + NO + NO + 4 + NO + + + + + NSImage + moof.png + + + + {320, 416} + + + + 6 + System + alternateSelectedControlTextColor + + 3 + MQA + + + + + + + + + + delegate + + + + 4 + + + + instructionsView + + + + 26 + + + + contentView + + + + 27 + + + + webView + + + + 32 + + + + startButton + + + + 33 + + + + navigationController + + + + 45 + + + + myViewController + + + + 46 + + + + window + + + + 47 + + + + bus0Switch + + + + 48 + + + + bus0VolumeSlider + + + + 49 + + + + bus1Switch + + + + 50 + + + + bus1VolumeSlider + + + + 51 + + + + outputVolumeSlider + + + + 62 + + + + setOutputVolume: + + + 13 + + 67 + + + + setInputVolume: + + + 13 + + 68 + + + + setInputVolume: + + + 13 + + 69 + + + + enableInput: + + + 13 + + 75 + + + + enableInput: + + + 13 + + 76 + + + + eqView + + + + 79 + + + + dataSource + + + + 80 + + + + delegate + + + + 81 + + + + enableEQ: + + + 13 + + 95 + + + + eqSwitch + + + + 97 + + + + graphController + + + + 98 + + + + buttonPressedAction: + + + 7 + + 99 + + + + + + 0 + + + + + + 2 + + + + + + -1 + + + File's Owner + + + 3 + + + AppDelegate + + + -2 + + + + + 10 + + + + + + + + + 11 + + + + + + + + + 12 + + + + + 13 + + + + + 14 + + + + + + + InstructionsView + + + 18 + + + + + 19 + + + + + + + + + + + + + + + + + + + ContentView + + + 20 + + + + + 22 + + + + + + 30 + + + + + 37 + + + + + 38 + + + + + 39 + + + + + 41 + + + + + 43 + + + + + 58 + + + + + 61 + + + + + 77 + + + + + + + + EQView + + + 78 + + + + + 82 + + + + + 88 + + + + + 89 + + + + + 90 + + + + + 91 + + + + + 92 + + + + + 93 + + + + + 94 + + + + + 100 + + + + + + + UIApplication + UIResponder + {{581, 839}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{90, 964}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{884, 925}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + {{789, 283}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MixerEQGraphTestDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + AUGraphController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{685, 882}, {320, 416}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 100 + + + + + AUGraphController + NSObject + + IBProjectSource + Classes/AUGraphController.h + + + + MixerEQGraphTestDelegate + NSObject + + MyViewController + UINavigationController + UIWindow + + + IBProjectSource + Classes/MixerEQGraphTestDelegate.h + + + + MyViewController + UIViewController + + id + UISwitch + UISwitch + UISlider + UISlider + + + UISwitch + UISlider + UISwitch + UISlider + UIView + UISwitch + UIView + AUGraphController + UIView + UISlider + UIButton + UIWebView + + + IBProjectSource + Classes/MyViewController.h + + + + UIView + UIResponder + + IBUserSource + + + + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIPickerView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIPickerView.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISlider + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISlider.h + + + + UISwitch + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISwitch.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWebView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWebView.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + iPhoneMixerEQGraphTest.xcodeproj + 3 + 3.1 + + diff --git a/iPhoneMixerEQGraphTest/iPhoneMixerEQGraphTest.xcodeproj/project.pbxproj b/iPhoneMixerEQGraphTest/iPhoneMixerEQGraphTest.xcodeproj/project.pbxproj new file mode 100755 index 0000000..2db829f --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPhoneMixerEQGraphTest.xcodeproj/project.pbxproj @@ -0,0 +1,366 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 180E66C611D5033600E800D1 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 180E66BF11D5033600E800D1 /* Icon-72.png */; }; + 180E66C711D5033600E800D1 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 180E66C011D5033600E800D1 /* Icon-Small-50.png */; }; + 180E66C811D5033600E800D1 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 180E66C111D5033600E800D1 /* Icon-Small.png */; }; + 180E66C911D5033600E800D1 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 180E66C211D5033600E800D1 /* Icon-Small@2x.png */; }; + 180E66CA11D5033600E800D1 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 180E66C311D5033600E800D1 /* Icon.png */; }; + 180E66CB11D5033600E800D1 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 180E66C411D5033600E800D1 /* Icon@2x.png */; }; + 180E66CC11D5033600E800D1 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 180E66C511D5033600E800D1 /* iTunesArtwork */; }; + 185ABC3111CBCAED003FD6E3 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 185ABC2F11CBCAED003FD6E3 /* MainWindow.xib */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2B0208D5111FCBB6002BB86D /* CAComponentDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B0208D4111FCBB6002BB86D /* CAComponentDescription.cpp */; }; + 2B1D98D51123637700E1AB0A /* moof.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B1D98D41123637600E1AB0A /* moof.png */; }; + 2B222C2C1120F73E002716C2 /* AUGraphController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2B222C291120F73E002716C2 /* AUGraphController.mm */; }; + 2B222C2D1120F73E002716C2 /* MixerEQGraphTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B222C2B1120F73E002716C2 /* MixerEQGraphTestDelegate.m */; }; + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C70F5383D30033DE8C /* AVFoundation.framework */; }; + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */; }; + 2B9A681111179D890050C8C6 /* Track1.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 2B9A680F11179D890050C8C6 /* Track1.mp4 */; }; + 2B9A681211179D890050C8C6 /* Track2.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 2B9A681011179D890050C8C6 /* Track2.mp4 */; }; + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */; }; + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1C0F59F67E00D63998 /* green_button.png */; }; + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1D0F59F67E00D63998 /* red_button.png */; }; + 2BE30B230F59F67E00D63998 /* info.html in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1F0F59F67E00D63998 /* info.html */; }; + 2BF8389A1047021B000A5DCC /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF838981047021B000A5DCC /* CAXException.cpp */; }; + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 180E66BF11D5033600E800D1 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 180E66C011D5033600E800D1 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 180E66C111D5033600E800D1 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 180E66C211D5033600E800D1 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 180E66C311D5033600E800D1 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 180E66C411D5033600E800D1 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 180E66C511D5033600E800D1 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 185ABC3011CBCAED003FD6E3 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* MixEQGraphTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MixEQGraphTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B0208D3111FCBB1002BB86D /* CAComponentDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAComponentDescription.h; sourceTree = ""; }; + 2B0208D4111FCBB6002BB86D /* CAComponentDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAComponentDescription.cpp; sourceTree = ""; }; + 2B1D98D41123637600E1AB0A /* moof.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = moof.png; path = Resources/moof.png; sourceTree = ""; }; + 2B222C281120F73E002716C2 /* AUGraphController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AUGraphController.h; path = Classes/AUGraphController.h; sourceTree = ""; }; + 2B222C291120F73E002716C2 /* AUGraphController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AUGraphController.mm; path = Classes/AUGraphController.mm; sourceTree = ""; }; + 2B222C2A1120F73E002716C2 /* MixerEQGraphTestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixerEQGraphTestDelegate.h; sourceTree = ""; }; + 2B222C2B1120F73E002716C2 /* MixerEQGraphTestDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MixerEQGraphTestDelegate.m; sourceTree = ""; }; + 2B222C411120F819002716C2 /* iPhoneMixerEQGraphTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneMixerEQGraphTest_Prefix.pch; sourceTree = ""; }; + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2B9A680F11179D890050C8C6 /* Track1.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; name = Track1.mp4; path = Resources/Track1.mp4; sourceTree = ""; }; + 2B9A681011179D890050C8C6 /* Track2.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; name = Track2.mp4; path = Resources/Track2.mp4; sourceTree = ""; }; + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = ""; }; + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = ""; }; + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + 2BE30B1C0F59F67E00D63998 /* green_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = green_button.png; path = Resources/green_button.png; sourceTree = ""; }; + 2BE30B1D0F59F67E00D63998 /* red_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = red_button.png; path = Resources/red_button.png; sourceTree = ""; }; + 2BE30B1F0F59F67E00D63998 /* info.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = info.html; path = Resources/info.html; sourceTree = ""; }; + 2BF838981047021B000A5DCC /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = ""; }; + 2BF838991047021B000A5DCC /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = ""; }; + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */, + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Other Classes */ = { + isa = PBXGroup; + children = ( + 2B222C2A1120F73E002716C2 /* MixerEQGraphTestDelegate.h */, + 2B222C2B1120F73E002716C2 /* MixerEQGraphTestDelegate.m */, + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */, + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */, + ); + name = "Other Classes"; + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MixEQGraphTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */, + 2B222C281120F73E002716C2 /* AUGraphController.h */, + 2B222C291120F73E002716C2 /* AUGraphController.mm */, + 080E96DDFE201D6D7F000001 /* Other Classes */, + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 2B222C411120F819002716C2 /* iPhoneMixerEQGraphTest_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 180E66BF11D5033600E800D1 /* Icon-72.png */, + 180E66C011D5033600E800D1 /* Icon-Small-50.png */, + 180E66C111D5033600E800D1 /* Icon-Small.png */, + 180E66C211D5033600E800D1 /* Icon-Small@2x.png */, + 180E66C311D5033600E800D1 /* Icon.png */, + 180E66C411D5033600E800D1 /* Icon@2x.png */, + 180E66C511D5033600E800D1 /* iTunesArtwork */, + 185ABC2F11CBCAED003FD6E3 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 2B1D98D41123637600E1AB0A /* moof.png */, + 2BE30B1C0F59F67E00D63998 /* green_button.png */, + 2BE30B1D0F59F67E00D63998 /* red_button.png */, + 2BE30B1F0F59F67E00D63998 /* info.html */, + 2B9A680F11179D890050C8C6 /* Track1.mp4 */, + 2B9A681011179D890050C8C6 /* Track2.mp4 */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */, + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */ = { + isa = PBXGroup; + children = ( + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */, + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */, + 2BF838991047021B000A5DCC /* CAXException.h */, + 2BF838981047021B000A5DCC /* CAXException.cpp */, + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */, + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */, + 2B0208D3111FCBB1002BB86D /* CAComponentDescription.h */, + 2B0208D4111FCBB6002BB86D /* CAComponentDescription.cpp */, + ); + path = iPublicUtility; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MixEQGraphTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MixEQGraphTest" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MixEQGraphTest; + productName = AQOffilineRenderTest; + productReference = 1D6058910D05DD3D006BFB54 /* MixEQGraphTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneMixerEQGraphTest" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MixEQGraphTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */, + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */, + 2BE30B230F59F67E00D63998 /* info.html in Resources */, + 2B9A681111179D890050C8C6 /* Track1.mp4 in Resources */, + 2B9A681211179D890050C8C6 /* Track2.mp4 in Resources */, + 2B1D98D51123637700E1AB0A /* moof.png in Resources */, + 185ABC3111CBCAED003FD6E3 /* MainWindow.xib in Resources */, + 180E66C611D5033600E800D1 /* Icon-72.png in Resources */, + 180E66C711D5033600E800D1 /* Icon-Small-50.png in Resources */, + 180E66C811D5033600E800D1 /* Icon-Small.png in Resources */, + 180E66C911D5033600E800D1 /* Icon-Small@2x.png in Resources */, + 180E66CA11D5033600E800D1 /* Icon.png in Resources */, + 180E66CB11D5033600E800D1 /* Icon@2x.png in Resources */, + 180E66CC11D5033600E800D1 /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */, + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */, + 2BF8389A1047021B000A5DCC /* CAXException.cpp in Sources */, + 2B0208D5111FCBB6002BB86D /* CAComponentDescription.cpp in Sources */, + 2B222C2C1120F73E002716C2 /* AUGraphController.mm in Sources */, + 2B222C2D1120F73E002716C2 /* MixerEQGraphTestDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 185ABC2F11CBCAED003FD6E3 /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 185ABC3011CBCAED003FD6E3 /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneMixerEQGraphTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PRODUCT_NAME = MixEQGraphTest; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneMixerEQGraphTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PRODUCT_NAME = MixEQGraphTest; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MixEQGraphTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneMixerEQGraphTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/iPhoneMixerEQGraphTest/iPhoneMixerEQGraphTest_Prefix.pch b/iPhoneMixerEQGraphTest/iPhoneMixerEQGraphTest_Prefix.pch new file mode 100644 index 0000000..a17209c --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPhoneMixerEQGraphTest_Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAComponentDescription.cpp b/iPhoneMixerEQGraphTest/iPublicUtility/CAComponentDescription.cpp new file mode 100644 index 0000000..11531ae --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAComponentDescription.cpp @@ -0,0 +1,111 @@ +/* + File: CAComponentDescription.cpp + Abstract: Core Audio component class. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include "CAComponentDescription.h" +#include "CAStreamBasicDescription.h" +#include + +void CAShowComponentDescription(const AudioComponentDescription *desc) +{ + CAComponentDescription::_CAShowComponentDescription (desc, stdout); +} + +void CAComponentDescription::_CAShowComponentDescription(const AudioComponentDescription *desc, FILE* file) +{ + if (desc) + { + char str[24]; + fprintf (file, "AudioComponentDescription: %s - ", CAStringForOSType(desc->componentType, str)); + fprintf (file, "%s - ", CAStringForOSType(desc->componentSubType, str)); + fprintf (file, "%s", CAStringForOSType(desc->componentManufacturer, str)); + fprintf (file, ", 0x%X, 0x%X\n", (int)desc->componentFlags, (int)desc->componentFlagsMask); + } +} + +CAComponentDescription::CAComponentDescription (OSType inType, OSType inSubtype, OSType inManu) +{ + componentType = inType; + componentSubType = inSubtype; + componentManufacturer = inManu; + componentFlags = 0; + componentFlagsMask = 0; +} + +bool CAComponentDescription::IsAU () const +{ + bool flag = IsEffect() || IsMusicDevice() || IsOffline(); + if (flag) return true; + + switch (componentType) { + case kAudioUnitType_Output: + case kAudioUnitType_FormatConverter: + case kAudioUnitType_Mixer: + return true; + } + return false; +} + +inline bool _MatchTest (const OSType &inTypeA, const OSType &inTypeB) +{ + return ((inTypeA == inTypeB) || (!inTypeA && !inTypeB) || (inTypeA && !inTypeB) || (!inTypeA && inTypeB)); +} + +bool CAComponentDescription::Matches (const AudioComponentDescription &desc) const +{ + bool matches = false; + + // see if the type matches + matches = _MatchTest (componentType, desc.componentType); + + if (matches) + matches = _MatchTest (componentSubType, desc.componentSubType); + + if (matches) + matches = _MatchTest (componentManufacturer, desc.componentManufacturer); + + return matches; +} diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAComponentDescription.h b/iPhoneMixerEQGraphTest/iPublicUtility/CAComponentDescription.h new file mode 100644 index 0000000..f60b67e --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAComponentDescription.h @@ -0,0 +1,141 @@ +/* + File: CAComponentDescription.h + Abstract: Core Audio component class. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAComponentDescription_h__ +#define __CAComponentDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif + +#include +#include + +void CAShowComponentDescription(const AudioComponentDescription *desc); + +// ____________________________________________________________________________ +// +// CAComponentDescription +class CAComponentDescription : public AudioComponentDescription { +public: + CAComponentDescription() { memset (this, 0, sizeof (AudioComponentDescription)); } + + CAComponentDescription (OSType inType, OSType inSubtype = 0, OSType inManu = 0); + + CAComponentDescription(const AudioComponentDescription& desc) { memcpy (this, &desc, sizeof (AudioComponentDescription)); } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsAU () const; + + bool IsAUFX() const { return componentType == kAudioUnitType_Effect; } + bool IsAUFM() const { return componentType == kAudioUnitType_MusicEffect; } + + bool IsEffect () const { return IsAUFX() || IsAUFM() || IsPanner(); } + + bool IsOffline () const { return componentType == 'auol'; } + + bool IsFConv () const { return componentType == kAudioUnitType_FormatConverter; } + + bool IsPanner () const { return componentType == kAudioUnitType_Panner; } + + bool IsMusicDevice () const { return componentType == kAudioUnitType_MusicDevice; } + +#ifndef MAC_OS_X_VERSION_10_4 + bool IsGenerator () const { return componentType =='augn'; } +#else + bool IsGenerator () const { return componentType ==kAudioUnitType_Generator; } +#endif + + bool IsOutput () const { return componentType == kAudioUnitType_Output; } + + bool IsSource () const { return IsMusicDevice() || IsGenerator(); } + + OSType Type () const { return componentType; } + OSType SubType () const { return componentSubType; } + OSType Manu () const { return componentManufacturer; } + + int Count() const { return AudioComponentCount(const_cast(this)); } + + // does a semantic match where "wild card" values for type, subtype, manu will match + bool Matches (const AudioComponentDescription &desc) const; + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + void Print(FILE* file = stdout) const { _CAShowComponentDescription (this, file); } + + OSStatus Save (CFPropertyListRef *outData) const; + OSStatus Restore (CFPropertyListRef &inData); + +private: + static void _CAShowComponentDescription (const AudioComponentDescription *desc, FILE* file); + friend void CAShowComponentDescription (const AudioComponentDescription *desc); +}; + +inline bool operator< (const AudioComponentDescription& x, const AudioComponentDescription& y) +{ + return memcmp (&x, &y, offsetof (AudioComponentDescription, componentFlags)) < 0; +} + +inline bool operator== (const AudioComponentDescription& x, const AudioComponentDescription& y) +{ + return !memcmp (&x, &y, offsetof (AudioComponentDescription, componentFlags)); +} + +inline bool operator!= (const AudioComponentDescription& x, const AudioComponentDescription& y) +{ + return !(x == y); +} + +#endif diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CADebugMacros.h b/iPhoneMixerEQGraphTest/iPublicUtility/CADebugMacros.h new file mode 100644 index 0000000..d3aec32 --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CADebugMacros.h @@ -0,0 +1,455 @@ +/* + File: CADebugMacros.h + Abstract: Handy debug macros for Core Audio. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#if !defined(__CADebugMacros_h__) +#define __CADebugMacros_h__ + +//============================================================================= +// Includes +//============================================================================= + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CADebugMacros +//============================================================================= + +//#define CoreAudio_StopOnFailure 1 +//#define CoreAudio_TimeStampMessages 1 +//#define CoreAudio_ThreadStampMessages 1 +//#define CoreAudio_FlushDebugMessages 1 + +#if TARGET_RT_BIG_ENDIAN + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } +#else + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } +#endif + +// This is a macro that does a sizeof and casts the result to a UInt32. This is useful for all the +// places where -wshorten64-32 catches assigning a sizeof expression to a UInt32. +// For want of a better place to park this, we'll park it here. +#define SizeOf32(X) ((UInt32)sizeof(X)) + +// This is a macro that does a offsetof and casts the result to a UInt32. This is useful for all the +// places where -wshorten64-32 catches assigning an offsetof expression to a UInt32. +// For want of a better place to park this, we'll park it here. +#define OffsetOf32(X, Y) ((UInt32)offsetof(X, Y)) + +// This macro casts the expression to a UInt32. It is called out specially to allow us to track casts +// that have been added purely to avert -wshorten64-32 warnings on 64 bit platforms. +// For want of a better place to park this, we'll park it here. +#define ToUInt32(X) ((UInt32)(X)) + +#pragma mark Basic Definitions + +#if DEBUG || CoreAudio_Debug + + // can be used to break into debugger immediately, also see CADebugger + #define BusError() (*(long *)0 = 0) + + // basic debugging print routines + #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON + extern void DebugStr(const unsigned char* debuggerMsg); + #define DebugMessage(msg) DebugStr("\p"msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #else + #include "CADebugPrintf.h" + + #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) + #define FlushRtn ,fflush(DebugPrintfFile) + #else + #define FlushRtn + #endif + + #if CoreAudio_ThreadStampMessages + #include + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #elif CoreAudio_TimeStampMessages + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%.4f: %s"DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #else + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%s"DebugPrintfLineEnding, msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #endif + #endif + void DebugPrint(const char *fmt, ...); // can be used like printf + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) + #endif + #if VERBOSE + #define vprint(msg) DEBUGPRINT(msg) + #else + #define vprint(msg) + #endif + + #if CoreAudio_StopOnFailure + #include "CADebugger.h" + #define STOP CADebuggerStop() + #else + #define STOP + #endif + +#else + #define DebugMessage(msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #define DebugMessageN4(msg, N1, N2, N3, N4) + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) + #endif + #define vprint(msg) + #define STOP +#endif + +void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) +void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) + +#if DEBUG || CoreAudio_Debug + +#pragma mark Debug Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + { \ + unsigned int __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + unsigned int __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + DebugMessage(inMethodName": Subclasses must implement this method"); \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#else + +#pragma mark Release Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + if((inKernelError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + if((inError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + unsigned int __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#endif // DEBUG || CoreAudio_Debug + +#endif diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAMath.h b/iPhoneMixerEQGraphTest/iPublicUtility/CAMath.h new file mode 100644 index 0000000..88fd5e0 --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAMath.h @@ -0,0 +1,69 @@ +/* + File: CAMath.h + Abstract: Various math macro functions. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAMath_h__ +#define __CAMath_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +inline bool fiszero(Float64 f) { return (f == 0.); } +inline bool fiszero(Float32 f) { return (f == 0.f); } + +inline bool fnonzero(Float64 f) { return !fiszero(f); } +inline bool fnonzero(Float32 f) { return !fiszero(f); } + +inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } +inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } + +inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } +inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } + +#endif // __CAMath_h__ diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAStreamBasicDescription.cpp b/iPhoneMixerEQGraphTest/iPublicUtility/CAStreamBasicDescription.cpp new file mode 100644 index 0000000..131f25d --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,580 @@ +/* + File: CAStreamBasicDescription.cpp + Abstract: Wrapper class for the AudioStreamBasicDescription struct. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include "CAStreamBasicDescription.h" +#include "CAMath.h" + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it + +char *CAStringForOSType (OSType t, char *writeLocation) +{ + char *p = writeLocation; + unsigned char str[4], *q = str; + *(UInt32 *)str = CFSwapInt32HostToBig(t); + + bool hasNonPrint = false; + for (int i = 0; i < 4; ++i) { + if (!(isprint(*q) && *q != '\\')) { + hasNonPrint = true; + break; + } + } + + if (hasNonPrint) + p += sprintf (p, "0x"); + else + *p++ = '\''; + + for (int i = 0; i < 4; ++i) { + if (hasNonPrint) { + p += sprintf(p, "%02X", *q++); + } else { + *p++ = *q++; + } + } + if (!hasNonPrint) + *p++ = '\''; + *p = '\0'; + return writeLocation; +} + + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; + mReserved = 0; +} + +char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize) const +{ + int bufsize = (int)_bufsize; // must be signed to protect against overflow + char *theBuffer = buf; + int nc; + char formatID[24]; + CAStringForOSType (mFormatID, formatID); + nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); + buf += nc; if ((bufsize -= nc) <= 0) goto exit; + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (wordSize > 0 && PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize); + else + snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + char bitdepth[20]; + + int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; + if (fracbits > 0) + snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); + else + snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel); + + nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s", + bitdepth, endian, sign, floatInt, + commaSpace, packed, align, deinter); + // buf += nc; if ((bufsize -= nc) <= 0) goto exit; + } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless + int sourceBits = 0; + switch (mFormatFlags) + { + case 1: // kAppleLosslessFormatFlag_16BitSourceData + sourceBits = 16; + break; + case 2: // kAppleLosslessFormatFlag_20BitSourceData + sourceBits = 20; + break; + case 3: // kAppleLosslessFormatFlag_24BitSourceData + sourceBits = 24; + break; + case 4: // kAppleLosslessFormatFlag_32BitSourceData + sourceBits = 32; + break; + } + if (sourceBits) + nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits); + else + nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, "); + buf += nc; if ((bufsize -= nc) <= 0) goto exit; + nc = snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket); + // buf += nc; if ((bufsize -= nc) <= 0) goto exit; + } + else + nc = snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", + (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); +exit: + return theBuffer; +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format + if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) + { + // the canonical linear PCM format + ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; + ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType); + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(fiszero(ioDescription.mSampleRate)) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + const char* theMixabilityString = NULL; + if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) + { + theMixabilityString = "Mixable"; + } + else + { + theMixabilityString = "Unmixable"; + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + snprintf(outName, inMaxNameLength, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + snprintf(outName, inMaxNameLength, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + if(thePackingString != NULL) + { + snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strlcpy(outName, "AC-3", sizeof(outName)); + break; + + case kAudioFormat60958AC3: + strlcpy(outName, "AC-3 for SPDIF", sizeof(outName)); + break; + + default: + CACopy4CCToCString(outName, inDescription.mFormatID); + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + + // mixable is always better than non-mixable for linear PCM and should be the second order sort item + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) + { + theAnswer = true; + isDone = true; + } + else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) + { + theAnswer = false; + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) + { + if(fnotequal(x.mSampleRate, y.mSampleRate)) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + + // if the number of channels is 0 or 1, we don't care about non-interleavedness + if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) { + xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const +{ + if (interpretingWildcards) + return *this == other; + return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0.) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024) + && (x.mFormatID != 0) + && !(x.mFormatID == kAudioFormatLinearPCM && (x.mFramesPerPacket != 1 || x.mBytesPerPacket != x.mBytesPerFrame)); +} diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAStreamBasicDescription.h b/iPhoneMixerEQGraphTest/iPublicUtility/CAStreamBasicDescription.h new file mode 100644 index 0000000..e744649 --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,304 @@ +/* + File: CAStreamBasicDescription.h + Abstract: Wrapper class for the AudioStreamBasicDescription struct. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CoreFoundation.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it + +extern char *CAStringForOSType (OSType t, char *writeLocation); + +// define Leopard specific symbols for backward compatibility if applicable +#if COREAUDIOTYPES_VERSION < 1050 +typedef Float32 AudioSampleType; +enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; +#endif +#if COREAUDIOTYPES_VERSION < 1051 +typedef Float32 AudioUnitSampleType; +enum { + kLinearPCMFormatFlagsSampleFractionShift = 7, + kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift), +}; +#endif + +// define the IsMixable format flag for all versions of the system +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; +#else + enum { kIsNonMixableFlag = (1L << 6) }; +#endif + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + bool IsNativeEndian() const + { + return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian; + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { + return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; + } + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; + int sampleSize = SizeOf32(AudioSampleType); + mFormatFlags = kAudioFormatFlagsCanonical; + mBitsPerChannel = 8 * sampleSize; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; + else { + mBytesPerPacket = mBytesPerFrame = sampleSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + bool IsCanonical() const + { + if (mFormatID != kAudioFormatLinearPCM) return false; + UInt32 reqFormatFlags; + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); + bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; + unsigned sampleSize = SizeOf32(AudioSampleType); + reqFormatFlags = kAudioFormatFlagsCanonical; + UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; + + return ((mFormatFlags & flagsMask) == reqFormatFlags + && mBitsPerChannel == 8 * sampleSize + && mFramesPerPacket == 1 + && mBytesPerFrame == reqFrameSize + && mBytesPerPacket == reqFrameSize); + } + + void SetAUCanonical(UInt32 nChannels, bool interleaved) + { + mFormatID = kAudioFormatLinearPCM; +#if CA_PREFER_FIXED_POINT + mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); +#else + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType); + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType); + else { + mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + if (wordSize == 0) + wordSize = (mBitsPerChannel + 7) / 8; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; + + void Print() const { + Print (stdout); + } + + void Print(FILE* file) const { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const { + char buf[256]; + fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); + } + + void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline + char buf[256]; + fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); + } + + char * AsString(char *buf, size_t bufsize) const; + + static void Print (const AudioStreamBasicDescription &inDesc) + { + CAStreamBasicDescription desc(inDesc); + desc.Print (); + } + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__ diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAXException.cpp b/iPhoneMixerEQGraphTest/iPublicUtility/CAXException.cpp new file mode 100644 index 0000000..38d725a --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAXException.cpp @@ -0,0 +1,50 @@ +/* + File: CAXException.cpp + Abstract: An extended exception class that includes the name of the failed operation. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#include "CAXException.h" + +CAXException::WarningHandler CAXException::sWarningHandler = NULL; diff --git a/iPhoneMixerEQGraphTest/iPublicUtility/CAXException.h b/iPhoneMixerEQGraphTest/iPublicUtility/CAXException.h new file mode 100644 index 0000000..4439eba --- /dev/null +++ b/iPhoneMixerEQGraphTest/iPublicUtility/CAXException.h @@ -0,0 +1,337 @@ +/* + File: CAXException.h + Abstract: An extended exception class that includes the name of the failed operation. + Version: 1.2 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#ifndef __CAXException_h__ +#define __CAXException_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif +#include "CADebugMacros.h" +#include +//#include +#include + + +class CAX4CCString { +public: + CAX4CCString(OSStatus error) { + // see if it appears to be a 4-char-code + char *str = mStr; + *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); + if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { + str[0] = str[5] = '\''; + str[6] = '\0'; + } else if (error > -200000 && error < 200000) + // no, format it as an integer + sprintf(str, "%d", (int)error); + else + sprintf(str, "0x%x", (int)error); + } + const char *get() const { return mStr; } + operator const char *() const { return mStr; } +private: + char mStr[16]; +}; + +// An extended exception class that includes the name of the failed operation +class CAXException { +public: + CAXException(const char *operation, OSStatus err) : + mError(err) + { + if (operation == NULL) + mOperation[0] = '\0'; + else if (strlen(operation) >= sizeof(mOperation)) { + memcpy(mOperation, operation, sizeof(mOperation) - 1); + mOperation[sizeof(mOperation) - 1] = '\0'; + } else + + strlcpy(mOperation, operation, sizeof(mOperation)); + } + + char *FormatError(char *str) const + { + return FormatError(str, mError); + } + + char mOperation[256]; + const OSStatus mError; + + // ------------------------------------------------- + + typedef void (*WarningHandler)(const char *msg, OSStatus err); + + static char *FormatError(char *str, OSStatus error) + { + strcpy(str, CAX4CCString(error)); + return str; + } + + static void Warning(const char *s, OSStatus error) + { + if (sWarningHandler) + (*sWarningHandler)(s, error); + } + + static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } +private: + static WarningHandler sWarningHandler; +}; + +#if DEBUG || CoreAudio_Debug + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + DebugMessageN2("about to throw %s: %s", CAX4CCString(__err).get(), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + DebugMessageN2("about to throw %s: %s", CAX4CCString(__err).get(), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + DebugMessageN2("about to throw %s: %s", CAX4CCString(__err).get(), #error);\ + STOP; \ + goto label; \ + } \ + } while (0) + + #define XAssert(assertion) \ + do { \ + if (!(assertion)) { \ + DebugMessageN1("error: failed assertion: %s", #assertion); \ + STOP; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + DebugMessageN2("error %s: %s", CAX4CCString(__err).get(), #error);\ + STOP; \ + } \ + } while (0) + + #define ca_require_noerr(errorCode, exceptionLabel) \ + do \ + { \ + int evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d", \ + #errorCode, evalOnceErrorCode, \ + #exceptionLabel, \ + __FILE__, \ + __LINE__); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + + #define ca_verify_noerr(errorCode) \ + do \ + { \ + int evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d", \ + #errorCode, evalOnceErrorCode, \ + __FILE__, \ + __LINE__); \ + } \ + } while ( 0 ) + + #define ca_debug_string(message) \ + do \ + { \ + DebugMessageN3("ca_debug_string: %s %s:%d", \ + message, \ + __FILE__, \ + __LINE__); \ + } while ( 0 ) + + + #define ca_verify(assertion) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DebugMessageN3("ca_verify: %s %s:%d", \ + #assertion, \ + __FILE__, \ + __LINE__); \ + } \ + } while ( 0 ) + + #define ca_require(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DebugMessageN4("ca_require: %s %s %s:%d", \ + #assertion, \ + #exceptionLabel, \ + __FILE__, \ + __LINE__); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + + #define ca_check(assertion) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DebugMessageN3("ca_check: %s %s:%d", \ + #assertion, \ + __FILE__, \ + __LINE__); \ + } \ + } while ( 0 ) + +#else + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + goto label; \ + } \ + } while (0) + + #define XAssert(assertion) \ + do { \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + /*OSStatus __err =*/ error; \ + } while (0) + + #define ca_require_noerr(errorCode, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + + #define ca_verify_noerr(errorCode) \ + do \ + { \ + if ( 0 != (errorCode) ) \ + { \ + } \ + } while ( 0 ) + + #define ca_debug_string(message) + + #define ca_verify(assertion) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + } \ + } while ( 0 ) + + #define ca_require(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + + #define ca_check(assertion) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + } \ + } while ( 0 ) + + +#endif + +#define XThrow(error, operation) XThrowIf(true, error, operation) +#define XThrowIfErr(error) XThrowIfError(error, #error) + +#endif // __CAXException_h__ diff --git a/iPhoneMixerEQGraphTest/images/Icon-72.png b/iPhoneMixerEQGraphTest/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/Icon-72.png differ diff --git a/iPhoneMixerEQGraphTest/images/Icon-Small-50.png b/iPhoneMixerEQGraphTest/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/Icon-Small-50.png differ diff --git a/iPhoneMixerEQGraphTest/images/Icon-Small.png b/iPhoneMixerEQGraphTest/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/Icon-Small.png differ diff --git a/iPhoneMixerEQGraphTest/images/Icon-Small@2x.png b/iPhoneMixerEQGraphTest/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/Icon-Small@2x.png differ diff --git a/iPhoneMixerEQGraphTest/images/Icon.png b/iPhoneMixerEQGraphTest/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/Icon.png differ diff --git a/iPhoneMixerEQGraphTest/images/Icon@2x.png b/iPhoneMixerEQGraphTest/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/Icon@2x.png differ diff --git a/iPhoneMixerEQGraphTest/images/iTunesArtwork b/iPhoneMixerEQGraphTest/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/iPhoneMixerEQGraphTest/images/iTunesArtwork differ diff --git a/iPhoneMixerEQGraphTest/main.m b/iPhoneMixerEQGraphTest/main.m new file mode 100644 index 0000000..391b30e --- /dev/null +++ b/iPhoneMixerEQGraphTest/main.m @@ -0,0 +1,56 @@ +/* + File: main.m +Abstract: The application main. + Version: 1.2 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/iPhoneMultichannelMixerTest.zip b/iPhoneMultichannelMixerTest.zip new file mode 100644 index 0000000..c77186f Binary files /dev/null and b/iPhoneMultichannelMixerTest.zip differ diff --git a/iPhoneMultichannelMixerTest/Classes/MultichannelMixerController.h b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerController.h new file mode 100755 index 0000000..c56197e --- /dev/null +++ b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerController.h @@ -0,0 +1,86 @@ +/* + File: MultichannelMixerController.h + Abstract: The Controller Class for the AUGraph. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "CAStreamBasicDescription.h" + +#define MAXBUFS 2 +#define NUMFILES 2 + +typedef struct { + AudioStreamBasicDescription asbd; + AudioUnitSampleType *data; + UInt32 numFrames; + UInt32 sampleNum; +} SoundBuffer, *SoundBufferPtr; + +@interface MultichannelMixerController : NSObject +{ + CFURLRef sourceURL[2]; + + AUGraph mGraph; + AudioUnit mMixer; + + SoundBuffer mSoundBuffer[MAXBUFS]; + + Boolean isPlaying; +} + +@property (readonly, nonatomic) Boolean isPlaying; + +- (void)initializeAUGraph; + +- (void)enableInput:(UInt32)inputNum isOn:(AudioUnitParameterValue)isONValue; +- (void)setInputVolume:(UInt32)inputNum value:(AudioUnitParameterValue)value; +- (void)setOutputVolume:(AudioUnitParameterValue)value; + +- (void)startAUGraph; +- (void)stopAUGraph; + +@end diff --git a/iPhoneMultichannelMixerTest/Classes/MultichannelMixerController.mm b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerController.mm new file mode 100755 index 0000000..41aa8c9 --- /dev/null +++ b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerController.mm @@ -0,0 +1,383 @@ +/* + File: MultichannelMixerController.mm + Abstract: The Controller Class for the AUGraph. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MultiChannelMixerController.h" + +const Float64 kGraphSampleRate = 44100.0; + +#pragma mark- AUComponentDescription + +// a simple wrapper for AudioComponentDescription +class AUComponentDescription : public AudioComponentDescription +{ +public: + AUComponentDescription() + { + componentType = 0; + componentSubType = 0; + componentManufacturer = 0; + componentFlags = 0; + componentFlagsMask = 0; + }; + + + AUComponentDescription(OSType inType, + OSType inSubType, + OSType inManufacturer = 0, + unsigned long inFlags = 0, + unsigned long inFlagsMask = 0 ) + { + componentType = inType; + componentSubType = inSubType; + componentManufacturer = inManufacturer; + componentFlags = inFlags; + componentFlagsMask = inFlagsMask; + }; + + AUComponentDescription(const AudioComponentDescription &inDescription) + { + *(AudioComponentDescription*)this = inDescription; + }; +}; + +#pragma mark- RenderProc + +// audio render procedure, don't allocate memory, don't take any locks, don't waste time +static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) +{ + SoundBufferPtr sndbuf = (SoundBufferPtr)inRefCon; + + UInt32 bufSamples = sndbuf[inBusNumber].numFrames; + AudioUnitSampleType *in = sndbuf[inBusNumber].data; + + AudioUnitSampleType *outA = (AudioUnitSampleType *)ioData->mBuffers[0].mData; + AudioUnitSampleType *outB = (AudioUnitSampleType *)ioData->mBuffers[1].mData; + + UInt32 sample = sndbuf[inBusNumber].sampleNum; + for (UInt32 i = 0; i < inNumberFrames; ++i) { + if (1 == inBusNumber) { + outA[i] = 0; + outB[i] = in[sample++]; + } else { + outA[i] = in[sample++]; + outB[i] = 0; + } + if (sample >= bufSamples) sample = 0; + } + sndbuf[inBusNumber].sampleNum = sample; + // printf("bus %d sample %d\n", inBusNumber, sample); + + return noErr; +} + +#pragma mark- MultichannelMixerController + +@interface MultichannelMixerController (hidden) + +- (void)loadFiles; + +@end + +@implementation MultichannelMixerController + +@synthesize isPlaying; + +- (void)dealloc +{ + printf("MultichannelMixerController dealloc\n"); + + DisposeAUGraph(mGraph); + + free(mSoundBuffer[0].data); + free(mSoundBuffer[1].data); + + CFRelease(sourceURL[0]); + CFRelease(sourceURL[1]); + + [super dealloc]; +} + +- (void)awakeFromNib +{ + printf("awakeFromNib\n"); + + isPlaying = false; + + // clear the mSoundBuffer struct + memset(&mSoundBuffer, 0, sizeof(mSoundBuffer)); + + // create the URLs we'll use for source A and B + NSString *sourceA = [[NSBundle mainBundle] pathForResource:@"GuitarMonoSTP" ofType:@"aif"]; + NSString *sourceB = [[NSBundle mainBundle] pathForResource:@"DrumsMonoSTP" ofType:@"aif"]; + sourceURL[0] = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)sourceA, kCFURLPOSIXPathStyle, false); + sourceURL[1] = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)sourceB, kCFURLPOSIXPathStyle, false); +} + +- (void)initializeAUGraph +{ + printf("initialize\n"); + + AUNode outputNode; + AUNode mixerNode; + CAStreamBasicDescription desc; + + OSStatus result = noErr; + + // load up the audio data + [self performSelectorInBackground:@selector(loadFiles) withObject:nil]; + + // create a new AUGraph + result = NewAUGraph(&mGraph); + if (result) { printf("NewAUGraph result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + // create two AudioComponentDescriptions for the AUs we want in the graph + + // output unit + AUComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple); + + // multichannel mixer unit + AUComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple); + + printf("new nodes\n"); + + // create a node in the graph that is an AudioUnit, using the supplied AudioComponentDescription to find and open that unit + result = AUGraphAddNode(mGraph, &output_desc, &outputNode); + if (result) { printf("AUGraphNewNode 1 result %lu %4.4s\n", result, (char*)&result); return; } + + result = AUGraphAddNode(mGraph, &mixer_desc, &mixerNode ); + if (result) { printf("AUGraphNewNode 2 result %lu %4.4s\n", result, (char*)&result); return; } + + // connect a node's output to a node's input + result = AUGraphConnectNodeInput(mGraph, mixerNode, 0, outputNode, 0); + if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; } + + // open the graph AudioUnits are open but not initialized (no resource allocation occurs here) + result = AUGraphOpen(mGraph); + if (result) { printf("AUGraphOpen result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + result = AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer); + if (result) { printf("AUGraphNodeInfo result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + // set bus count + UInt32 numbuses = 2; + UInt32 size = sizeof(numbuses); + + printf("set input bus count %lu\n", numbuses); + + result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &numbuses, sizeof(UInt32)); + if (result) { printf("AudioUnitSetProperty result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + for (int i = 0; i < numbuses; ++i) { + // setup render callback struct + AURenderCallbackStruct rcbs; + rcbs.inputProc = &renderInput; + rcbs.inputProcRefCon = mSoundBuffer; + + printf("set kAudioUnitProperty_SetRenderCallback\n"); + + // Set a callback for the specified node's specified input + result = AUGraphSetNodeInputCallback(mGraph, mixerNode, i, &rcbs); + // equivalent to AudioUnitSetProperty(mMixer, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, i, &rcbs, sizeof(rcbs)); + if (result) { printf("AUGraphSetNodeInputCallback result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + // set input stream format to what we want + printf("get kAudioUnitProperty_StreamFormat\n"); + + size = sizeof(desc); + result = AudioUnitGetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, i, &desc, &size); + if (result) { printf("AudioUnitGetProperty result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + desc.ChangeNumberChannels(2, false); + desc.mSampleRate = kGraphSampleRate; + + printf("set kAudioUnitProperty_StreamFormat\n"); + + result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, i, &desc, sizeof(desc)); + if (result) { printf("AudioUnitSetProperty result %d %08X %4.4s\n", result, result, (char*)&result); return; } + } + + // set output stream format to what we want + printf("get kAudioUnitProperty_StreamFormat\n"); + + result = AudioUnitGetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &desc, &size); + if (result) { printf("AudioUnitGetProperty result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + desc.ChangeNumberChannels(2, false); + desc.mSampleRate = kGraphSampleRate; + + printf("set kAudioUnitProperty_StreamFormat\n"); + + result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &desc, sizeof(desc)); + if (result) { printf("AudioUnitSetProperty result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + printf("AUGraphInitialize\n"); + + // now that we've set everything up we can initialize the graph, this will also validate the connections + result = AUGraphInitialize(mGraph); + if (result) { printf("AUGraphInitialize result %d %08X %4.4s\n", result, result, (char*)&result); return; } +} + +// load up audio data from the demo files into mSoundBuffer.data used in the render proc +- (void)loadFiles +{ + for (int i = 0; i < NUMFILES && i < MAXBUFS; i++) { + printf("loadFiles, %d\n", i); + + ExtAudioFileRef xafref = 0; + + // open one of the two source files + OSStatus result = ExtAudioFileOpenURL(sourceURL[i], &xafref); + if (result || !xafref) { printf("ExtAudioFileOpenURL result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + // get the file data format, this represents the file's actual data format + CAStreamBasicDescription clientFormat; + UInt32 propSize = sizeof(clientFormat); + + result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileDataFormat, &propSize, &clientFormat); + if (result) { printf("ExtAudioFileGetProperty kExtAudioFileProperty_FileDataFormat result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + // set the client format to be what we want back + double rateRatio = kGraphSampleRate / clientFormat.mSampleRate; + clientFormat.mSampleRate = kGraphSampleRate; + clientFormat.SetAUCanonical(1, true); + + propSize = sizeof(clientFormat); + result = ExtAudioFileSetProperty(xafref, kExtAudioFileProperty_ClientDataFormat, propSize, &clientFormat); + if (result) { printf("ExtAudioFileSetProperty kExtAudioFileProperty_ClientDataFormat %d %08X %4.4s\n", result, result, (char*)&result); return; } + + // get the file's length in sample frames + UInt64 numFrames = 0; + propSize = sizeof(numFrames); + result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileLengthFrames, &propSize, &numFrames); + if (result) { printf("ExtAudioFileGetProperty kExtAudioFileProperty_FileLengthFrames result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + numFrames = (UInt32)(numFrames * rateRatio); // account for any sample rate conversion + + // set up our buffer + mSoundBuffer[i].numFrames = numFrames; + mSoundBuffer[i].asbd = clientFormat; + + UInt32 samples = numFrames * mSoundBuffer[i].asbd.mChannelsPerFrame; + mSoundBuffer[i].data = (AudioUnitSampleType *)calloc(samples, sizeof(AudioUnitSampleType)); + mSoundBuffer[i].sampleNum = 0; + + // set up a AudioBufferList to read data into + AudioBufferList bufList; + bufList.mNumberBuffers = 1; + bufList.mBuffers[0].mNumberChannels = 1; + bufList.mBuffers[0].mData = mSoundBuffer[i].data; + bufList.mBuffers[0].mDataByteSize = samples * sizeof(AudioUnitSampleType); + + // perform a synchronous sequential read of the audio data out of the file into our allocated data buffer + UInt32 numPackets = numFrames; + result = ExtAudioFileRead(xafref, &numPackets, &bufList); + if (result) { + printf("ExtAudioFileRead result %d %08X %4.4s\n", result, result, (char*)&result); + free(mSoundBuffer[i].data); + mSoundBuffer[i].data = 0; + return; + } + + // close the file and dispose the ExtAudioFileRef + ExtAudioFileDispose(xafref); + } +} + +#pragma mark- + +// enable or disables a specific bus +- (void)enableInput:(UInt32)inputNum isOn:(AudioUnitParameterValue)isONValue +{ + printf("BUS %d isON %f\n", inputNum, isONValue); + + OSStatus result = AudioUnitSetParameter(mMixer, kMultiChannelMixerParam_Enable, kAudioUnitScope_Input, inputNum, isONValue, 0); + if (result) { printf("AudioUnitSetParameter kMultiChannelMixerParam_Enable result %d %08X %4.4s\n", result, result, (char*)&result); return; } + +} + +// sets the input volume for a specific bus +- (void)setInputVolume:(UInt32)inputNum value:(AudioUnitParameterValue)value +{ + OSStatus result = AudioUnitSetParameter(mMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, inputNum, value, 0); + if (result) { printf("AudioUnitSetParameter kMultiChannelMixerParam_Volume Input result %d %08X %4.4s\n", result, result, (char*)&result); return; } +} + +// sets the overall mixer output volume +- (void)setOutputVolume:(AudioUnitParameterValue)value +{ + OSStatus result = AudioUnitSetParameter(mMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, 0, value, 0); + if (result) { printf("AudioUnitSetParameter kMultiChannelMixerParam_Volume Output result %d %08X %4.4s\n", result, result, (char*)&result); return; } +} + +// stars render +- (void)startAUGraph +{ + printf("PLAY\n"); + + OSStatus result = AUGraphStart(mGraph); + if (result) { printf("AUGraphStart result %d %08X %4.4s\n", result, result, (char*)&result); return; } + isPlaying = true; +} + +// stops render +- (void)stopAUGraph +{ + printf("STOP\n"); + + Boolean isRunning = false; + + OSStatus result = AUGraphIsRunning(mGraph, &isRunning); + if (result) { printf("AUGraphIsRunning result %d %08X %4.4s\n", result, result, (char*)&result); return; } + + if (isRunning) { + result = AUGraphStop(mGraph); + if (result) { printf("AUGraphStop result %d %08X %4.4s\n", result, result, (char*)&result); return; } + isPlaying = false; + } +} + +@end \ No newline at end of file diff --git a/iPhoneMultichannelMixerTest/Classes/MultichannelMixerTestDelegate.h b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerTestDelegate.h new file mode 100644 index 0000000..dfe4399 --- /dev/null +++ b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerTestDelegate.h @@ -0,0 +1,66 @@ +/* + File: MultichannelMixerTestDelegate.h + Abstract: The application delegate class. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import + +#import "MyViewController.h"file +#import "CAXException.h" + +@interface MultichannelMixerTestDelegate : NSObject { + IBOutlet UIWindow *window; + + IBOutlet UINavigationController *navigationController; + IBOutlet MyViewController *myViewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet MyViewController *myViewController; + +@end + diff --git a/iPhoneMultichannelMixerTest/Classes/MultichannelMixerTestDelegate.m b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerTestDelegate.m new file mode 100644 index 0000000..c0bf269 --- /dev/null +++ b/iPhoneMultichannelMixerTest/Classes/MultichannelMixerTestDelegate.m @@ -0,0 +1,152 @@ +/* + File: MultichannelMixerTestDelegate.m + Abstract: The application delegate class. + + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MultichannelMixerTestDelegate.h" + +@implementation MultichannelMixerTestDelegate + +@synthesize window, navigationController, myViewController; + +#pragma mark -Audio Session Interruption Listener + +static void interruptionListener(void *inClientData, UInt32 inInterruption) +{ + printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + MultichannelMixerTestDelegate *THIS = (MultichannelMixerTestDelegate *)inClientData; + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + AudioSessionSetActive(true); + } + + if (inInterruption == kAudioSessionBeginInterruption) { + // session is already set to not active so if we're playing stop + [THIS->myViewController stopForInterruption]; + } +} + +#pragma mark -Audio Session Property Listener + +static void propertyListener(void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) +{ + //MultichannelMixerTestDelegate *THIS = (MultichannelMixerTestDelegate *)inClientData; + + if (inID == kAudioSessionProperty_AudioRouteChange) { + try { + CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inData; + + UInt32 routeChangeReason; + CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); + CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); + printf("Audio Route Change, Reason: %d\n", routeChangeReason); + + CFStringRef routeChangeOldRouteRef = (CFStringRef)CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute)); + printf("Old Route: "); + CFShow(routeChangeOldRouteRef); + + CFStringRef newRoute; + UInt32 size = sizeof(newRoute); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute), "couldn't get new audio route"); + if (newRoute) { + printf("New Route: "); + CFShow(newRoute); + } + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + } +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after application launch + [window addSubview:[navigationController view]]; + [window makeKeyAndVisible]; + + try { + // Initialize and configure the audio session + XThrowIfError(AudioSessionInitialize(NULL, NULL, interruptionListener, self), "couldn't initialize audio session"); + + UInt32 audioCategory = kAudioSessionCategory_MediaPlayback; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory), "couldn't set audio category"); + XThrowIfError(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propertyListener, self), "couldn't set property listener"); + + Float32 preferredBufferSize = .005; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize), "couldn't set i/o buffer duration"); + + Float64 hwSampleRate = 44100.0; + XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(hwSampleRate), &hwSampleRate), "couldn't set hw sample rate"); + + XThrowIfError(AudioSessionSetActive(true), "couldn't set audio session active\n"); + + UInt32 size = sizeof(hwSampleRate); + XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &hwSampleRate), "couldn't get hw sample rate"); + printf("Hardware Sample Rate: %f\n", hwSampleRate); + } catch (CAXException e) { + char buf[256]; + fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); + } + + // initialize the mixerController object + [myViewController.mixerController initializeAUGraph]; + + // set up the mixer according to our interface defaults + [myViewController setUIDefaults]; +} + +- (void)dealloc { + self.window = nil; + self.navigationController = nil; + self.myViewController = nil; + + [super dealloc]; +} + +@end diff --git a/iPhoneMultichannelMixerTest/Classes/MyViewController.h b/iPhoneMultichannelMixerTest/Classes/MyViewController.h new file mode 100755 index 0000000..df11835 --- /dev/null +++ b/iPhoneMultichannelMixerTest/Classes/MyViewController.h @@ -0,0 +1,99 @@ +/* + File: MyViewController.h + Abstract: The main view controller of this app + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import +#import + +#import "MultichannelMixerController.h" + +@interface MyViewController : UIViewController +{ + IBOutlet UIView *instructionsView; + IBOutlet UIWebView *webView; + IBOutlet UIView *contentView; + + UIBarButtonItem *flipButton; + UIBarButtonItem *doneButton; + + IBOutlet UIButton *startButton; + + IBOutlet UISwitch *bus0Switch; + IBOutlet UISlider *bus0VolumeSlider; + IBOutlet UISwitch *bus1Switch; + IBOutlet UISlider *bus1VolumeSlider; + IBOutlet UISlider *outputVolumeSlider; + + IBOutlet MultichannelMixerController *mixerController; +} + +@property (readonly, nonatomic) UIView *instructionsView; +@property (readonly, nonatomic) UIWebView *webView; +@property (readonly, nonatomic) UIView *contentView; + +@property (nonatomic, retain) UIBarButtonItem *flipButton; +@property (nonatomic, retain) UIBarButtonItem *doneButton; + +@property (readonly, nonatomic) UIButton *startButton; + +@property (readonly, nonatomic) UISwitch *bus0Switch; +@property (readonly, nonatomic) UISlider *bus0VolumeSlider; +@property (readonly, nonatomic) UISwitch *bus1Switch; +@property (readonly, nonatomic) UISlider *bus1VolumeSlider; +@property (readonly, nonatomic) UISlider *outputVolumeSlider; + +@property (readonly, nonatomic)MultichannelMixerController *mixerController; + +- (void)setUIDefaults; +- (void)stopForInterruption; + +- (IBAction)enableInput:(UISwitch *)sender; +- (IBAction)setInputVolume:(UISlider *)sender; +- (IBAction)setOutputVolume:(UISlider *)sender; + +- (IBAction)doSomethingAction:(id)sender; + +@end \ No newline at end of file diff --git a/iPhoneMultichannelMixerTest/Classes/MyViewController.m b/iPhoneMultichannelMixerTest/Classes/MyViewController.m new file mode 100755 index 0000000..89c33a6 --- /dev/null +++ b/iPhoneMultichannelMixerTest/Classes/MyViewController.m @@ -0,0 +1,209 @@ +/* + File: MyViewController.m + Abstract: The main view controller of this app + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import "MyViewController.h" + +#define kTransitionDuration 0.75 + +@implementation MyViewController + +@synthesize instructionsView, webView, contentView, flipButton, doneButton, startButton, bus0Switch, bus0VolumeSlider, bus1Switch, bus1VolumeSlider, outputVolumeSlider, mixerController; + +#pragma mark- UIView + +- (void)viewDidLoad +{ + // load up the info text + NSString *infoSouceFile = [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]; + NSString *infoText = [NSString stringWithContentsOfFile:infoSouceFile encoding:NSUTF8StringEncoding error:nil]; + [self.webView loadHTMLString:infoText baseURL:nil]; + + // set up start button + UIImage *greenImage = [[UIImage imageNamed:@"green_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + UIImage *redImage = [[UIImage imageNamed:@"red_button.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0]; + + [startButton setBackgroundImage:greenImage forState:UIControlStateNormal]; + [startButton setBackgroundImage:redImage forState:UIControlStateSelected]; + + // add the subview + [self.view addSubview:contentView]; + + // add our custom flip buttons as the nav bars custom right view + UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; + [infoButton addTarget:self action:@selector(flipAction:) forControlEvents:UIControlEventTouchUpInside]; + + flipButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton]; + self.navigationItem.rightBarButtonItem = flipButton; + + // create our done button as the nav bar's custom right view for the flipped view (used later) + doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(flipAction:)]; +} + +- (void)didReceiveMemoryWarning +{ + // invoke super's implementation to do the Right Thing. In practice this is unlikely to be used in this application, + // and it would be of little benefit, but the principle is the important thing. + [super didReceiveMemoryWarning]; +} + +- (void)dealloc +{ + [instructionsView release]; + [webView release]; + [contentView release]; + + self.flipButton = nil; + self.doneButton = nil; + + [startButton release]; + + [bus0Switch release]; + [bus0VolumeSlider release]; + [bus1Switch release]; + [bus1VolumeSlider release]; + [outputVolumeSlider release]; + + [mixerController release]; + + [super dealloc]; +} + +#pragma mark- + +// set the mixers values according to the UI state +- (void)setUIDefaults +{ + [mixerController enableInput:0 isOn:bus0Switch.isOn]; + [mixerController enableInput:1 isOn:bus1Switch.isOn]; + [mixerController setInputVolume:0 value:bus0VolumeSlider.value]; + [mixerController setInputVolume:1 value:bus1VolumeSlider.value]; + [mixerController setOutputVolume:outputVolumeSlider.value]; +} + +// do the info button flip +- (void)flipAction:(id)sender +{ + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:animationIDfinished:finished:context:)]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + + [UIView setAnimationTransition:([self.contentView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) + forView:self.view + cache:YES]; + + if ([self.instructionsView superview]) { + [self.instructionsView removeFromSuperview]; + [self.view addSubview:contentView]; + } else { + [self.contentView removeFromSuperview]; + [self.view addSubview:instructionsView]; + } + + [UIView commitAnimations]; + + // adjust our done/info buttons accordingly + if ([instructionsView superview]) { + self.navigationItem.rightBarButtonItem = doneButton; + } else { + self.navigationItem.rightBarButtonItem = flipButton; + } +} + +// called if we've been interrupted and if we're playing, stop +- (void)stopForInterruption +{ + if (mixerController.isPlaying) { + [mixerController stopAUGraph]; + self.startButton.selected = NO; + } +} + +#pragma mark- Actions + +// handle input on/off switch action +- (IBAction)enableInput:(UISwitch *)sender +{ + UInt32 inputNum = [sender tag]; + AudioUnitParameterValue isOn = (AudioUnitParameterValue)sender.isOn; + + if (0 == inputNum) self.bus0VolumeSlider.enabled = isOn; + if (1 == inputNum) self.bus1VolumeSlider.enabled = isOn; + + [mixerController enableInput:inputNum isOn:isOn]; +} + +// handle input volume changes +- (IBAction)setInputVolume:(UISlider *)sender +{ + UInt32 inputNum = [sender tag]; + AudioUnitParameterValue value = sender.value; + + [mixerController setInputVolume:inputNum value:value]; +} + +// handle output volume changes +- (IBAction)setOutputVolume:(UISlider *)sender +{ + AudioUnitParameterValue value = sender.value; + + [mixerController setOutputVolume:value]; +} + +// handle the button press +- (IBAction)doSomethingAction:(id)sender +{ + if (mixerController.isPlaying) { + [mixerController stopAUGraph]; + self.startButton.selected = NO; + } else { + [mixerController startAUGraph]; + self.startButton.selected = YES; + } +} + +@end \ No newline at end of file diff --git a/iPhoneMultichannelMixerTest/Info.plist b/iPhoneMultichannelMixerTest/Info.plist new file mode 100644 index 0000000..891321a --- /dev/null +++ b/iPhoneMultichannelMixerTest/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.apple.dts.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + eDTS + CFBundleVersion + 1.1 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/iPhoneMultichannelMixerTest/MultichannelMixerTest_Prefix.pch b/iPhoneMultichannelMixerTest/MultichannelMixerTest_Prefix.pch new file mode 100644 index 0000000..a17209c --- /dev/null +++ b/iPhoneMultichannelMixerTest/MultichannelMixerTest_Prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iPhoneMultichannelMixerTest/ReadMe.txt b/iPhoneMultichannelMixerTest/ReadMe.txt new file mode 100755 index 0000000..0a66acf --- /dev/null +++ b/iPhoneMultichannelMixerTest/ReadMe.txt @@ -0,0 +1,85 @@ +iPhoneMultichannelMixerTest + +=========================================================================== +DESCRIPTION: + +iPhoneMultichannelMixerTest demonstrates how to build an Audio Unit Graph connecting a MultiChannel Mixer instance +to the RemoteIO unit. +Two input busses are created each with input volume controls. An overall mixer output volume control is also provided +and each bus may be enabled or disabled. + +All the relevant code is in the file MultichannelMixerController.mm while the supporting UI code is in MyViewController.m + +Touching the "Play Audio" button simply calls AUGraphStart while "Stop Audio" calls AUGraphStop. Changing AU volume is +performed via AudioUnitSetParameter. + +Audio data is provided from two single channel audio files. Each single channel of data +(a guitar riff and drum groove respectively) is rendered to a single channel of each input bus resulting in the guitar +on the left channel and the drums on the right channel at the output. This serves no specific purpose other than making +for an obvious sample where you can turn off and change the volume of each input and be very aware of the results. + + +=========================================================================== +RELATED INFORMATION: + +Audio Session Programming Guide +Core Audio Overview +Audio Unit Processing Graph Services Reference +Output Audio Unit Services Reference +System Audio Unit Access Guide +Audio Component Services Reference +Audio File Services Reference + + +AudioToolbox/AUGraph.h +AudioToolbox/ExtendedAudioFile.h + + +=========================================================================== +SPECIAL CONSIDERATIONS: + +None + + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 or later + +=========================================================================== +PACKAGING LIST: + +MultichannelMixerTestDelegate.h +MultichannelMixerTestDelegate.m + +The MultichannelMixerTestDelegate class defines the application delegate object, responsible for adding the navigation +controllers view to the application window, setting up the Audio Session and so on. + +MyViewController.h +MyViewController.m + +The MyViewController class defines the controller object for the application. The object helps set up the user interface, +responds to and manages user interaction, and communicates with the MultichannelMixerController. + +MultichannelMixerController.h +MultichannelMixerController.mm + +This file implements setting up the AUGraph, loading up the audio data using ExtAudioFile, the input render procedure and so on. + +All the code demonstrating interacting with Core Audio is in this one file, the rest of the sample can be thought of as a simple +framework for the demonstration code in this file. + +=========================================================================== +CHANGES FROM PREVIOUS VERSIONS: + +Version 1.1, upgraded project to build with the iOS 4 SDK. +Version 1.0, tested with iPhone OS 3.0. First public release. + + +================================================================================ +Copyright (C) 2009-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/iPhoneMultichannelMixerTest/Resources/DrumsMonoSTP.aif b/iPhoneMultichannelMixerTest/Resources/DrumsMonoSTP.aif new file mode 100644 index 0000000..674c672 Binary files /dev/null and b/iPhoneMultichannelMixerTest/Resources/DrumsMonoSTP.aif differ diff --git a/iPhoneMultichannelMixerTest/Resources/GuitarMonoSTP.aif b/iPhoneMultichannelMixerTest/Resources/GuitarMonoSTP.aif new file mode 100644 index 0000000..6c8b549 Binary files /dev/null and b/iPhoneMultichannelMixerTest/Resources/GuitarMonoSTP.aif differ diff --git a/iPhoneMultichannelMixerTest/Resources/green_button.png b/iPhoneMultichannelMixerTest/Resources/green_button.png new file mode 100755 index 0000000..6c8b20e Binary files /dev/null and b/iPhoneMultichannelMixerTest/Resources/green_button.png differ diff --git a/iPhoneMultichannelMixerTest/Resources/info.html b/iPhoneMultichannelMixerTest/Resources/info.html new file mode 100644 index 0000000..35e41ff --- /dev/null +++ b/iPhoneMultichannelMixerTest/Resources/info.html @@ -0,0 +1,38 @@ + + +

+ +

Demonstrates the use of the AUGraph and related APIs. All the relevant code is +in the file MultichannelMixerController.mm. Touching the "Play Audio" button simply calls +AUGraphStart starting the graph initialized by the class, while "Stop Audio" will call +AUGraphStop. Audio data from each file is provided to the appropriate bus via the +renderInput Render Procedure. Each of the two input busses may be enabled or disabled +and volume controls are provided for both inputs and the mixer output.

+ +


+ +

Audio Unit Processing Graph Services provide interfaces for representing a set of +audio units, connections between their inputs and outputs, and callbacks used to provide +inputs. It also enables the embedding of sub (or child) processing graphs within parent +graphs to allow for a logical organization of parts of an overall signal chain.

+ +

An audio processing graph object (of type AUGraph) is a complete description of an +audio signal processing network. Audio Unit Processing Graph Services may manage the +instantiated audio units if the AUGraphOpen function is called.

+ +

An audio processing graph object may be introspected to get complete information +about all of the audio units in the graph. The various node objects (each of type AUNode) +in the graph, each representing an audio unit or a sub graph, may be added or removed, +and the interactions between them modified.

+ + +

A graph object’s state can be manipulated in both the rendering thread and in other +threads. Consequently, any activities that affect the state of the graph are guarded with +locks and a messaging model between any calling thread and the thread upon which the +graph object’s output unit is called (the render thread).

+ +

A graph object will have a single head node-an output unit. The output unit is used to +both start and stop the rendering operations of a graph, and is the dispatch point for +the safe manipulation of the state of the graph while it is running.

+
+
\ No newline at end of file diff --git a/iPhoneMultichannelMixerTest/Resources/red_button.png b/iPhoneMultichannelMixerTest/Resources/red_button.png new file mode 100755 index 0000000..42de34e Binary files /dev/null and b/iPhoneMultichannelMixerTest/Resources/red_button.png differ diff --git a/iPhoneMultichannelMixerTest/en.lproj/MainWindow.xib b/iPhoneMultichannelMixerTest/en.lproj/MainWindow.xib new file mode 100644 index 0000000..4405666 --- /dev/null +++ b/iPhoneMultichannelMixerTest/en.lproj/MainWindow.xib @@ -0,0 +1,808 @@ + + + + 768 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + 1 + MCAwIDAAA + + NO + NO + YES + + + + + 256 + {0, 0} + NO + YES + YES + + + YES + + + + 274 + {320, 436} + + 1 + MSAxIDEAA + + NO + + + MC Mixer Test + + + + + + + + 268 + + YES + + + 268 + {{-2250, 100}, {42, 21}} + + NO + YES + NO + Label + + + 1 + 1.000000e+01 + + + + 292 + {{20, 20}, {280, 420}} + + + YES + YES + YES + + + {320, 460} + + 3 + MQA + + 2 + + + NO + + + + 292 + + YES + + + 292 + {{62, 28}, {201, 40}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 1.500000e+01 + 16 + + 1 + NO + + + Stop Audio + Play Audio + + + + + 3 + MAA + + + + + 292 + {{30, 124}, {94, 27}} + + NO + YES + 0 + 0 + YES + + + + 292 + {{20, 88}, {140, 21}} + + NO + YES + NO + Mixer Input Bus 0: + + Helvetica + 1.400000e+01 + 16 + + + + 1 + 1.000000e+01 + + + + 292 + {{28, 166}, {264, 23}} + + NO + YES + 0 + 0 + 5.000000e-01 + NO + + + + 292 + {{30, 239}, {94, 27}} + + NO + YES + 1 + 0 + 0 + YES + + + + 292 + {{20, 203}, {140, 21}} + + NO + YES + NO + Mixer Input Bus 1: + + + + 1 + 1.000000e+01 + + + + 292 + {{28, 281}, {264, 23}} + + NO + YES + 1 + 0 + 0 + 5.000000e-01 + NO + + + + 292 + {{20, 323}, {167, 21}} + + NO + YES + NO + Mixer Output Volume: + + + + 1 + 1.000000e+01 + + + + 292 + {{28, 359}, {264, 23}} + + NO + YES + 0 + 0 + 1.000000e+00 + NO + + + {320, 460} + + + NO + + + + + + YES + + + delegate + + + + 4 + + + + instructionsView + + + + 26 + + + + contentView + + + + 27 + + + + webView + + + + 32 + + + + startButton + + + + 33 + + + + doSomethingAction: + + + 7 + + 36 + + + + navigationController + + + + 45 + + + + myViewController + + + + 46 + + + + window + + + + 47 + + + + bus0Switch + + + + 48 + + + + bus0VolumeSlider + + + + 49 + + + + bus1Switch + + + + 50 + + + + bus1VolumeSlider + + + + 51 + + + + mixerController + + + + 59 + + + + outputVolumeSlider + + + + 62 + + + + setOutputVolume: + + + 13 + + 67 + + + + setInputVolume: + + + 13 + + 68 + + + + setInputVolume: + + + 13 + + 69 + + + + enableInput: + + + 13 + + 75 + + + + enableInput: + + + 13 + + 76 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + AppDelegate + + + -2 + + + + + 10 + + + YES + + + + + + + 11 + + + YES + + + + + + + 12 + + + + + 13 + + + + + 14 + + + YES + + + + + InstructionsView + + + 18 + + + + + 19 + + + YES + + + + + + + + + + + + ContentView + + + 20 + + + + + 22 + + + YES + + + + + 30 + + + + + 37 + + + + + 38 + + + + + 39 + + + + + 41 + + + + + 42 + + + + + 43 + + + + + 58 + + + + + 60 + + + + + 61 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 11.CustomClassName + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBEditorWindowLastContentRect + 14.IBPluginDependency + 14.IBViewEditorWindowController.showingLayoutRectangles + 18.IBPluginDependency + 19.IBEditorWindowLastContentRect + 19.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 20.IBPluginDependency + 22.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 30.IBPluginDependency + 37.IBPluginDependency + 38.IBPluginDependency + 39.IBPluginDependency + 41.IBPluginDependency + 42.IBPluginDependency + 43.IBPluginDependency + 58.CustomClassName + 58.IBPluginDependency + 60.IBPluginDependency + 61.IBPluginDependency + + + YES + UIApplication + UIResponder + {{629, 113}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MyViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{133, 77}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{209, 522}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{789, 283}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MultichannelMixerTestDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MultichannelMixerController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 76 + + + + YES + + MultichannelMixerController + NSObject + + IBProjectSource + Classes/MultichannelMixerController.h + + + + MultichannelMixerTestDelegate + NSObject + + YES + + YES + myViewController + navigationController + window + + + YES + MyViewController + UINavigationController + UIWindow + + + + IBProjectSource + Classes/MultichannelMixerTestDelegate.h + + + + MyViewController + UIViewController + + YES + + YES + doSomethingAction: + enableInput: + setInputVolume: + setOutputVolume: + + + YES + id + UISwitch + UISlider + UISlider + + + + YES + + YES + bus0Switch + bus0VolumeSlider + bus1Switch + bus1VolumeSlider + contentView + instructionsView + mixerController + outputVolumeSlider + startButton + webView + + + YES + UISwitch + UISlider + UISwitch + UISlider + UIView + UIView + MultichannelMixerController + UISlider + UIButton + UIWebView + + + + IBProjectSource + Classes/MyViewController.h + + + + UIView + UIResponder + + IBUserSource + + + + + + 0 + iPhoneMultichannelMixerTest.xcodeproj + 3 + 3.0 + + diff --git a/iPhoneMultichannelMixerTest/iPhoneMultichannelMixerTest.xcodeproj/project.pbxproj b/iPhoneMultichannelMixerTest/iPhoneMultichannelMixerTest.xcodeproj/project.pbxproj new file mode 100755 index 0000000..44b3c39 --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPhoneMultichannelMixerTest.xcodeproj/project.pbxproj @@ -0,0 +1,357 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 185E840311E5253D0096E7CF /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 185E840111E5253D0096E7CF /* MainWindow.xib */; }; + 185E840B11E525570096E7CF /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 185E840411E525570096E7CF /* Icon-72.png */; }; + 185E840C11E525570096E7CF /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 185E840511E525570096E7CF /* Icon-Small-50.png */; }; + 185E840D11E525570096E7CF /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 185E840611E525570096E7CF /* Icon-Small.png */; }; + 185E840E11E525570096E7CF /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 185E840711E525570096E7CF /* Icon-Small@2x.png */; }; + 185E840F11E525570096E7CF /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 185E840811E525570096E7CF /* Icon.png */; }; + 185E841011E525570096E7CF /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 185E840911E525570096E7CF /* Icon@2x.png */; }; + 185E841111E525570096E7CF /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 185E840A11E525570096E7CF /* iTunesArtwork */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C70F5383D30033DE8C /* AVFoundation.framework */; }; + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */; }; + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */; }; + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1C0F59F67E00D63998 /* green_button.png */; }; + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1D0F59F67E00D63998 /* red_button.png */; }; + 2BE30B230F59F67E00D63998 /* info.html in Resources */ = {isa = PBXBuildFile; fileRef = 2BE30B1F0F59F67E00D63998 /* info.html */; }; + 2BF43A3C1016927300FBDA14 /* MultichannelMixerTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF43A3B1016927300FBDA14 /* MultichannelMixerTestDelegate.m */; }; + 2BF43B011017CED800FBDA14 /* DrumsMonoSTP.aif in Resources */ = {isa = PBXBuildFile; fileRef = 2BF43AFF1017CED800FBDA14 /* DrumsMonoSTP.aif */; }; + 2BF43B021017CED800FBDA14 /* GuitarMonoSTP.aif in Resources */ = {isa = PBXBuildFile; fileRef = 2BF43B001017CED800FBDA14 /* GuitarMonoSTP.aif */; }; + 2BF43BD0101A4C9200FBDA14 /* MultichannelMixerController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2BF43BCE101A4C9200FBDA14 /* MultichannelMixerController.mm */; }; + 2BF8389A1047021B000A5DCC /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF838981047021B000A5DCC /* CAXException.cpp */; }; + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 185E840211E5253D0096E7CF /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 185E840411E525570096E7CF /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 185E840511E525570096E7CF /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 185E840611E525570096E7CF /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 185E840711E525570096E7CF /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 185E840811E525570096E7CF /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 185E840911E525570096E7CF /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 185E840A11E525570096E7CF /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* MCMixerTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MCMixerTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2BA4F216101FA32700975F88 /* MultichannelMixerTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultichannelMixerTest_Prefix.pch; sourceTree = ""; }; + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = ""; }; + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = ""; }; + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + 2BE30B1C0F59F67E00D63998 /* green_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = green_button.png; path = Resources/green_button.png; sourceTree = ""; }; + 2BE30B1D0F59F67E00D63998 /* red_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = red_button.png; path = Resources/red_button.png; sourceTree = ""; }; + 2BE30B1F0F59F67E00D63998 /* info.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = info.html; path = Resources/info.html; sourceTree = ""; }; + 2BF43A3A1016927300FBDA14 /* MultichannelMixerTestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultichannelMixerTestDelegate.h; sourceTree = ""; }; + 2BF43A3B1016927300FBDA14 /* MultichannelMixerTestDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MultichannelMixerTestDelegate.m; sourceTree = ""; }; + 2BF43AFF1017CED800FBDA14 /* DrumsMonoSTP.aif */ = {isa = PBXFileReference; lastKnownFileType = file; name = DrumsMonoSTP.aif; path = Resources/DrumsMonoSTP.aif; sourceTree = ""; }; + 2BF43B001017CED800FBDA14 /* GuitarMonoSTP.aif */ = {isa = PBXFileReference; lastKnownFileType = file; name = GuitarMonoSTP.aif; path = Resources/GuitarMonoSTP.aif; sourceTree = ""; }; + 2BF43BCE101A4C9200FBDA14 /* MultichannelMixerController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MultichannelMixerController.mm; sourceTree = ""; }; + 2BF43BCF101A4C9200FBDA14 /* MultichannelMixerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultichannelMixerController.h; sourceTree = ""; }; + 2BF838981047021B000A5DCC /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = ""; }; + 2BF838991047021B000A5DCC /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = ""; }; + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyViewController.m; sourceTree = ""; }; + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyViewController.h; sourceTree = ""; }; + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 2B5324C80F5383D30033DE8C /* AVFoundation.framework in Frameworks */, + 2B5324CA0F5383DD0033DE8C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 2BF43A3A1016927300FBDA14 /* MultichannelMixerTestDelegate.h */, + 2BF43A3B1016927300FBDA14 /* MultichannelMixerTestDelegate.m */, + 2BF43BCF101A4C9200FBDA14 /* MultichannelMixerController.h */, + 2BF43BCE101A4C9200FBDA14 /* MultichannelMixerController.mm */, + 2BFBE19C0F5C9B30003ECC4F /* MyViewController.h */, + 2BFBE19B0F5C9B30003ECC4F /* MyViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* MCMixerTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 2BFBE1A00F5C9C30003ECC4F /* ReadMe.txt */, + 080E96DDFE201D6D7F000001 /* Classes */, + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 2BA4F216101FA32700975F88 /* MultichannelMixerTest_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 185E840411E525570096E7CF /* Icon-72.png */, + 185E840511E525570096E7CF /* Icon-Small-50.png */, + 185E840611E525570096E7CF /* Icon-Small.png */, + 185E840711E525570096E7CF /* Icon-Small@2x.png */, + 185E840811E525570096E7CF /* Icon.png */, + 185E840911E525570096E7CF /* Icon@2x.png */, + 185E840A11E525570096E7CF /* iTunesArtwork */, + 185E840111E5253D0096E7CF /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + 2BE30B1C0F59F67E00D63998 /* green_button.png */, + 2BE30B1D0F59F67E00D63998 /* red_button.png */, + 2BE30B1F0F59F67E00D63998 /* info.html */, + 2BF43B001017CED800FBDA14 /* GuitarMonoSTP.aif */, + 2BF43AFF1017CED800FBDA14 /* DrumsMonoSTP.aif */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2B5324C90F5383DD0033DE8C /* AudioToolbox.framework */, + 2B5324C70F5383D30033DE8C /* AVFoundation.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2BE30ABC0F59C4ED00D63998 /* iPublicUtility */ = { + isa = PBXGroup; + children = ( + 2BE30ABD0F59C4ED00D63998 /* CADebugMacros.h */, + 2BE30ABE0F59C4ED00D63998 /* CAMath.h */, + 2BF838991047021B000A5DCC /* CAXException.h */, + 2BE30AC00F59C4ED00D63998 /* CAStreamBasicDescription.h */, + 2BE30ABF0F59C4ED00D63998 /* CAStreamBasicDescription.cpp */, + 2BF838981047021B000A5DCC /* CAXException.cpp */, + ); + path = iPublicUtility; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* MCMixerTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MCMixerTest" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MCMixerTest; + productName = AQOffilineRenderTest; + productReference = 1D6058910D05DD3D006BFB54 /* MCMixerTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneMultichannelMixerTest" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* MCMixerTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BE30B200F59F67E00D63998 /* green_button.png in Resources */, + 2BE30B210F59F67E00D63998 /* red_button.png in Resources */, + 2BE30B230F59F67E00D63998 /* info.html in Resources */, + 2BF43B011017CED800FBDA14 /* DrumsMonoSTP.aif in Resources */, + 2BF43B021017CED800FBDA14 /* GuitarMonoSTP.aif in Resources */, + 185E840311E5253D0096E7CF /* MainWindow.xib in Resources */, + 185E840B11E525570096E7CF /* Icon-72.png in Resources */, + 185E840C11E525570096E7CF /* Icon-Small-50.png in Resources */, + 185E840D11E525570096E7CF /* Icon-Small.png in Resources */, + 185E840E11E525570096E7CF /* Icon-Small@2x.png in Resources */, + 185E840F11E525570096E7CF /* Icon.png in Resources */, + 185E841011E525570096E7CF /* Icon@2x.png in Resources */, + 185E841111E525570096E7CF /* iTunesArtwork in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 2BE30AC10F59C4ED00D63998 /* CAStreamBasicDescription.cpp in Sources */, + 2BFBE19D0F5C9B30003ECC4F /* MyViewController.m in Sources */, + 2BF43A3C1016927300FBDA14 /* MultichannelMixerTestDelegate.m in Sources */, + 2BF43BD0101A4C9200FBDA14 /* MultichannelMixerController.mm in Sources */, + 2BF8389A1047021B000A5DCC /* CAXException.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 185E840111E5253D0096E7CF /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 185E840211E5253D0096E7CF /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MultichannelMixerTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = MCMixerTest; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MultichannelMixerTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = MCMixerTest; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "MCMixerTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneMultichannelMixerTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/iPhoneMultichannelMixerTest/iPublicUtility/CADebugMacros.h b/iPhoneMultichannelMixerTest/iPublicUtility/CADebugMacros.h new file mode 100755 index 0000000..3c697ae --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPublicUtility/CADebugMacros.h @@ -0,0 +1,440 @@ +/* + + File: CADebugMacros.h +Abstract: Helper class for printing debug messages + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#if !defined(__CADebugMacros_h__) +#define __CADebugMacros_h__ + +//============================================================================= +// Includes +//============================================================================= + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CADebugMacros +//============================================================================= + +//#define CoreAudio_StopOnFailure 1 +//#define CoreAudio_TimeStampMessages 1 +//#define CoreAudio_ThreadStampMessages 1 +//#define CoreAudio_FlushDebugMessages 1 + +#if TARGET_RT_BIG_ENDIAN + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } +#else + #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } + #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } +#endif + +#pragma mark Basic Definitions + +#if DEBUG || CoreAudio_Debug + + // can be used to break into debugger immediately, also see CADebugger + #define BusError() (*(long *)0 = 0) + + // basic debugging print routines + #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON + extern void DebugStr(const unsigned char* debuggerMsg); + #define DebugMessage(msg) DebugStr("\p"msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #else + #include "CADebugPrintf.h" + + #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) + #define FlushRtn ,fflush(DebugPrintfFile) + #else + #define FlushRtn + #endif + + #if CoreAudio_ThreadStampMessages + #include + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #elif CoreAudio_TimeStampMessages + #include "CAHostTimeBase.h" + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #else + #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFileComma "%s"DebugPrintfLineEnding, msg) FlushRtn + #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1) FlushRtn + #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2) FlushRtn + #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn + #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFileComma msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn + #endif + #endif + void DebugPrint(const char *fmt, ...); // can be used like printf + #ifndef DEBUGPRINT + #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) + #endif + #if VERBOSE + #define vprint(msg) DEBUGPRINT(msg) + #else + #define vprint(msg) + #endif + + #if CoreAudio_StopOnFailure + #include "CADebugger.h" + #define STOP CADebuggerStop() + #else + #define STOP + #endif + +#else + #define DebugMessage(msg) + #define DebugMessageN1(msg, N1) + #define DebugMessageN2(msg, N1, N2) + #define DebugMessageN3(msg, N1, N2, N3) + #define DebugMessageN4(msg, N1, N2, N3, N4) + #define DebugMessageN5(msg, N1, N2, N3, N4, N5) + #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) + #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) + #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) + #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) + #define DEBUGPRINT(msg) + #define vprint(msg) + #define STOP +#endif + +void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) +void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) + +#if DEBUG || CoreAudio_Debug + +#pragma mark Debug Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + DebugMessage(inMessage); \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + char __4CC[5] = CA4CCToCString(__Err); \ + DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + DebugMessage(inMethodName": Subclasses must implement this method"); \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#else + +#pragma mark Release Macros + +#define Assert(inCondition, inMessage) \ + if(!(inCondition)) \ + { \ + STOP; \ + } + +#define AssertNoError(inError, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define AssertNoKernelError(inError, inMessage) \ + { \ + unsigned int __Err = (unsigned int)(inError); \ + if(__Err != 0) \ + { \ + STOP; \ + } \ + } + +#define FailIf(inCondition, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + goto inHandler; \ + } + +#define FailWithAction(inCondition, inAction, inHandler, inMessage) \ + if(inCondition) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ + if((inPointer) == NULL) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ + if((inKernelError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#define FailIfError(inError, inAction, inHandler, inMessage) \ + if((inError) != 0) \ + { \ + STOP; \ + { inAction; } \ + goto inHandler; \ + } + +#if defined(__cplusplus) + +#define Throw(inException) STOP; throw (inException) + +#define ThrowIf(inCondition, inException, inMessage) \ + if(inCondition) \ + { \ + Throw(inException); \ + } + +#define ThrowIfNULL(inPointer, inException, inMessage) \ + if((inPointer) == NULL) \ + { \ + Throw(inException); \ + } + +#define ThrowIfKernelError(inKernelError, inException, inMessage) \ + { \ + kern_return_t __Err = (inKernelError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#define ThrowIfError(inError, inException, inMessage) \ + { \ + SInt32 __Err = (inError); \ + if(__Err != 0) \ + { \ + Throw(inException); \ + } \ + } + +#if TARGET_OS_WIN32 +#define ThrowIfWinError(inError, inException, inMessage) \ + { \ + HRESULT __Err = (inError); \ + if(FAILED(__Err)) \ + { \ + Throw(inException); \ + } \ + } +#endif + +#define SubclassResponsibility(inMethodName, inException) \ + { \ + Throw(inException); \ + } + +#endif // defined(__cplusplus) + +#endif // DEBUG || CoreAudio_Debug + +#endif diff --git a/iPhoneMultichannelMixerTest/iPublicUtility/CAMath.h b/iPhoneMultichannelMixerTest/iPublicUtility/CAMath.h new file mode 100755 index 0000000..def9151 --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPublicUtility/CAMath.h @@ -0,0 +1,71 @@ +/* + + File: CAMath.h +Abstract: Helper class for various math functions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#ifndef __CAMath_h__ +#define __CAMath_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +inline bool fiszero(Float64 f) { return (f == 0.); } +inline bool fiszero(Float32 f) { return (f == 0.f); } + +inline bool fnonzero(Float64 f) { return !fiszero(f); } +inline bool fnonzero(Float32 f) { return !fiszero(f); } + +inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } +inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } + +inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } +inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } + +#endif // __CAMath_h__ diff --git a/iPhoneMultichannelMixerTest/iPublicUtility/CAStreamBasicDescription.cpp b/iPhoneMultichannelMixerTest/iPublicUtility/CAStreamBasicDescription.cpp new file mode 100755 index 0000000..6307741 --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,552 @@ +/* + + File: CAStreamBasicDescription.cpp +Abstract: Helper class for audio stream descriptions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + +#include "CAStreamBasicDescription.h" +#include "CAMath.h" + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include +#endif + +#if TARGET_OS_WIN32 + #include +#endif + +#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; + mReserved = 0; +} + +char *CAStreamBasicDescription::AsString(char *buf, size_t bufsize) const +{ + char *theBuffer = buf; + int nc; + char formatID[5]; + *(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID); + formatID[4] = '\0'; + nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); + buf += nc; bufsize -= nc; + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (wordSize > 0 && PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + sprintf(packed, "packed in %d bytes", wordSize); + else + sprintf(packed, "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + char bitdepth[20]; + +#if CA_PREFER_FIXED_POINT + int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; + if (fracbits > 0) + sprintf(bitdepth, "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); + else +#endif + sprintf(bitdepth, "%d", (int)mBitsPerChannel); + + nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s", + bitdepth, endian, sign, floatInt, + commaSpace, packed, align, deinter); + //buf += nc; bufsize -= nc; + } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless + int sourceBits = 0; + switch (mFormatFlags) + { + case 1: // kAppleLosslessFormatFlag_16BitSourceData + sourceBits = 16; + break; + case 2: // kAppleLosslessFormatFlag_20BitSourceData + sourceBits = 20; + break; + case 3: // kAppleLosslessFormatFlag_24BitSourceData + sourceBits = 24; + break; + case 4: // kAppleLosslessFormatFlag_32BitSourceData + sourceBits = 32; + break; + } + if (sourceBits) + nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits); + else + nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, "); + buf += nc; bufsize -= nc; + nc = snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket); + //buf += nc; bufsize -= nc; + } + else + nc = snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", + (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); + return theBuffer; +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format + if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) + { + // the canonical linear PCM format + ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; + ioDescription.mBytesPerPacket = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerFrame = sizeof(AudioSampleType) * ioDescription.mChannelsPerFrame; + ioDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType); + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(fiszero(ioDescription.mSampleRate)) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + const char* theMixabilityString = NULL; + if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) + { + theMixabilityString = "Mixable"; + } + else + { + theMixabilityString = "Unmixable"; + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strcpy(outName, "AC-3"); + break; + + case kAudioFormat60958AC3: + strcpy(outName, "AC-3 for SPDIF"); + break; + + default: + CACopy4CCToCString(outName, inDescription.mFormatID); + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + + // mixable is always better than non-mixable for linear PCM and should be the second order sort item + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) + { + theAnswer = true; + isDone = true; + } + else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) + { + theAnswer = false; + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) + { + if(fnotequal(x.mSampleRate, y.mSampleRate)) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + + // if the number of channels is 0 or 1, we don't care about non-interleavedness + if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) { + xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const +{ + if (interpretingWildcards) + return *this == other; + return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0.) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024); +} diff --git a/iPhoneMultichannelMixerTest/iPublicUtility/CAStreamBasicDescription.h b/iPhoneMultichannelMixerTest/iPublicUtility/CAStreamBasicDescription.h new file mode 100755 index 0000000..dcbe051 --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,310 @@ +/* + + File: CAStreamBasicDescription.h +Abstract: Helper class for audio stream descriptions + Version: 1.5 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2008 Apple Inc. All Rights Reserved. + + +*/ + + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CoreFoundation.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it + +// define Leopard specific symbols for backward compatibility if applicable +#if COREAUDIOTYPES_VERSION < 1050 +typedef Float32 AudioSampleType; +enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; +#endif +#if COREAUDIOTYPES_VERSION < 1051 +typedef Float32 AudioUnitSampleType; +#endif + +// define the IsMixable format flag for all versions of the system +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; +#else + enum { kIsNonMixableFlag = (1L << 6) }; +#endif + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { + return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; + } + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; +#if CA_ENV_MACOSX + int sampleSize = sizeof(Float32); + mFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + int sampleSize = sizeof(AudioSampleType); + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mBitsPerChannel = 8 * sampleSize; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; + else { + mBytesPerPacket = mBytesPerFrame = sampleSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + bool IsCanonical() const + { + if (mFormatID != kAudioFormatLinearPCM) return false; + UInt32 reqFormatFlags; +#if (COREAUDIOTYPES_VERSION <= 1050) + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh); +#else + UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); +#endif + bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; +#if CA_ENV_MACOSX + unsigned sampleSize = sizeof(Float32); + reqFormatFlags = kAudioFormatFlagsNativeFloatPacked; +#else + unsigned sampleSize = sizeof(AudioSampleType); + reqFormatFlags = kAudioFormatFlagsCanonical; +#endif + UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; + + return ((mFormatFlags & flagsMask) == reqFormatFlags + && mBitsPerChannel == 8 * sampleSize + && mFramesPerPacket == 1 + && mBytesPerFrame == reqFrameSize + && mBytesPerPacket == reqFrameSize); + } + + void SetAUCanonical(UInt32 nChannels, bool interleaved) + { + mFormatID = kAudioFormatLinearPCM; +#if CA_PREFER_FIXED_POINT + mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); +#else + mFormatFlags = kAudioFormatFlagsCanonical; +#endif + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); + else { + mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + if (wordSize == 0) + wordSize = (mBitsPerChannel + 7) / 8; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; + + void Print() const { + Print (stdout); + } + + void Print(FILE* file) const { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const { + char buf[256]; + fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); + } + + void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline + char buf[256]; + fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); + } + + char * AsString(char *buf, size_t bufsize) const; + + static void Print (const AudioStreamBasicDescription &inDesc) + { + CAStreamBasicDescription desc(inDesc); + desc.Print (); + } + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__ diff --git a/iPhoneMultichannelMixerTest/iPublicUtility/CAXException.cpp b/iPhoneMultichannelMixerTest/iPublicUtility/CAXException.cpp new file mode 100644 index 0000000..da39296 --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPublicUtility/CAXException.cpp @@ -0,0 +1,43 @@ +/* Copyright � 2007 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#include "CAXException.h" + +CAXException::WarningHandler CAXException::sWarningHandler = NULL; diff --git a/iPhoneMultichannelMixerTest/iPublicUtility/CAXException.h b/iPhoneMultichannelMixerTest/iPublicUtility/CAXException.h new file mode 100644 index 0000000..623b32f --- /dev/null +++ b/iPhoneMultichannelMixerTest/iPublicUtility/CAXException.h @@ -0,0 +1,189 @@ +/* Copyright � 2007 Apple Inc. All Rights Reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef __CAXException_h__ +#define __CAXException_h__ + +#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) + #include +#else + #include + #include +#endif +#include "CADebugMacros.h" +#include +#include +#include + +// An extended exception class that includes the name of the failed operation +class CAXException { +public: + CAXException(const char *operation, OSStatus err) : + mError(err) + { + if (operation == NULL) + mOperation[0] = '\0'; + else if (strlen(operation) >= sizeof(mOperation)) { + memcpy(mOperation, operation, sizeof(mOperation) - 1); + mOperation[sizeof(mOperation) - 1] = '\0'; + } else + strcpy(mOperation, operation); + } + + char *FormatError(char *str) const + { + return FormatError(str, mError); + } + + char mOperation[256]; + const OSStatus mError; + + // ------------------------------------------------- + + typedef void (*WarningHandler)(const char *msg, OSStatus err); + + /*static void Throw(const char *operation, OSStatus err) + { + throw CAXException(operation, err); + }*/ + + static char *FormatError(char *str, OSStatus error) + { + // see if it appears to be a 4-char-code + *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); + if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { + str[0] = str[5] = '\''; + str[6] = '\0'; + } else + // no, format it as an integer + sprintf(str, "%d", (int)error); + return str; + } + + static void Warning(const char *s, OSStatus error) + { + if (sWarningHandler) + (*sWarningHandler)(s, error); + } + + static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } +private: + static WarningHandler sWarningHandler; +}; + +#if DEBUG || CoreAudio_Debug + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), operation);\ + STOP; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + char __buf[12]; \ + DebugMessageN2("error %s: %s\n", CAXException::FormatError(__buf, __err), #error);\ + STOP; \ + } \ + } while (0) + +#else + #define XThrowIfError(error, operation) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XThrowIf(condition, error, operation) \ + do { \ + if (condition) { \ + OSStatus __err = error; \ + throw CAXException(operation, __err); \ + } \ + } while (0) + + #define XRequireNoError(error, label) \ + do { \ + OSStatus __err = error; \ + if (__err) { \ + goto label; \ + } \ + } while (0) + + #define XAssertNoError(error) \ + do { \ + /*OSStatus __err =*/ error; \ + } while (0) +#endif + +#define XThrow(error, operation) XThrowIf(true, error, operation) +#define XThrowIfErr(error) XThrowIfError(error, #error) + +#endif // __CAXException_h__ diff --git a/iPhoneMultichannelMixerTest/images/Icon-72.png b/iPhoneMultichannelMixerTest/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/Icon-72.png differ diff --git a/iPhoneMultichannelMixerTest/images/Icon-Small-50.png b/iPhoneMultichannelMixerTest/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/Icon-Small-50.png differ diff --git a/iPhoneMultichannelMixerTest/images/Icon-Small.png b/iPhoneMultichannelMixerTest/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/Icon-Small.png differ diff --git a/iPhoneMultichannelMixerTest/images/Icon-Small@2x.png b/iPhoneMultichannelMixerTest/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/Icon-Small@2x.png differ diff --git a/iPhoneMultichannelMixerTest/images/Icon.png b/iPhoneMultichannelMixerTest/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/Icon.png differ diff --git a/iPhoneMultichannelMixerTest/images/Icon@2x.png b/iPhoneMultichannelMixerTest/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/Icon@2x.png differ diff --git a/iPhoneMultichannelMixerTest/images/iTunesArtwork b/iPhoneMultichannelMixerTest/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/iPhoneMultichannelMixerTest/images/iTunesArtwork differ diff --git a/iPhoneMultichannelMixerTest/main.m b/iPhoneMultichannelMixerTest/main.m new file mode 100644 index 0000000..ee8a5bf --- /dev/null +++ b/iPhoneMultichannelMixerTest/main.m @@ -0,0 +1,56 @@ +/* + File: main.m + Abstract: The application main. + Version: 1.1 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/oalTouch.zip b/oalTouch.zip new file mode 100644 index 0000000..cc766f4 Binary files /dev/null and b/oalTouch.zip differ diff --git a/oalTouch/Classes/MyOpenALSupport.c b/oalTouch/Classes/MyOpenALSupport.c new file mode 100644 index 0000000..7780480 --- /dev/null +++ b/oalTouch/Classes/MyOpenALSupport.c @@ -0,0 +1,140 @@ +/* + + File: MyOpenALSupport.c +Abstract: OpenAL-related support functions + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#include "MyOpenALSupport.h" + +ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq) +{ + static alBufferDataStaticProcPtr proc = NULL; + + if (proc == NULL) { + proc = (alBufferDataStaticProcPtr) alcGetProcAddress(NULL, (const ALCchar*) "alBufferDataStatic"); + } + + if (proc) + proc(bid, format, data, size, freq); + + return; +} + +void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate) +{ + OSStatus err = noErr; + SInt64 theFileLengthInFrames = 0; + AudioStreamBasicDescription theFileFormat; + UInt32 thePropertySize = sizeof(theFileFormat); + ExtAudioFileRef extRef = NULL; + void* theData = NULL; + AudioStreamBasicDescription theOutputFormat; + + // Open a file with ExtAudioFileOpen() + err = ExtAudioFileOpenURL(inFileURL, &extRef); + if(err) { printf("MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", err); goto Exit; } + + // Get the audio data format + err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); + if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", err); goto Exit; } + if (theFileFormat.mChannelsPerFrame > 2) { printf("MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); goto Exit;} + + // Set the client format to 16 bit signed integer (native-endian) data + // Maintain the channel count and sample rate of the original source format + theOutputFormat.mSampleRate = theFileFormat.mSampleRate; + theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame; + + theOutputFormat.mFormatID = kAudioFormatLinearPCM; + theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame; + theOutputFormat.mFramesPerPacket = 1; + theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame; + theOutputFormat.mBitsPerChannel = 16; + theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; + + // Set the desired client (output) data format + err = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat); + if(err) { printf("MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", err); goto Exit; } + + // Get the total frame count + thePropertySize = sizeof(theFileLengthInFrames); + err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); + if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", err); goto Exit; } + + // Read all the data into memory + UInt32 dataSize = theFileLengthInFrames * theOutputFormat.mBytesPerFrame;; + theData = malloc(dataSize); + if (theData) + { + AudioBufferList theDataBuffer; + theDataBuffer.mNumberBuffers = 1; + theDataBuffer.mBuffers[0].mDataByteSize = dataSize; + theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame; + theDataBuffer.mBuffers[0].mData = theData; + + // Read the data into an AudioBufferList + err = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer); + if(err == noErr) + { + // success + *outDataSize = (ALsizei)dataSize; + *outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; + *outSampleRate = (ALsizei)theOutputFormat.mSampleRate; + } + else + { + // failure + free (theData); + theData = NULL; // make sure to return NULL + printf("MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", err); goto Exit; + } + } + +Exit: + // Dispose the ExtAudioFileRef, it is no longer needed + if (extRef) ExtAudioFileDispose(extRef); + return theData; +} + diff --git a/oalTouch/Classes/MyOpenALSupport.h b/oalTouch/Classes/MyOpenALSupport.h new file mode 100755 index 0000000..7b13bd1 --- /dev/null +++ b/oalTouch/Classes/MyOpenALSupport.h @@ -0,0 +1,60 @@ +/* + + File: MyOpenALSupport.h +Abstract: OpenAL-related support functions + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import +#import +#import +#import + +typedef ALvoid AL_APIENTRY (*alBufferDataStaticProcPtr) (const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq); +ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq); + +void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate); + + diff --git a/oalTouch/Classes/oalPlayback.h b/oalTouch/Classes/oalPlayback.h new file mode 100644 index 0000000..9155c65 --- /dev/null +++ b/oalTouch/Classes/oalPlayback.h @@ -0,0 +1,97 @@ +/* + + File: oalPlayback.h +Abstract: An Obj-C class which wraps an OpenAL playback environment + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import +#import + +#import +#import + +#define kDefaultDistance 25.0 + +@interface oalPlayback : NSObject +{ + IBOutlet UISwitch* musicSwitch; + + ALuint source; + ALuint buffer; + ALCcontext* context; + ALCdevice* device; + + void* data; + CGPoint sourcePos; + CGPoint listenerPos; + CGFloat listenerRotation; + ALfloat sourceVolume; + BOOL isPlaying; + BOOL wasInterrupted; + + NSURL* bgURL; + AVAudioPlayer* bgPlayer; + UInt32 iPodIsPlaying; + +} + +@property (nonatomic, assign) BOOL isPlaying; // Whether the sound is playing or stopped +@property (nonatomic, assign) UInt32 iPodIsPlaying; // Whether the iPod is playing +@property (nonatomic, assign) BOOL wasInterrupted; // Whether playback was interrupted by the system +@property (nonatomic, assign) CGPoint sourcePos; // The coordinates of the sound source +@property (nonatomic, assign) CGPoint listenerPos; // The coordinates of the listener +@property (nonatomic, assign) CGFloat listenerRotation; // The rotation angle of the listener in radians + +- (IBAction)toggleMusic:(UISwitch*)sender; +- (void)checkForMusic; + +- (void)initOpenAL; +- (void)teardownOpenAL; + +- (void)startSound; +- (void)stopSound; + +@end diff --git a/oalTouch/Classes/oalPlayback.m b/oalTouch/Classes/oalPlayback.m new file mode 100644 index 0000000..4e0bfa3 --- /dev/null +++ b/oalTouch/Classes/oalPlayback.m @@ -0,0 +1,380 @@ +/* + + File: oalPlayback.m +Abstract: An Obj-C class which wraps an OpenAL playback environment + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "oalPlayback.h" +#import "MyOpenALSupport.h" + + +@implementation oalPlayback + +@synthesize isPlaying; +@synthesize wasInterrupted; +@synthesize listenerRotation; +@synthesize iPodIsPlaying; + +#pragma mark Object Init / Maintenance +void interruptionListener( void * inClientData, + UInt32 inInterruptionState) +{ + oalPlayback* THIS = (oalPlayback*)inClientData; + if (inInterruptionState == kAudioSessionBeginInterruption) + { + alcMakeContextCurrent(NULL); + if ([THIS isPlaying]) { + THIS.wasInterrupted = YES; + } + } + else if (inInterruptionState == kAudioSessionEndInterruption) + { + OSStatus result = AudioSessionSetActive(true); + if (result) NSLog(@"Error setting audio session active! %d\n", result); + + alcMakeContextCurrent(THIS->context); + + if (THIS.wasInterrupted) + { + [THIS startSound]; + THIS.wasInterrupted = NO; + } + } +} + +void RouteChangeListener( void * inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void * inData) +{ + CFDictionaryRef dict = (CFDictionaryRef)inData; + + CFStringRef oldRoute = CFDictionaryGetValue(dict, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute)); + + UInt32 size = sizeof(CFStringRef); + + CFStringRef newRoute; + OSStatus result = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute); + + NSLog(@"result: %d Route changed from %@ to %@", result, oldRoute, newRoute); +} + +- (id)init +{ + if (self = [super init]) { + // Start with our sound source slightly in front of the listener + sourcePos = CGPointMake(0., -70.); + + // Put the listener in the center of the stage + listenerPos = CGPointMake(0., 0.); + + // Listener looking straight ahead + listenerRotation = 0.; + + // setup our audio session + OSStatus result = AudioSessionInitialize(NULL, NULL, interruptionListener, self); + if (result) NSLog(@"Error initializing audio session! %d\n", result); + else { + // if there is other audio playing, we don't want to play the background music + UInt32 size = sizeof(iPodIsPlaying); + result = AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &size, &iPodIsPlaying); + if (result) NSLog(@"Error getting other audio playing property! %d", result); + + // if the iPod is playing, use the ambient category to mix with it + // otherwise, use solo ambient to get the hardware for playing the app background track + UInt32 category = (iPodIsPlaying) ? kAudioSessionCategory_AmbientSound : kAudioSessionCategory_SoloAmbientSound; + + result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category); + if (result) NSLog(@"Error setting audio session category! %d\n", result); + + result = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self); + if (result) NSLog(@"Couldn't add listener: %d", result); + + result = AudioSessionSetActive(true); + if (result) NSLog(@"Error setting audio session active! %d\n", result); + } + + bgURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:@"background" ofType:@"m4a"]]; + bgPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:bgURL error:nil]; + + wasInterrupted = NO; + + // Initialize our OpenAL environment + [self initOpenAL]; + } + + return self; +} + +- (void)checkForMusic +{ + if (iPodIsPlaying) { + //the iPod is playing, so we should disable the background music switch + NSLog(@"Disabling background music, iPod is active"); + musicSwitch.enabled = NO; + } + else { + musicSwitch.enabled = YES; + } +} + +- (void)dealloc +{ + [super dealloc]; + + [self teardownOpenAL]; + [bgURL release]; + [bgPlayer release]; +} + +#pragma mark AVAudioPlayer + +- (IBAction)toggleMusic:(UISwitch*)sender { + NSLog(@"togging music %s", sender.on ? "on" : "off"); + + if (bgPlayer) { + + if (sender.on) { + [bgPlayer play]; + } + else { + [bgPlayer stop]; + } + } +} + +#pragma mark OpenAL + +- (void) initBuffer +{ + ALenum error = AL_NO_ERROR; + ALenum format; + ALsizei size; + ALsizei freq; + + NSBundle* bundle = [NSBundle mainBundle]; + + // get some audio data from a wave file + CFURLRef fileURL = (CFURLRef)[[NSURL fileURLWithPath:[bundle pathForResource:@"sound" ofType:@"caf"]] retain]; + + if (fileURL) + { + data = MyGetOpenALAudioData(fileURL, &size, &format, &freq); + CFRelease(fileURL); + + if((error = alGetError()) != AL_NO_ERROR) { + NSLog(@"error loading sound: %x\n", error); + exit(1); + } + + // use the static buffer data API + alBufferDataStaticProc(buffer, format, data, size, freq); + + if((error = alGetError()) != AL_NO_ERROR) { + NSLog(@"error attaching audio to buffer: %x\n", error); + } + } + else + NSLog(@"Could not find file!\n"); +} + +- (void) initSource +{ + ALenum error = AL_NO_ERROR; + alGetError(); // Clear the error + + // Turn Looping ON + alSourcei(source, AL_LOOPING, AL_TRUE); + + // Set Source Position + float sourcePosAL[] = {sourcePos.x, kDefaultDistance, sourcePos.y}; + alSourcefv(source, AL_POSITION, sourcePosAL); + + // Set Source Reference Distance + alSourcef(source, AL_REFERENCE_DISTANCE, 50.0f); + + // attach OpenAL Buffer to OpenAL Source + alSourcei(source, AL_BUFFER, buffer); + + if((error = alGetError()) != AL_NO_ERROR) { + NSLog(@"Error attaching buffer to source: %x\n", error); + exit(1); + } +} + + +- (void)initOpenAL +{ + ALenum error; + + // Create a new OpenAL Device + // Pass NULL to specify the system’s default output device + device = alcOpenDevice(NULL); + if (device != NULL) + { + // Create a new OpenAL Context + // The new context will render to the OpenAL Device just created + context = alcCreateContext(device, 0); + if (context != NULL) + { + // Make the new context the Current OpenAL Context + alcMakeContextCurrent(context); + + // Create some OpenAL Buffer Objects + alGenBuffers(1, &buffer); + if((error = alGetError()) != AL_NO_ERROR) { + NSLog(@"Error Generating Buffers: %x", error); + exit(1); + } + + // Create some OpenAL Source Objects + alGenSources(1, &source); + if(alGetError() != AL_NO_ERROR) + { + NSLog(@"Error generating sources! %x\n", error); + exit(1); + } + + } + } + // clear any errors + alGetError(); + + [self initBuffer]; + [self initSource]; +} + +- (void)teardownOpenAL +{ + // Delete the Sources + alDeleteSources(1, &source); + // Delete the Buffers + alDeleteBuffers(1, &buffer); + + //Release context + alcDestroyContext(context); + //Close device + alcCloseDevice(device); +} + +#pragma mark Play / Pause + +- (void)startSound +{ + ALenum error; + + NSLog(@"Start!\n"); + // Begin playing our source file + alSourcePlay(source); + if((error = alGetError()) != AL_NO_ERROR) { + NSLog(@"error starting source: %x\n", error); + } else { + // Mark our state as playing (the view looks at this) + self.isPlaying = YES; + } +} + +- (void)stopSound +{ + ALenum error; + + NSLog(@"Stop!!\n"); + // Stop playing our source file + alSourceStop(source); + if((error = alGetError()) != AL_NO_ERROR) { + NSLog(@"error stopping source: %x\n", error); + } else { + // Mark our state as not playing (the view looks at this) + self.isPlaying = NO; + } +} + +#pragma mark Setters / Getters + +- (CGPoint)sourcePos +{ + return sourcePos; +} + +- (void)setSourcePos:(CGPoint)SOURCEPOS +{ + sourcePos = SOURCEPOS; + float sourcePosAL[] = {sourcePos.x, kDefaultDistance, sourcePos.y}; + // Move our audio source coordinates + alSourcefv(source, AL_POSITION, sourcePosAL); +} + + + +- (CGPoint)listenerPos +{ + return listenerPos; +} + +- (void)setListenerPos:(CGPoint)LISTENERPOS +{ + listenerPos = LISTENERPOS; + float listenerPosAL[] = {listenerPos.x, 0., listenerPos.y}; + // Move our listener coordinates + alListenerfv(AL_POSITION, listenerPosAL); +} + + + +- (CGFloat)listenerRotation +{ + return listenerRotation; +} + +- (void)setListenerRotation:(CGFloat)radians +{ + listenerRotation = radians; + float ori[] = {cos(radians + M_PI_2), sin(radians + M_PI_2), 0., 0., 0., 1.}; + // Set our listener orientation (rotation) + alListenerfv(AL_ORIENTATION, ori); +} + +@end diff --git a/oalTouch/Classes/oalSpatialView.h b/oalTouch/Classes/oalSpatialView.h new file mode 100644 index 0000000..928c976 --- /dev/null +++ b/oalTouch/Classes/oalSpatialView.h @@ -0,0 +1,90 @@ +/* + + File: oalSpatialView.h +Abstract: A visual representation of our sound stage + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import +#import +#import + +#define kTouchDistanceThreshhold 45. + +// A function to bring an outlying point into the bounds of a rectangle, +// so that it is as close as possible to its original outlying position. +static inline CGPoint CGPointWithinBounds(CGPoint point, CGRect bounds) +{ + CGPoint ret = point; + if (ret.x < CGRectGetMinX(bounds)) ret.x = CGRectGetMinX(bounds); + else if (ret.x > CGRectGetMaxX(bounds)) ret.x = CGRectGetMaxX(bounds); + if (ret.y < CGRectGetMinY(bounds)) ret.y = CGRectGetMinY(bounds); + else if (ret.y > CGRectGetMaxY(bounds)) ret.y = CGRectGetMaxY(bounds); + return ret; +} + +@class oalPlayback; + +@interface oalSpatialView : UIView +{ + // Reference to our playback object, wired up in IB + IBOutlet oalPlayback *playback; + + // Images for the speaker in its on and off state + CGImageRef _speaker_off; + CGImageRef _speaker_on; + + // Various layers we use to represent things in the sound stage + CALayer *_draggingLayer; + CALayer *_speakerLayer; + CALayer *_listenerLayer; + CALayer *_instructionsLayer; +} + +- (void)initializeContents; + +- (void)layoutContents; + +@end diff --git a/oalTouch/Classes/oalSpatialView.m b/oalTouch/Classes/oalSpatialView.m new file mode 100644 index 0000000..1a395fc --- /dev/null +++ b/oalTouch/Classes/oalSpatialView.m @@ -0,0 +1,285 @@ +/* + + File: oalSpatialView.m +Abstract: A visual representation of our sound stage + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "oalSpatialView.h" + +#import "oalPlayback.h" + +CGPathRef CreateRoundedRectPath(CGRect RECT, CGFloat cornerRadius) +{ + CGMutablePathRef path; + path = CGPathCreateMutable(); + + double maxRad = MAX(CGRectGetHeight(RECT) / 2., CGRectGetWidth(RECT) / 2.); + + if (cornerRadius > maxRad) cornerRadius = maxRad; + + CGPoint bl, tl, tr, br; + + bl = tl = tr = br = RECT.origin; + tl.y += RECT.size.height; + tr.y += RECT.size.height; + tr.x += RECT.size.width; + br.x += RECT.size.width; + + CGPathMoveToPoint(path, NULL, bl.x + cornerRadius, bl.y); + CGPathAddArcToPoint(path, NULL, bl.x, bl.y, bl.x, bl.y + cornerRadius, cornerRadius); + CGPathAddLineToPoint(path, NULL, tl.x, tl.y - cornerRadius); + CGPathAddArcToPoint(path, NULL, tl.x, tl.y, tl.x + cornerRadius, tl.y, cornerRadius); + CGPathAddLineToPoint(path, NULL, tr.x - cornerRadius, tr.y); + CGPathAddArcToPoint(path, NULL, tr.x, tr.y, tr.x, tr.y - cornerRadius, cornerRadius); + CGPathAddLineToPoint(path, NULL, br.x, br.y + cornerRadius); + CGPathAddArcToPoint(path, NULL, br.x, br.y, br.x - cornerRadius, br.y, cornerRadius); + + CGPathCloseSubpath(path); + + CGPathRef ret; + ret = CGPathCreateCopy(path); + CGPathRelease(path); + return ret; +} + +@implementation oalSpatialView + +#pragma mark Object Init / Maintenance + +- (id)initWithCoder:(NSCoder *)coder +{ + if (self = [super initWithCoder:coder]) { + [self initializeContents]; + } + return self; +} + +- (void)dealloc +{ + [playback removeObserver:self forKeyPath:@"sourcePos"]; + [playback removeObserver:self forKeyPath:@"isPlaying"]; + [playback removeObserver:self forKeyPath:@"listenerPos"]; + [playback removeObserver:self forKeyPath:@"listenerRotation"]; + + CGImageRelease(_speaker_off); + CGImageRelease(_speaker_on); + + [super dealloc]; +} + +- (void)awakeFromNib +{ + // We want to register as an observer for the oalPlayback environment, so we'll get notified when things + // change, i.e. source position, listener position. + [playback addObserver:self forKeyPath:@"sourcePos" options:NSKeyValueObservingOptionNew context:NULL]; + [playback addObserver:self forKeyPath:@"isPlaying" options:NSKeyValueObservingOptionNew context:NULL]; + [playback addObserver:self forKeyPath:@"listenerPos" options:NSKeyValueObservingOptionNew context:NULL]; + [playback addObserver:self forKeyPath:@"listenerRotation" options:NSKeyValueObservingOptionNew context:NULL]; + + [playback checkForMusic]; + [self layoutContents]; +} + + +#pragma mark KVO + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // Generally, we just call [self layoutContents] whenever something changes in the oalPlayback environment. + // When the sound sound source is turned on or off, we also change the image for the speaker to either show + // or hide the sound waves. + + if ( (object == playback) && ([keyPath isEqualToString:@"sourcePos"]) ) { + [self layoutContents]; + } + else if ( (object == playback) && [keyPath isEqualToString:@"isPlaying"] ) { + [self layoutContents]; + if (playback.isPlaying) + _speakerLayer.contents = (id)_speaker_on; + else + _speakerLayer.contents = (id)_speaker_off; + } + else if ( (object == playback) && ([keyPath isEqualToString:@"listenerPos"]) ) { + [self layoutContents]; + } else if ( (object == playback) && ([keyPath isEqualToString:@"listenerRotation"]) ) { + [self layoutContents]; + } else { + [NSException raise:@"Error" format:@"%@ observing unexpected keypath %@ for object %@", self, keyPath, object]; + } +} + + + +#pragma mark View contents + +- (void)initializeContents +{ + // Load images for the two speaker states and retain them, because we'll be switching between them + _speaker_off = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"speaker_off" ofType:@"png"]] CGImage]; + CGImageRetain(_speaker_off); + _speaker_on = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"speaker_on" ofType:@"png"]] CGImage]; + + CGImageRetain(_speaker_on); + + CGImageRef listenerImg = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"listener" ofType:@"png"]] CGImage]; + CGImageRef instructionsImg = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"instructions" ofType:@"png"]] CGImage]; + + // Set up the CALayer which shows the speaker + _speakerLayer = [CALayer layer]; + _speakerLayer.frame = CGRectMake(0., 0., CGImageGetWidth(_speaker_off), CGImageGetHeight(_speaker_off)); + _speakerLayer.contents = (id)_speaker_off; + + // Set up the CALayer which shows the listener + _listenerLayer = [CALayer layer]; + _listenerLayer.frame = CGRectMake(0., 0., CGImageGetWidth(listenerImg), CGImageGetHeight(listenerImg)); + _listenerLayer.contents = (id)listenerImg; + _listenerLayer.anchorPoint = CGPointMake(0.5, 0.57); + + // Set up the CALayer which shows the instructions + _instructionsLayer = [CALayer layer]; + _instructionsLayer.frame = CGRectMake(0., 0., CGImageGetWidth(instructionsImg), CGImageGetHeight(instructionsImg)); + _instructionsLayer.position = CGPointMake(0., -140.); + _instructionsLayer.contents = (id)instructionsImg; + + // Set a sublayerTransform on our view's layer. This causes (0,0) to be in the center of the view. This transform + // is useful because now our view's coordinates map precisely to our oalPlayback sound environment's coordinates. + CATransform3D trans = CATransform3DMakeTranslation([self frame].size.width / 2., [self frame].size.height / 2., 0.); + self.layer.sublayerTransform = trans; + + // Set the background image for the sound stage + CGImageRef bgImg = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"stagebg" ofType:@"png"]] CGImage]; + self.layer.contents = (id)bgImg; + + // Add our sublayers + [self.layer insertSublayer:_speakerLayer above:self.layer]; + [self.layer insertSublayer:_listenerLayer above:self.layer]; + [self.layer insertSublayer:_instructionsLayer above:self.layer]; + + // Prevent things from drawing outside our layer bounds + self.layer.masksToBounds = YES; +} + +- (void)layoutContents +{ + // layoutContents gets called via KVO whenever properties within our oalPlayback object change + + // Wrap these layer changes in a transaction and set the animation duration to 0 so we don't get implicit animation + [CATransaction begin]; + [CATransaction setValue:[NSNumber numberWithDouble:0.] forKey:kCATransactionAnimationDuration]; + + // Position and rotate the listener + _listenerLayer.position = playback.listenerPos; + _listenerLayer.transform = CATransform3DMakeRotation(playback.listenerRotation, 0., 0., 1.); + + // The speaker gets rotated so that it's always facing the listener + CGFloat rot = atan2(-(playback.sourcePos.x - playback.listenerPos.x), playback.sourcePos.y - playback.listenerPos.y); + + // Rotate and position the speaker + _speakerLayer.position = playback.sourcePos; + _speakerLayer.transform = CATransform3DMakeRotation(rot, 0., 0., 1.); + + [CATransaction commit]; +} + + +#pragma mark Events + +- (void)touchPoint:(CGPoint)pt +{ + if (!(_instructionsLayer.hidden)) _instructionsLayer.hidden = YES; + + if (_draggingLayer == _speakerLayer) playback.sourcePos = pt; + else if (_draggingLayer == _listenerLayer) playback.listenerPos = pt; +} + +- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event +{ + CGPoint pointInView = [[touches anyObject] locationInView:self]; + + // Clip our pointInView to within 5 pixels of any edge, so we can't position objects near or beyond + // the edge of the sound stage + pointInView = CGPointWithinBounds(pointInView, CGRectInset([self bounds], 5., 5.)); + + // Convert the view point to our layer / sound stage coordinate system, which is centered at (0,0) + CGPoint pointInLayer = CGPointMake(pointInView.x - [self frame].size.width / 2., pointInView.y - [self frame].size.height / 2.); + + // Find out if the distance between the touch is within the tolerance threshhold for moving + // the source object or the listener object + if (hypot(playback.sourcePos.x - pointInLayer.x, playback.sourcePos.y - pointInLayer.y) < kTouchDistanceThreshhold) + { + _draggingLayer = _speakerLayer; + } + else if (hypot(playback.listenerPos.x - pointInLayer.x, playback.listenerPos.y - pointInLayer.y) < kTouchDistanceThreshhold) + { + _draggingLayer = _listenerLayer; + } + else + { + _draggingLayer = nil; + } + + // Handle the touch + [self touchPoint:pointInLayer]; +} + +- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event +{ + // Called repeatedly as the touch moves + + CGPoint pointInView = [[touches anyObject] locationInView:self]; + pointInView = CGPointWithinBounds(pointInView, CGRectInset([self bounds], 5., 5.)); + CGPoint pointInLayer = CGPointMake(pointInView.x - [self frame].size.width / 2., pointInView.y - [self frame].size.height / 2.); + [self touchPoint:pointInLayer]; +} + +- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event +{ + _draggingLayer = nil; +} + + + +@end diff --git a/oalTouch/Classes/oalTouchAppDelegate.h b/oalTouch/Classes/oalTouchAppDelegate.h new file mode 100755 index 0000000..9648be2 --- /dev/null +++ b/oalTouch/Classes/oalTouchAppDelegate.h @@ -0,0 +1,70 @@ +/* + + File: oalTouchAppDelegate.h +Abstract: App delegate. Ties everything together, and handles some high-level UI input. + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#import + +@class oalSpatialView; +@class oalPlayback; + +@interface oalTouchAppDelegate : NSObject { + IBOutlet UIWindow* window; + IBOutlet oalSpatialView* view; + IBOutlet oalPlayback* playback; +} + +@property (nonatomic, retain) UIWindow* window; + +@property (nonatomic, retain) oalSpatialView* view; +@property (nonatomic, retain) oalPlayback* playback; + +- (IBAction)playPause:(UIButton*)sender; +- (IBAction)toggleAccelerometer:(UISwitch*)sender; + +@end + diff --git a/oalTouch/Classes/oalTouchAppDelegate.m b/oalTouch/Classes/oalTouchAppDelegate.m new file mode 100755 index 0000000..197bb6b --- /dev/null +++ b/oalTouch/Classes/oalTouchAppDelegate.m @@ -0,0 +1,109 @@ +/* + + File: oalTouchAppDelegate.m +Abstract: App delegate. Ties everything together, and handles some high-level UI input. + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import "oalTouchAppDelegate.h" + +#import "oalPlayback.h" + +@implementation oalTouchAppDelegate + +@synthesize window; +@synthesize view; +@synthesize playback; + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // Get accelerometer updates at 15 hz + [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 15.)]; +} + + +- (void)dealloc +{ + [playback release]; + [view release]; + [window release]; + [super dealloc]; +} + + +- (IBAction)playPause:(UIButton *)sender +{ + // Toggle the playback + + if (playback.isPlaying) [playback stopSound]; + else [playback startSound]; + sender.selected = playback.isPlaying; +} + +- (IBAction)toggleAccelerometer:(UISwitch *)sender +{ + // Toggle the accelerometer + // Note: With the accelerometer on, the device should be held vertically, not laid down flat. + // As the device is rotated, the orientation of the listener will adjust so as as to be looking upward. + if (sender.on) + { + [[UIAccelerometer sharedAccelerometer] setDelegate:self]; + } else { + [[UIAccelerometer sharedAccelerometer] setDelegate:nil]; + } +} + +- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration +{ + CGFloat zRot; + + // Find out the Z rotation of the device by doing some trig on the accelerometer values for X and Y + zRot = (atan2(acceleration.x, acceleration.y) + M_PI); + + // Set our listener's rotation + playback.listenerRotation = zRot; +} + +@end diff --git a/oalTouch/Info.plist b/oalTouch/Info.plist new file mode 100755 index 0000000..e44adc9 --- /dev/null +++ b/oalTouch/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + Icon.png + Icon@2x.png + Icon-72.png + Icon-Small.png + Icon-Small-50.png + Icon-Small@2x.png + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.8 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarStyle + UIStatusBarStyleBlackOpaque + + diff --git a/oalTouch/ReadMe.txt b/oalTouch/ReadMe.txt new file mode 100644 index 0000000..f9a4afa --- /dev/null +++ b/oalTouch/ReadMe.txt @@ -0,0 +1,75 @@ +oalTouch + +=========================================================================== +DESCRIPTION: + +oalTouch demonstrates basic use of OpenAL, Audio File Services, Core Animation, and Core Graphics Services on the iPhone for manipulating sound in a spatial environment. + +The code in oalTouch uses OpenAL to play an audio file containing uncompressed (PCM) audio data. The application uses Audio File Services to manage audio file data reading. The application also uses Audio Session Services to manage interruptions (as described in Core Audio Overview). + +This application shows how to: + + * Set up the environment for OpenAL usage by creating oalDevice and oalContext objects. + * Read data from an audio file using the ExtendedAudioFile API and attach into an OpenAL buffer object. + * Create an OpenAL source object and attach a buffer object to it. + * Manipulate various properties of OpenAL source and listener objects. + * Use Core Animation layers to rotate and move image objects based on user input. + * Use Audio Session Services to register an interruption callback. + * Use Audio Session Services to set appropriate audio session categories for recording and playback. + * Use Audio Session Services to pause playback upon receiving an interruption, and to then resume playback if the interruption ends. + * Use UIAccelerometer Services to provide user input from device movement. + * Use UISlider objects as switches. + +oalTouch does not demonstrate how to play multiple source objects, nor does it provide more advanced OpenAL usage. + + +=========================================================================== +RELATED INFORMATION: + +Core Audio Overview, June 2008 + + +=========================================================================== +SPECIAL CONSIDERATIONS: + +oalTouch demonstrates use of the OpenAL framework for positional audio, and as such is best suited for a stereo listening environment (headphones, external speakers, etc.) + + +=========================================================================== +BUILD REQUIREMENTS: + +iOS 4.0 SDK + + +=========================================================================== +RUNTIME REQUIREMENTS: + +iPhone OS 3.2 and later + + +=========================================================================== +PACKAGING LIST: + +MyOpenALSupport.h + +MyOpenALSupport.h provides helper functions for various common OpenAL-related tasks (opening files for data read, creating devices and context objects, etc.) + +oalPlayback.h +oalPlayback.m + +The oalPlayback class defines the audio playback object for the application. The object responds to and manages of the OpenAL environment + + +oalTouchAppDelegate.h +oalTouchAppDelegate.m + +The oalTouchAppDelegate class defines the application delegate object, responsible for handling accelerometer input and adding the application's view to the application window. + + +oalSpatialView.h +oalSpatialView.m + +The oalSpatialView class defines the view object, responsible for handling user interaction and displaying the representation of the OpenAL environment. + +================================================================================ +Copyright (C) 2008-2010 Apple Inc. All rights reserved. \ No newline at end of file diff --git a/oalTouch/background.m4a b/oalTouch/background.m4a new file mode 100644 index 0000000..3019cda Binary files /dev/null and b/oalTouch/background.m4a differ diff --git a/oalTouch/en.lproj/MainWindow.xib b/oalTouch/en.lproj/MainWindow.xib new file mode 100755 index 0000000..7af006d --- /dev/null +++ b/oalTouch/en.lproj/MainWindow.xib @@ -0,0 +1,468 @@ + + + + 512 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1292 + + YES + + + 1292 + {{20, 40}, {280, 360}} + + + 3 + MSAwAA + + 2 + + + YES + NO + + + + 1292 + {{20, 416}, {53, 47}} + + + 1 + MCAwIDAgMAA + + NO + NO + 0 + 0 + + Helvetica + 2.200000e+01 + 16 + + 1 + + 3 + MAA + + + + + + + + NSImage + play.png + + + + NSImage + pause.png + + + + + + 1292 + {{212, 436}, {88, 27}} + + NO + YES + YES + 0 + 0 + + + + 1292 + {{209, 408}, {94, 21}} + + NO + YES + NO + Tilt Listener + + 1 + MSAxIDEAA + + + 1 + 1.000000e+01 + + + + 1316 + {{98, 436}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 1292 + {{98, 407}, {94, 21}} + + NO + YES + NO + Music + + + 1 + 1.000000e+01 + 1 + + + + {320, 480} + + + NO + NO + YES + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + playPause: + + + 7 + + 21 + + + + toggleAccelerometer: + + + 13 + + 22 + + + + playback + + + + 23 + + + + view + + + + 24 + + + + toggleMusic: + + + 13 + + 33 + + + + musicSwitch + + + + 34 + + + + playback + + + + 35 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 8 + + + YES + + + + + 13 + + + + + 9 + + + + + 17 + + + + + 18 + + + + + 25 + + + + + 27 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 13.CustomClassName + 13.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 2.IBUserGuides + 25.IBPluginDependency + 27.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + UIApplication + UIResponder + oalPlayback + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{77, 184}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + oalTouchAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + oalSpatialView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 35 + + + + YES + + oalPlayback + NSObject + + toggleMusic: + UISwitch + + + musicSwitch + UISwitch + + + IBProjectSource + Classes/oalPlayback.h + + + + oalSpatialView + UIView + + playback + oalPlayback + + + IBProjectSource + Classes/oalSpatialView.h + + + + oalTouchAppDelegate + NSObject + + YES + + YES + playPause: + toggleAccelerometer: + + + YES + UIButton + UISwitch + + + + YES + + YES + playback + view + window + + + YES + oalPlayback + oalSpatialView + UIWindow + + + + IBProjectSource + Classes/oalTouchAppDelegate.h + + + + + 0 + oalTouch.xcodeproj + 3 + 3.0 + + diff --git a/oalTouch/images/Default.png b/oalTouch/images/Default.png new file mode 100755 index 0000000..c536805 Binary files /dev/null and b/oalTouch/images/Default.png differ diff --git a/oalTouch/images/Icon-72.png b/oalTouch/images/Icon-72.png new file mode 100644 index 0000000..b154505 Binary files /dev/null and b/oalTouch/images/Icon-72.png differ diff --git a/oalTouch/images/Icon-Small-50.png b/oalTouch/images/Icon-Small-50.png new file mode 100644 index 0000000..e7dbbf4 Binary files /dev/null and b/oalTouch/images/Icon-Small-50.png differ diff --git a/oalTouch/images/Icon-Small.png b/oalTouch/images/Icon-Small.png new file mode 100644 index 0000000..675c18f Binary files /dev/null and b/oalTouch/images/Icon-Small.png differ diff --git a/oalTouch/images/Icon-Small@2x.png b/oalTouch/images/Icon-Small@2x.png new file mode 100644 index 0000000..e740019 Binary files /dev/null and b/oalTouch/images/Icon-Small@2x.png differ diff --git a/oalTouch/images/Icon.png b/oalTouch/images/Icon.png new file mode 100644 index 0000000..dfc83b7 Binary files /dev/null and b/oalTouch/images/Icon.png differ diff --git a/oalTouch/images/Icon@2x.png b/oalTouch/images/Icon@2x.png new file mode 100644 index 0000000..21e17cc Binary files /dev/null and b/oalTouch/images/Icon@2x.png differ diff --git a/oalTouch/images/iTunesArtwork b/oalTouch/images/iTunesArtwork new file mode 100644 index 0000000..6ad7a1f Binary files /dev/null and b/oalTouch/images/iTunesArtwork differ diff --git a/oalTouch/images/instructions.png b/oalTouch/images/instructions.png new file mode 100644 index 0000000..ccfe6df Binary files /dev/null and b/oalTouch/images/instructions.png differ diff --git a/oalTouch/images/listener.png b/oalTouch/images/listener.png new file mode 100644 index 0000000..236747e Binary files /dev/null and b/oalTouch/images/listener.png differ diff --git a/oalTouch/images/pause.png b/oalTouch/images/pause.png new file mode 100644 index 0000000..5d597b4 Binary files /dev/null and b/oalTouch/images/pause.png differ diff --git a/oalTouch/images/play.png b/oalTouch/images/play.png new file mode 100644 index 0000000..916c129 Binary files /dev/null and b/oalTouch/images/play.png differ diff --git a/oalTouch/images/speaker_off.png b/oalTouch/images/speaker_off.png new file mode 100644 index 0000000..9b14b1e Binary files /dev/null and b/oalTouch/images/speaker_off.png differ diff --git a/oalTouch/images/speaker_on.png b/oalTouch/images/speaker_on.png new file mode 100644 index 0000000..9b09a28 Binary files /dev/null and b/oalTouch/images/speaker_on.png differ diff --git a/oalTouch/images/stagebg.png b/oalTouch/images/stagebg.png new file mode 100644 index 0000000..abd6b11 Binary files /dev/null and b/oalTouch/images/stagebg.png differ diff --git a/oalTouch/main.m b/oalTouch/main.m new file mode 100755 index 0000000..262cf22 --- /dev/null +++ b/oalTouch/main.m @@ -0,0 +1,58 @@ +/* + + File: main.m +Abstract: main file + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + +*/ + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/oalTouch/oalTouch.xcodeproj/project.pbxproj b/oalTouch/oalTouch.xcodeproj/project.pbxproj new file mode 100755 index 0000000..4e6f041 --- /dev/null +++ b/oalTouch/oalTouch.xcodeproj/project.pbxproj @@ -0,0 +1,374 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 18352A7211CFE5A30089BE2C /* background.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7011CFE5A30089BE2C /* background.m4a */; }; + 18352A7311CFE5A30089BE2C /* sound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7111CFE5A30089BE2C /* sound.caf */; }; + 18352A7D11CFE5AA0089BE2C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7411CFE5AA0089BE2C /* Default.png */; }; + 18352A7F11CFE5AA0089BE2C /* instructions.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7611CFE5AA0089BE2C /* instructions.png */; }; + 18352A8011CFE5AA0089BE2C /* listener.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7711CFE5AA0089BE2C /* listener.png */; }; + 18352A8111CFE5AA0089BE2C /* pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7811CFE5AA0089BE2C /* pause.png */; }; + 18352A8211CFE5AA0089BE2C /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7911CFE5AA0089BE2C /* play.png */; }; + 18352A8311CFE5AA0089BE2C /* speaker_off.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7A11CFE5AA0089BE2C /* speaker_off.png */; }; + 18352A8411CFE5AA0089BE2C /* speaker_on.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7B11CFE5AA0089BE2C /* speaker_on.png */; }; + 18352A8511CFE5AA0089BE2C /* stagebg.png in Resources */ = {isa = PBXBuildFile; fileRef = 18352A7C11CFE5AA0089BE2C /* stagebg.png */; }; + 18352A9911CFE75F0089BE2C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18352A9711CFE75F0089BE2C /* MainWindow.xib */; }; + 18DA37AF11D5508E00975162 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37A811D5508E00975162 /* Icon-72.png */; }; + 18DA37B011D5508E00975162 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37A911D5508E00975162 /* Icon-Small-50.png */; }; + 18DA37B111D5508E00975162 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37AA11D5508E00975162 /* Icon-Small.png */; }; + 18DA37B211D5508E00975162 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37AB11D5508E00975162 /* Icon-Small@2x.png */; }; + 18DA37B411D5508E00975162 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37AD11D5508E00975162 /* Icon@2x.png */; }; + 18DA37B511D5508E00975162 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37AE11D5508E00975162 /* iTunesArtwork */; }; + 18DA37F811D5529300975162 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18DA37F711D5529300975162 /* Icon.png */; }; + 1D3623260D0F684500981E51 /* oalTouchAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* oalTouchAppDelegate.m */; }; + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + A192CEE10DDBB40300D03FCA /* oalSpatialView.m in Sources */ = {isa = PBXBuildFile; fileRef = A192CEE00DDBB40300D03FCA /* oalSpatialView.m */; }; + A192CEE60DDBB43B00D03FCA /* oalPlayback.m in Sources */ = {isa = PBXBuildFile; fileRef = A192CEE50DDBB43B00D03FCA /* oalPlayback.m */; }; + A192CF1A0DDBB6C900D03FCA /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A192CF190DDBB6C900D03FCA /* AudioToolbox.framework */; }; + A192CF1E0DDBB6D400D03FCA /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A192CF1D0DDBB6D400D03FCA /* OpenAL.framework */; }; + A1E88B190DDCA844008449A6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E88B180DDCA844008449A6 /* QuartzCore.framework */; }; + F78602FE0DF86FCD00A013EA /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F78602FD0DF86FCD00A013EA /* MediaPlayer.framework */; }; + F79463430ED73BE70014B1E8 /* MyOpenALSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = F79463420ED73BE70014B1E8 /* MyOpenALSupport.c */; }; + F79D54850FC4B9A500350F08 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F79D54840FC4B9A500350F08 /* AVFoundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 18352A7011CFE5A30089BE2C /* background.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = background.m4a; sourceTree = ""; }; + 18352A7111CFE5A30089BE2C /* sound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = sound.caf; sourceTree = ""; }; + 18352A7411CFE5AA0089BE2C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; }; + 18352A7611CFE5AA0089BE2C /* instructions.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = instructions.png; path = images/instructions.png; sourceTree = ""; }; + 18352A7711CFE5AA0089BE2C /* listener.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = listener.png; path = images/listener.png; sourceTree = ""; }; + 18352A7811CFE5AA0089BE2C /* pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause.png; path = images/pause.png; sourceTree = ""; }; + 18352A7911CFE5AA0089BE2C /* play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = play.png; path = images/play.png; sourceTree = ""; }; + 18352A7A11CFE5AA0089BE2C /* speaker_off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off.png; path = images/speaker_off.png; sourceTree = ""; }; + 18352A7B11CFE5AA0089BE2C /* speaker_on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on.png; path = images/speaker_on.png; sourceTree = ""; }; + 18352A7C11CFE5AA0089BE2C /* stagebg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = stagebg.png; path = images/stagebg.png; sourceTree = ""; }; + 18352A9811CFE75F0089BE2C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; + 18DA37A811D5508E00975162 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "images/Icon-72.png"; sourceTree = ""; }; + 18DA37A911D5508E00975162 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "images/Icon-Small-50.png"; sourceTree = ""; }; + 18DA37AA11D5508E00975162 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "images/Icon-Small.png"; sourceTree = ""; }; + 18DA37AB11D5508E00975162 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "images/Icon-Small@2x.png"; sourceTree = ""; }; + 18DA37AD11D5508E00975162 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "images/Icon@2x.png"; sourceTree = ""; }; + 18DA37AE11D5508E00975162 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; name = iTunesArtwork; path = images/iTunesArtwork; sourceTree = ""; }; + 18DA37F711D5529300975162 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = images/Icon.png; sourceTree = ""; }; + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* oalTouchAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalTouchAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* oalTouchAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = oalTouchAppDelegate.m; sourceTree = ""; }; + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* oalTouch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = oalTouch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* oalTouch_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalTouch_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A192CEDF0DDBB40300D03FCA /* oalSpatialView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalSpatialView.h; sourceTree = ""; }; + A192CEE00DDBB40300D03FCA /* oalSpatialView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = oalSpatialView.m; sourceTree = ""; }; + A192CEE40DDBB43B00D03FCA /* oalPlayback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalPlayback.h; sourceTree = ""; }; + A192CEE50DDBB43B00D03FCA /* oalPlayback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = oalPlayback.m; sourceTree = ""; }; + A192CF190DDBB6C900D03FCA /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + A192CF1D0DDBB6D400D03FCA /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; + A192CF420DDBB97F00D03FCA /* MyOpenALSupport.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = MyOpenALSupport.h; sourceTree = ""; }; + A1E88B180DDCA844008449A6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + F78602FD0DF86FCD00A013EA /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; + F79463420ED73BE70014B1E8 /* MyOpenALSupport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MyOpenALSupport.c; sourceTree = ""; }; + F79D54840FC4B9A500350F08 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + A192CF1A0DDBB6C900D03FCA /* AudioToolbox.framework in Frameworks */, + A192CF1E0DDBB6D400D03FCA /* OpenAL.framework in Frameworks */, + A1E88B190DDCA844008449A6 /* QuartzCore.framework in Frameworks */, + F78602FE0DF86FCD00A013EA /* MediaPlayer.framework in Frameworks */, + F79D54850FC4B9A500350F08 /* AVFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + A192CF420DDBB97F00D03FCA /* MyOpenALSupport.h */, + F79463420ED73BE70014B1E8 /* MyOpenALSupport.c */, + A192CEE40DDBB43B00D03FCA /* oalPlayback.h */, + A192CEE50DDBB43B00D03FCA /* oalPlayback.m */, + A192CEDF0DDBB40300D03FCA /* oalSpatialView.h */, + A192CEE00DDBB40300D03FCA /* oalSpatialView.m */, + 1D3623240D0F684500981E51 /* oalTouchAppDelegate.h */, + 1D3623250D0F684500981E51 /* oalTouchAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* oalTouch.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* oalTouch_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 18DA37F711D5529300975162 /* Icon.png */, + 18DA37A811D5508E00975162 /* Icon-72.png */, + 18DA37A911D5508E00975162 /* Icon-Small-50.png */, + 18DA37AA11D5508E00975162 /* Icon-Small.png */, + 18DA37AB11D5508E00975162 /* Icon-Small@2x.png */, + 18DA37AD11D5508E00975162 /* Icon@2x.png */, + 18DA37AE11D5508E00975162 /* iTunesArtwork */, + 18352A9711CFE75F0089BE2C /* MainWindow.xib */, + 18352A7411CFE5AA0089BE2C /* Default.png */, + 18352A7611CFE5AA0089BE2C /* instructions.png */, + 18352A7711CFE5AA0089BE2C /* listener.png */, + 18352A7811CFE5AA0089BE2C /* pause.png */, + 18352A7911CFE5AA0089BE2C /* play.png */, + 18352A7A11CFE5AA0089BE2C /* speaker_off.png */, + 18352A7B11CFE5AA0089BE2C /* speaker_on.png */, + 18352A7C11CFE5AA0089BE2C /* stagebg.png */, + F79D542A0FC4B27C00350F08 /* audio */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + F79D54840FC4B9A500350F08 /* AVFoundation.framework */, + F78602FD0DF86FCD00A013EA /* MediaPlayer.framework */, + A1E88B180DDCA844008449A6 /* QuartzCore.framework */, + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + A192CF1D0DDBB6D400D03FCA /* OpenAL.framework */, + A192CF190DDBB6C900D03FCA /* AudioToolbox.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + F79D542A0FC4B27C00350F08 /* audio */ = { + isa = PBXGroup; + children = ( + 18352A7011CFE5A30089BE2C /* background.m4a */, + 18352A7111CFE5A30089BE2C /* sound.caf */, + ); + name = audio; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* oalTouch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "oalTouch" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = oalTouch; + productName = oalTouch; + productReference = 1D6058910D05DD3D006BFB54 /* oalTouch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "oalTouch" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* oalTouch */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18352A7211CFE5A30089BE2C /* background.m4a in Resources */, + 18352A7311CFE5A30089BE2C /* sound.caf in Resources */, + 18352A7D11CFE5AA0089BE2C /* Default.png in Resources */, + 18352A7F11CFE5AA0089BE2C /* instructions.png in Resources */, + 18352A8011CFE5AA0089BE2C /* listener.png in Resources */, + 18352A8111CFE5AA0089BE2C /* pause.png in Resources */, + 18352A8211CFE5AA0089BE2C /* play.png in Resources */, + 18352A8311CFE5AA0089BE2C /* speaker_off.png in Resources */, + 18352A8411CFE5AA0089BE2C /* speaker_on.png in Resources */, + 18352A8511CFE5AA0089BE2C /* stagebg.png in Resources */, + 18352A9911CFE75F0089BE2C /* MainWindow.xib in Resources */, + 18DA37AF11D5508E00975162 /* Icon-72.png in Resources */, + 18DA37B011D5508E00975162 /* Icon-Small-50.png in Resources */, + 18DA37B111D5508E00975162 /* Icon-Small.png in Resources */, + 18DA37B211D5508E00975162 /* Icon-Small@2x.png in Resources */, + 18DA37B411D5508E00975162 /* Icon@2x.png in Resources */, + 18DA37B511D5508E00975162 /* iTunesArtwork in Resources */, + 18DA37F811D5529300975162 /* Icon.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* oalTouchAppDelegate.m in Sources */, + A192CEE10DDBB40300D03FCA /* oalSpatialView.m in Sources */, + A192CEE60DDBB43B00D03FCA /* oalPlayback.m in Sources */, + F79463430ED73BE70014B1E8 /* MyOpenALSupport.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 18352A9711CFE75F0089BE2C /* MainWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 18352A9811CFE75F0089BE2C /* en */, + ); + name = MainWindow.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = oalTouch_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = oalTouch; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = oalTouch_Prefix.pch; + INFOPLIST_FILE = Info.plist; + PRODUCT_NAME = oalTouch; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.2; + PREBINDING = NO; + SDKROOT = iphoneos4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "oalTouch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "oalTouch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/oalTouch/oalTouch_Prefix.pch b/oalTouch/oalTouch_Prefix.pch new file mode 100755 index 0000000..2754fb5 --- /dev/null +++ b/oalTouch/oalTouch_Prefix.pch @@ -0,0 +1,53 @@ +/* + + File: oalTouch_Prefix.pch +Abstract: Prefix file + Version: 1.9 + +Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following +terms, and your use, installation, modification or redistribution of +this Apple software constitutes acceptance of these terms. If you do +not agree with these terms, please do not use, install, modify or +redistribute this Apple software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, Apple grants you a personal, non-exclusive +license, under Apple's copyrights in this original Apple software (the +"Apple Software"), to use, reproduce, modify and redistribute the Apple +Software, with or without modifications, in source and/or binary forms; +provided that if you redistribute the Apple Software in its entirety and +without modifications, you must retain this notice and the following +text and disclaimers in all such redistributions of the Apple Software. +Neither the name, trademarks, service marks or logos of Apple Inc. may +be used to endorse or promote products derived from the Apple Software +without specific prior written permission from Apple. Except as +expressly stated in this notice, no other rights or licenses, express or +implied, are granted by Apple herein, including but not limited to any +patent rights that may be infringed by your derivative works or by other +works in which the Apple Software may be incorporated. + +The Apple Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +Copyright (C) 2010 Apple Inc. All Rights Reserved. + + + */ + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/oalTouch/sound.caf b/oalTouch/sound.caf new file mode 100644 index 0000000..415a9fd Binary files /dev/null and b/oalTouch/sound.caf differ