├── Example ├── NSDictionary+ImageMetadata Example.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── stevengrace.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── stevengrace.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── NSDictionary+ImageMetadata Example.xcscheme │ │ └── xcschememanagement.plist ├── NSDictionary+ImageMetadata Example │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Images │ │ ├── arches_8_bg_012003.jpg │ │ ├── canada_4_bg_061904.jpg │ │ ├── farm6_bg_092699.jpg │ │ ├── fried_egg_1_bg_20090705.jpg │ │ ├── orchid_3_bg_032402.jpg │ │ ├── phoenix_12_bg_050501.jpg │ │ ├── photoday_5_bg_071302.jpg │ │ ├── sandiego_3_bg_011301.jpg │ │ ├── sanfran_71_bg_032605.jpg │ │ ├── sanfran_79_bg_032605.jpg │ │ ├── sequoia_15_bg_082000.jpg │ │ └── zoo_5_bg_11302.jpg │ ├── ImagesViewController.h │ ├── ImagesViewController.m │ ├── MetadataTableViewController.h │ ├── MetadataTableViewController.m │ ├── NSBundle+ExampleAdditions.h │ ├── NSBundle+ExampleAdditions.m │ ├── NSDictionary+ImageMetadata Example-Info.plist │ ├── NSDictionary+ImageMetadata Example-Prefix.pch │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── NSDictionary+ImageMetadata ExampleTests │ ├── NSDictionary+ImageMetadata ExampleTests-Info.plist │ ├── NSDictionary_ImageMetadata_ExampleTests.m │ └── en.lproj │ └── InfoPlist.strings ├── LICENSE.txt ├── NSDictionary+ImageMetadata.h ├── NSDictionary+ImageMetadata.m ├── NSDictionary+MetadataDatasource.h ├── NSDictionary+MetadataDatasource.m ├── README.md └── gitignore /Example/NSDictionary+ImageMetadata Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E954C078192253D1004061FF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C077192253D1004061FF /* Foundation.framework */; }; 11 | E954C07A192253D1004061FF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C079192253D1004061FF /* CoreGraphics.framework */; }; 12 | E954C07C192253D1004061FF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C07B192253D1004061FF /* UIKit.framework */; }; 13 | E954C082192253D1004061FF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E954C080192253D1004061FF /* InfoPlist.strings */; }; 14 | E954C084192253D1004061FF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C083192253D1004061FF /* main.m */; }; 15 | E954C088192253D1004061FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C087192253D1004061FF /* AppDelegate.m */; }; 16 | E954C08B192253D1004061FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E954C089192253D1004061FF /* Main.storyboard */; }; 17 | E954C08E192253D1004061FF /* ImagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C08D192253D1004061FF /* ImagesViewController.m */; }; 18 | E954C090192253D1004061FF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E954C08F192253D1004061FF /* Images.xcassets */; }; 19 | E954C097192253D1004061FF /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C096192253D1004061FF /* XCTest.framework */; }; 20 | E954C098192253D1004061FF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C077192253D1004061FF /* Foundation.framework */; }; 21 | E954C099192253D1004061FF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C07B192253D1004061FF /* UIKit.framework */; }; 22 | E954C0A1192253D1004061FF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E954C09F192253D1004061FF /* InfoPlist.strings */; }; 23 | E954C0A3192253D1004061FF /* NSDictionary_ImageMetadata_ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C0A2192253D1004061FF /* NSDictionary_ImageMetadata_ExampleTests.m */; }; 24 | E954C0B51922546D004061FF /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C0B41922546D004061FF /* CoreLocation.framework */; }; 25 | E954C0B719225476004061FF /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E954C0B619225476004061FF /* CoreImage.framework */; }; 26 | E954C0BC1923972B004061FF /* NSDictionary+ImageMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C0B91923972B004061FF /* NSDictionary+ImageMetadata.m */; }; 27 | E954C0BD1923972B004061FF /* NSDictionary+MetadataDatasource.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C0BB1923972B004061FF /* NSDictionary+MetadataDatasource.m */; }; 28 | E954C0C0192398C6004061FF /* MetadataTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C0BF192398C6004061FF /* MetadataTableViewController.m */; }; 29 | E954C0C319239A6A004061FF /* NSBundle+ExampleAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = E954C0C219239A6A004061FF /* NSBundle+ExampleAdditions.m */; }; 30 | E954C0CB19239C50004061FF /* canada_4_bg_061904.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0C519239C50004061FF /* canada_4_bg_061904.jpg */; }; 31 | E954C0CC19239C50004061FF /* fried_egg_1_bg_20090705.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0C619239C50004061FF /* fried_egg_1_bg_20090705.jpg */; }; 32 | E954C0CD19239C50004061FF /* phoenix_12_bg_050501.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0C719239C50004061FF /* phoenix_12_bg_050501.jpg */; }; 33 | E954C0CE19239C50004061FF /* photoday_5_bg_071302.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0C819239C50004061FF /* photoday_5_bg_071302.jpg */; }; 34 | E954C0CF19239C50004061FF /* sanfran_71_bg_032605.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0C919239C50004061FF /* sanfran_71_bg_032605.jpg */; }; 35 | E954C0D019239C50004061FF /* sanfran_79_bg_032605.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0CA19239C50004061FF /* sanfran_79_bg_032605.jpg */; }; 36 | E954C0D71923A400004061FF /* arches_8_bg_012003.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0D11923A400004061FF /* arches_8_bg_012003.jpg */; }; 37 | E954C0D81923A400004061FF /* farm6_bg_092699.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0D21923A400004061FF /* farm6_bg_092699.jpg */; }; 38 | E954C0D91923A400004061FF /* orchid_3_bg_032402.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0D31923A400004061FF /* orchid_3_bg_032402.jpg */; }; 39 | E954C0DA1923A400004061FF /* sandiego_3_bg_011301.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0D41923A400004061FF /* sandiego_3_bg_011301.jpg */; }; 40 | E954C0DB1923A400004061FF /* sequoia_15_bg_082000.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0D51923A400004061FF /* sequoia_15_bg_082000.jpg */; }; 41 | E954C0DC1923A400004061FF /* zoo_5_bg_11302.jpg in Resources */ = {isa = PBXBuildFile; fileRef = E954C0D61923A400004061FF /* zoo_5_bg_11302.jpg */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | E954C09A192253D1004061FF /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = E954C06C192253D1004061FF /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = E954C073192253D1004061FF; 50 | remoteInfo = "NSDictionary+ImageMetadata Example"; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | E954C074192253D1004061FF /* NSDictionary+ImageMetadata Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NSDictionary+ImageMetadata Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | E954C077192253D1004061FF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 57 | E954C079192253D1004061FF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 58 | E954C07B192253D1004061FF /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 59 | E954C07F192253D1004061FF /* NSDictionary+ImageMetadata Example-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NSDictionary+ImageMetadata Example-Info.plist"; sourceTree = ""; }; 60 | E954C081192253D1004061FF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 61 | E954C083192253D1004061FF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 62 | E954C085192253D1004061FF /* NSDictionary+ImageMetadata Example-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+ImageMetadata Example-Prefix.pch"; sourceTree = ""; }; 63 | E954C086192253D1004061FF /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 64 | E954C087192253D1004061FF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 65 | E954C08A192253D1004061FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 66 | E954C08C192253D1004061FF /* ImagesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagesViewController.h; sourceTree = ""; }; 67 | E954C08D192253D1004061FF /* ImagesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagesViewController.m; sourceTree = ""; }; 68 | E954C08F192253D1004061FF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 69 | E954C095192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "NSDictionary+ImageMetadata ExampleTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 70 | E954C096192253D1004061FF /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 71 | E954C09E192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NSDictionary+ImageMetadata ExampleTests-Info.plist"; sourceTree = ""; }; 72 | E954C0A0192253D1004061FF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 73 | E954C0A2192253D1004061FF /* NSDictionary_ImageMetadata_ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSDictionary_ImageMetadata_ExampleTests.m; sourceTree = ""; }; 74 | E954C0B219225461004061FF /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 75 | E954C0B41922546D004061FF /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 76 | E954C0B619225476004061FF /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; }; 77 | E954C0B81923972B004061FF /* NSDictionary+ImageMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+ImageMetadata.h"; path = "../NSDictionary+ImageMetadata.h"; sourceTree = ""; }; 78 | E954C0B91923972B004061FF /* NSDictionary+ImageMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+ImageMetadata.m"; path = "../NSDictionary+ImageMetadata.m"; sourceTree = ""; }; 79 | E954C0BA1923972B004061FF /* NSDictionary+MetadataDatasource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+MetadataDatasource.h"; path = "../NSDictionary+MetadataDatasource.h"; sourceTree = ""; }; 80 | E954C0BB1923972B004061FF /* NSDictionary+MetadataDatasource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+MetadataDatasource.m"; path = "../NSDictionary+MetadataDatasource.m"; sourceTree = ""; }; 81 | E954C0BE192398C6004061FF /* MetadataTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetadataTableViewController.h; sourceTree = ""; }; 82 | E954C0BF192398C6004061FF /* MetadataTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MetadataTableViewController.m; sourceTree = ""; }; 83 | E954C0C119239A6A004061FF /* NSBundle+ExampleAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+ExampleAdditions.h"; sourceTree = ""; }; 84 | E954C0C219239A6A004061FF /* NSBundle+ExampleAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+ExampleAdditions.m"; sourceTree = ""; }; 85 | E954C0C519239C50004061FF /* canada_4_bg_061904.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = canada_4_bg_061904.jpg; path = Images/canada_4_bg_061904.jpg; sourceTree = ""; }; 86 | E954C0C619239C50004061FF /* fried_egg_1_bg_20090705.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = fried_egg_1_bg_20090705.jpg; path = Images/fried_egg_1_bg_20090705.jpg; sourceTree = ""; }; 87 | E954C0C719239C50004061FF /* phoenix_12_bg_050501.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = phoenix_12_bg_050501.jpg; path = Images/phoenix_12_bg_050501.jpg; sourceTree = ""; }; 88 | E954C0C819239C50004061FF /* photoday_5_bg_071302.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = photoday_5_bg_071302.jpg; path = Images/photoday_5_bg_071302.jpg; sourceTree = ""; }; 89 | E954C0C919239C50004061FF /* sanfran_71_bg_032605.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = sanfran_71_bg_032605.jpg; path = Images/sanfran_71_bg_032605.jpg; sourceTree = ""; }; 90 | E954C0CA19239C50004061FF /* sanfran_79_bg_032605.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = sanfran_79_bg_032605.jpg; path = Images/sanfran_79_bg_032605.jpg; sourceTree = ""; }; 91 | E954C0D11923A400004061FF /* arches_8_bg_012003.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = arches_8_bg_012003.jpg; path = Images/arches_8_bg_012003.jpg; sourceTree = ""; }; 92 | E954C0D21923A400004061FF /* farm6_bg_092699.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = farm6_bg_092699.jpg; path = Images/farm6_bg_092699.jpg; sourceTree = ""; }; 93 | E954C0D31923A400004061FF /* orchid_3_bg_032402.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = orchid_3_bg_032402.jpg; path = Images/orchid_3_bg_032402.jpg; sourceTree = ""; }; 94 | E954C0D41923A400004061FF /* sandiego_3_bg_011301.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = sandiego_3_bg_011301.jpg; path = Images/sandiego_3_bg_011301.jpg; sourceTree = ""; }; 95 | E954C0D51923A400004061FF /* sequoia_15_bg_082000.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = sequoia_15_bg_082000.jpg; path = Images/sequoia_15_bg_082000.jpg; sourceTree = ""; }; 96 | E954C0D61923A400004061FF /* zoo_5_bg_11302.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = zoo_5_bg_11302.jpg; path = Images/zoo_5_bg_11302.jpg; sourceTree = ""; }; 97 | /* End PBXFileReference section */ 98 | 99 | /* Begin PBXFrameworksBuildPhase section */ 100 | E954C071192253D1004061FF /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | E954C0B719225476004061FF /* CoreImage.framework in Frameworks */, 105 | E954C0B51922546D004061FF /* CoreLocation.framework in Frameworks */, 106 | E954C07A192253D1004061FF /* CoreGraphics.framework in Frameworks */, 107 | E954C07C192253D1004061FF /* UIKit.framework in Frameworks */, 108 | E954C078192253D1004061FF /* Foundation.framework in Frameworks */, 109 | ); 110 | runOnlyForDeploymentPostprocessing = 0; 111 | }; 112 | E954C092192253D1004061FF /* Frameworks */ = { 113 | isa = PBXFrameworksBuildPhase; 114 | buildActionMask = 2147483647; 115 | files = ( 116 | E954C097192253D1004061FF /* XCTest.framework in Frameworks */, 117 | E954C099192253D1004061FF /* UIKit.framework in Frameworks */, 118 | E954C098192253D1004061FF /* Foundation.framework in Frameworks */, 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXFrameworksBuildPhase section */ 123 | 124 | /* Begin PBXGroup section */ 125 | E954C06B192253D1004061FF = { 126 | isa = PBXGroup; 127 | children = ( 128 | E954C0B81923972B004061FF /* NSDictionary+ImageMetadata.h */, 129 | E954C0B91923972B004061FF /* NSDictionary+ImageMetadata.m */, 130 | E954C0BA1923972B004061FF /* NSDictionary+MetadataDatasource.h */, 131 | E954C0BB1923972B004061FF /* NSDictionary+MetadataDatasource.m */, 132 | E954C07D192253D1004061FF /* NSDictionary+ImageMetadata Example */, 133 | E954C09C192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests */, 134 | E954C076192253D1004061FF /* Frameworks */, 135 | E954C075192253D1004061FF /* Products */, 136 | ); 137 | sourceTree = ""; 138 | }; 139 | E954C075192253D1004061FF /* Products */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | E954C074192253D1004061FF /* NSDictionary+ImageMetadata Example.app */, 143 | E954C095192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests.xctest */, 144 | ); 145 | name = Products; 146 | sourceTree = ""; 147 | }; 148 | E954C076192253D1004061FF /* Frameworks */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | E954C0B619225476004061FF /* CoreImage.framework */, 152 | E954C0B41922546D004061FF /* CoreLocation.framework */, 153 | E954C0B219225461004061FF /* AssetsLibrary.framework */, 154 | E954C077192253D1004061FF /* Foundation.framework */, 155 | E954C079192253D1004061FF /* CoreGraphics.framework */, 156 | E954C07B192253D1004061FF /* UIKit.framework */, 157 | E954C096192253D1004061FF /* XCTest.framework */, 158 | ); 159 | name = Frameworks; 160 | sourceTree = ""; 161 | }; 162 | E954C07D192253D1004061FF /* NSDictionary+ImageMetadata Example */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | E954C0C419239C44004061FF /* Images */, 166 | E954C086192253D1004061FF /* AppDelegate.h */, 167 | E954C087192253D1004061FF /* AppDelegate.m */, 168 | E954C089192253D1004061FF /* Main.storyboard */, 169 | E954C08C192253D1004061FF /* ImagesViewController.h */, 170 | E954C08D192253D1004061FF /* ImagesViewController.m */, 171 | E954C0BE192398C6004061FF /* MetadataTableViewController.h */, 172 | E954C0BF192398C6004061FF /* MetadataTableViewController.m */, 173 | E954C0C119239A6A004061FF /* NSBundle+ExampleAdditions.h */, 174 | E954C0C219239A6A004061FF /* NSBundle+ExampleAdditions.m */, 175 | E954C08F192253D1004061FF /* Images.xcassets */, 176 | E954C07E192253D1004061FF /* Supporting Files */, 177 | ); 178 | path = "NSDictionary+ImageMetadata Example"; 179 | sourceTree = ""; 180 | }; 181 | E954C07E192253D1004061FF /* Supporting Files */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | E954C07F192253D1004061FF /* NSDictionary+ImageMetadata Example-Info.plist */, 185 | E954C080192253D1004061FF /* InfoPlist.strings */, 186 | E954C083192253D1004061FF /* main.m */, 187 | E954C085192253D1004061FF /* NSDictionary+ImageMetadata Example-Prefix.pch */, 188 | ); 189 | name = "Supporting Files"; 190 | sourceTree = ""; 191 | }; 192 | E954C09C192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | E954C0A2192253D1004061FF /* NSDictionary_ImageMetadata_ExampleTests.m */, 196 | E954C09D192253D1004061FF /* Supporting Files */, 197 | ); 198 | path = "NSDictionary+ImageMetadata ExampleTests"; 199 | sourceTree = ""; 200 | }; 201 | E954C09D192253D1004061FF /* Supporting Files */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | E954C09E192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests-Info.plist */, 205 | E954C09F192253D1004061FF /* InfoPlist.strings */, 206 | ); 207 | name = "Supporting Files"; 208 | sourceTree = ""; 209 | }; 210 | E954C0C419239C44004061FF /* Images */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | E954C0D11923A400004061FF /* arches_8_bg_012003.jpg */, 214 | E954C0D21923A400004061FF /* farm6_bg_092699.jpg */, 215 | E954C0D31923A400004061FF /* orchid_3_bg_032402.jpg */, 216 | E954C0D41923A400004061FF /* sandiego_3_bg_011301.jpg */, 217 | E954C0D51923A400004061FF /* sequoia_15_bg_082000.jpg */, 218 | E954C0D61923A400004061FF /* zoo_5_bg_11302.jpg */, 219 | E954C0C519239C50004061FF /* canada_4_bg_061904.jpg */, 220 | E954C0C619239C50004061FF /* fried_egg_1_bg_20090705.jpg */, 221 | E954C0C719239C50004061FF /* phoenix_12_bg_050501.jpg */, 222 | E954C0C819239C50004061FF /* photoday_5_bg_071302.jpg */, 223 | E954C0C919239C50004061FF /* sanfran_71_bg_032605.jpg */, 224 | E954C0CA19239C50004061FF /* sanfran_79_bg_032605.jpg */, 225 | ); 226 | name = Images; 227 | sourceTree = ""; 228 | }; 229 | /* End PBXGroup section */ 230 | 231 | /* Begin PBXNativeTarget section */ 232 | E954C073192253D1004061FF /* NSDictionary+ImageMetadata Example */ = { 233 | isa = PBXNativeTarget; 234 | buildConfigurationList = E954C0A6192253D1004061FF /* Build configuration list for PBXNativeTarget "NSDictionary+ImageMetadata Example" */; 235 | buildPhases = ( 236 | E954C070192253D1004061FF /* Sources */, 237 | E954C071192253D1004061FF /* Frameworks */, 238 | E954C072192253D1004061FF /* Resources */, 239 | ); 240 | buildRules = ( 241 | ); 242 | dependencies = ( 243 | ); 244 | name = "NSDictionary+ImageMetadata Example"; 245 | productName = "NSDictionary+ImageMetadata Example"; 246 | productReference = E954C074192253D1004061FF /* NSDictionary+ImageMetadata Example.app */; 247 | productType = "com.apple.product-type.application"; 248 | }; 249 | E954C094192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests */ = { 250 | isa = PBXNativeTarget; 251 | buildConfigurationList = E954C0A9192253D1004061FF /* Build configuration list for PBXNativeTarget "NSDictionary+ImageMetadata ExampleTests" */; 252 | buildPhases = ( 253 | E954C091192253D1004061FF /* Sources */, 254 | E954C092192253D1004061FF /* Frameworks */, 255 | E954C093192253D1004061FF /* Resources */, 256 | ); 257 | buildRules = ( 258 | ); 259 | dependencies = ( 260 | E954C09B192253D1004061FF /* PBXTargetDependency */, 261 | ); 262 | name = "NSDictionary+ImageMetadata ExampleTests"; 263 | productName = "NSDictionary+ImageMetadata ExampleTests"; 264 | productReference = E954C095192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests.xctest */; 265 | productType = "com.apple.product-type.bundle.unit-test"; 266 | }; 267 | /* End PBXNativeTarget section */ 268 | 269 | /* Begin PBXProject section */ 270 | E954C06C192253D1004061FF /* Project object */ = { 271 | isa = PBXProject; 272 | attributes = { 273 | LastUpgradeCheck = 0510; 274 | ORGANIZATIONNAME = "Steven Grace"; 275 | TargetAttributes = { 276 | E954C094192253D1004061FF = { 277 | TestTargetID = E954C073192253D1004061FF; 278 | }; 279 | }; 280 | }; 281 | buildConfigurationList = E954C06F192253D1004061FF /* Build configuration list for PBXProject "NSDictionary+ImageMetadata Example" */; 282 | compatibilityVersion = "Xcode 3.2"; 283 | developmentRegion = English; 284 | hasScannedForEncodings = 0; 285 | knownRegions = ( 286 | en, 287 | Base, 288 | ); 289 | mainGroup = E954C06B192253D1004061FF; 290 | productRefGroup = E954C075192253D1004061FF /* Products */; 291 | projectDirPath = ""; 292 | projectRoot = ""; 293 | targets = ( 294 | E954C073192253D1004061FF /* NSDictionary+ImageMetadata Example */, 295 | E954C094192253D1004061FF /* NSDictionary+ImageMetadata ExampleTests */, 296 | ); 297 | }; 298 | /* End PBXProject section */ 299 | 300 | /* Begin PBXResourcesBuildPhase section */ 301 | E954C072192253D1004061FF /* Resources */ = { 302 | isa = PBXResourcesBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | E954C090192253D1004061FF /* Images.xcassets in Resources */, 306 | E954C0DC1923A400004061FF /* zoo_5_bg_11302.jpg in Resources */, 307 | E954C0CE19239C50004061FF /* photoday_5_bg_071302.jpg in Resources */, 308 | E954C0CC19239C50004061FF /* fried_egg_1_bg_20090705.jpg in Resources */, 309 | E954C0D71923A400004061FF /* arches_8_bg_012003.jpg in Resources */, 310 | E954C0CD19239C50004061FF /* phoenix_12_bg_050501.jpg in Resources */, 311 | E954C082192253D1004061FF /* InfoPlist.strings in Resources */, 312 | E954C0DB1923A400004061FF /* sequoia_15_bg_082000.jpg in Resources */, 313 | E954C0D91923A400004061FF /* orchid_3_bg_032402.jpg in Resources */, 314 | E954C08B192253D1004061FF /* Main.storyboard in Resources */, 315 | E954C0CF19239C50004061FF /* sanfran_71_bg_032605.jpg in Resources */, 316 | E954C0D81923A400004061FF /* farm6_bg_092699.jpg in Resources */, 317 | E954C0D019239C50004061FF /* sanfran_79_bg_032605.jpg in Resources */, 318 | E954C0DA1923A400004061FF /* sandiego_3_bg_011301.jpg in Resources */, 319 | E954C0CB19239C50004061FF /* canada_4_bg_061904.jpg in Resources */, 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | E954C093192253D1004061FF /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | E954C0A1192253D1004061FF /* InfoPlist.strings in Resources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | /* End PBXResourcesBuildPhase section */ 332 | 333 | /* Begin PBXSourcesBuildPhase section */ 334 | E954C070192253D1004061FF /* Sources */ = { 335 | isa = PBXSourcesBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | E954C0C0192398C6004061FF /* MetadataTableViewController.m in Sources */, 339 | E954C08E192253D1004061FF /* ImagesViewController.m in Sources */, 340 | E954C0BC1923972B004061FF /* NSDictionary+ImageMetadata.m in Sources */, 341 | E954C088192253D1004061FF /* AppDelegate.m in Sources */, 342 | E954C0C319239A6A004061FF /* NSBundle+ExampleAdditions.m in Sources */, 343 | E954C084192253D1004061FF /* main.m in Sources */, 344 | E954C0BD1923972B004061FF /* NSDictionary+MetadataDatasource.m in Sources */, 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | }; 348 | E954C091192253D1004061FF /* Sources */ = { 349 | isa = PBXSourcesBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | E954C0A3192253D1004061FF /* NSDictionary_ImageMetadata_ExampleTests.m in Sources */, 353 | ); 354 | runOnlyForDeploymentPostprocessing = 0; 355 | }; 356 | /* End PBXSourcesBuildPhase section */ 357 | 358 | /* Begin PBXTargetDependency section */ 359 | E954C09B192253D1004061FF /* PBXTargetDependency */ = { 360 | isa = PBXTargetDependency; 361 | target = E954C073192253D1004061FF /* NSDictionary+ImageMetadata Example */; 362 | targetProxy = E954C09A192253D1004061FF /* PBXContainerItemProxy */; 363 | }; 364 | /* End PBXTargetDependency section */ 365 | 366 | /* Begin PBXVariantGroup section */ 367 | E954C080192253D1004061FF /* InfoPlist.strings */ = { 368 | isa = PBXVariantGroup; 369 | children = ( 370 | E954C081192253D1004061FF /* en */, 371 | ); 372 | name = InfoPlist.strings; 373 | sourceTree = ""; 374 | }; 375 | E954C089192253D1004061FF /* Main.storyboard */ = { 376 | isa = PBXVariantGroup; 377 | children = ( 378 | E954C08A192253D1004061FF /* Base */, 379 | ); 380 | name = Main.storyboard; 381 | sourceTree = ""; 382 | }; 383 | E954C09F192253D1004061FF /* InfoPlist.strings */ = { 384 | isa = PBXVariantGroup; 385 | children = ( 386 | E954C0A0192253D1004061FF /* en */, 387 | ); 388 | name = InfoPlist.strings; 389 | sourceTree = ""; 390 | }; 391 | /* End PBXVariantGroup section */ 392 | 393 | /* Begin XCBuildConfiguration section */ 394 | E954C0A4192253D1004061FF /* Debug */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | ALWAYS_SEARCH_USER_PATHS = NO; 398 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 399 | CLANG_CXX_LIBRARY = "libc++"; 400 | CLANG_ENABLE_MODULES = YES; 401 | CLANG_ENABLE_OBJC_ARC = YES; 402 | CLANG_WARN_BOOL_CONVERSION = YES; 403 | CLANG_WARN_CONSTANT_CONVERSION = YES; 404 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 405 | CLANG_WARN_EMPTY_BODY = YES; 406 | CLANG_WARN_ENUM_CONVERSION = YES; 407 | CLANG_WARN_INT_CONVERSION = YES; 408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 409 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 410 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 411 | COPY_PHASE_STRIP = NO; 412 | GCC_C_LANGUAGE_STANDARD = gnu99; 413 | GCC_DYNAMIC_NO_PIC = NO; 414 | GCC_OPTIMIZATION_LEVEL = 0; 415 | GCC_PREPROCESSOR_DEFINITIONS = ( 416 | "DEBUG=1", 417 | "$(inherited)", 418 | ); 419 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 420 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 422 | GCC_WARN_UNDECLARED_SELECTOR = YES; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 427 | ONLY_ACTIVE_ARCH = YES; 428 | SDKROOT = iphoneos; 429 | }; 430 | name = Debug; 431 | }; 432 | E954C0A5192253D1004061FF /* Release */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_SEARCH_USER_PATHS = NO; 436 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 437 | CLANG_CXX_LIBRARY = "libc++"; 438 | CLANG_ENABLE_MODULES = YES; 439 | CLANG_ENABLE_OBJC_ARC = YES; 440 | CLANG_WARN_BOOL_CONVERSION = YES; 441 | CLANG_WARN_CONSTANT_CONVERSION = YES; 442 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 443 | CLANG_WARN_EMPTY_BODY = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INT_CONVERSION = YES; 446 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 447 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 448 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 449 | COPY_PHASE_STRIP = YES; 450 | ENABLE_NS_ASSERTIONS = NO; 451 | GCC_C_LANGUAGE_STANDARD = gnu99; 452 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 453 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 454 | GCC_WARN_UNDECLARED_SELECTOR = YES; 455 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 456 | GCC_WARN_UNUSED_FUNCTION = YES; 457 | GCC_WARN_UNUSED_VARIABLE = YES; 458 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 459 | SDKROOT = iphoneos; 460 | VALIDATE_PRODUCT = YES; 461 | }; 462 | name = Release; 463 | }; 464 | E954C0A7192253D1004061FF /* Debug */ = { 465 | isa = XCBuildConfiguration; 466 | buildSettings = { 467 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 468 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 469 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 470 | GCC_PREFIX_HEADER = "NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Prefix.pch"; 471 | INFOPLIST_FILE = "NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Info.plist"; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | WRAPPER_EXTENSION = app; 474 | }; 475 | name = Debug; 476 | }; 477 | E954C0A8192253D1004061FF /* Release */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 481 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 482 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 483 | GCC_PREFIX_HEADER = "NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Prefix.pch"; 484 | INFOPLIST_FILE = "NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Info.plist"; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | WRAPPER_EXTENSION = app; 487 | }; 488 | name = Release; 489 | }; 490 | E954C0AA192253D1004061FF /* Debug */ = { 491 | isa = XCBuildConfiguration; 492 | buildSettings = { 493 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NSDictionary+ImageMetadata Example.app/NSDictionary+ImageMetadata Example"; 494 | FRAMEWORK_SEARCH_PATHS = ( 495 | "$(SDKROOT)/Developer/Library/Frameworks", 496 | "$(inherited)", 497 | "$(DEVELOPER_FRAMEWORKS_DIR)", 498 | ); 499 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 500 | GCC_PREFIX_HEADER = "NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Prefix.pch"; 501 | GCC_PREPROCESSOR_DEFINITIONS = ( 502 | "DEBUG=1", 503 | "$(inherited)", 504 | ); 505 | INFOPLIST_FILE = "NSDictionary+ImageMetadata ExampleTests/NSDictionary+ImageMetadata ExampleTests-Info.plist"; 506 | PRODUCT_NAME = "$(TARGET_NAME)"; 507 | TEST_HOST = "$(BUNDLE_LOADER)"; 508 | WRAPPER_EXTENSION = xctest; 509 | }; 510 | name = Debug; 511 | }; 512 | E954C0AB192253D1004061FF /* Release */ = { 513 | isa = XCBuildConfiguration; 514 | buildSettings = { 515 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NSDictionary+ImageMetadata Example.app/NSDictionary+ImageMetadata Example"; 516 | FRAMEWORK_SEARCH_PATHS = ( 517 | "$(SDKROOT)/Developer/Library/Frameworks", 518 | "$(inherited)", 519 | "$(DEVELOPER_FRAMEWORKS_DIR)", 520 | ); 521 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 522 | GCC_PREFIX_HEADER = "NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Prefix.pch"; 523 | INFOPLIST_FILE = "NSDictionary+ImageMetadata ExampleTests/NSDictionary+ImageMetadata ExampleTests-Info.plist"; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | TEST_HOST = "$(BUNDLE_LOADER)"; 526 | WRAPPER_EXTENSION = xctest; 527 | }; 528 | name = Release; 529 | }; 530 | /* End XCBuildConfiguration section */ 531 | 532 | /* Begin XCConfigurationList section */ 533 | E954C06F192253D1004061FF /* Build configuration list for PBXProject "NSDictionary+ImageMetadata Example" */ = { 534 | isa = XCConfigurationList; 535 | buildConfigurations = ( 536 | E954C0A4192253D1004061FF /* Debug */, 537 | E954C0A5192253D1004061FF /* Release */, 538 | ); 539 | defaultConfigurationIsVisible = 0; 540 | defaultConfigurationName = Release; 541 | }; 542 | E954C0A6192253D1004061FF /* Build configuration list for PBXNativeTarget "NSDictionary+ImageMetadata Example" */ = { 543 | isa = XCConfigurationList; 544 | buildConfigurations = ( 545 | E954C0A7192253D1004061FF /* Debug */, 546 | E954C0A8192253D1004061FF /* Release */, 547 | ); 548 | defaultConfigurationIsVisible = 0; 549 | defaultConfigurationName = Release; 550 | }; 551 | E954C0A9192253D1004061FF /* Build configuration list for PBXNativeTarget "NSDictionary+ImageMetadata ExampleTests" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | E954C0AA192253D1004061FF /* Debug */, 555 | E954C0AB192253D1004061FF /* Release */, 556 | ); 557 | defaultConfigurationIsVisible = 0; 558 | defaultConfigurationName = Release; 559 | }; 560 | /* End XCConfigurationList section */ 561 | }; 562 | rootObject = E954C06C192253D1004061FF /* Project object */; 563 | } 564 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example.xcodeproj/project.xcworkspace/xcuserdata/stevengrace.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example.xcodeproj/project.xcworkspace/xcuserdata/stevengrace.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example.xcodeproj/project.xcworkspace/xcuserdata/stevengrace.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example.xcodeproj/xcuserdata/stevengrace.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example.xcodeproj/xcuserdata/stevengrace.xcuserdatad/xcschemes/NSDictionary+ImageMetadata Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example.xcodeproj/xcuserdata/stevengrace.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSDictionary+ImageMetadata Example.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E954C073192253D1004061FF 16 | 17 | primary 18 | 19 | 20 | E954C094192253D1004061FF 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/13/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/13/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/arches_8_bg_012003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/arches_8_bg_012003.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/canada_4_bg_061904.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/canada_4_bg_061904.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/farm6_bg_092699.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/farm6_bg_092699.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/fried_egg_1_bg_20090705.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/fried_egg_1_bg_20090705.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/orchid_3_bg_032402.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/orchid_3_bg_032402.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/phoenix_12_bg_050501.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/phoenix_12_bg_050501.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/photoday_5_bg_071302.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/photoday_5_bg_071302.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/sandiego_3_bg_011301.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/sandiego_3_bg_011301.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/sanfran_71_bg_032605.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/sanfran_71_bg_032605.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/sanfran_79_bg_032605.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/sanfran_79_bg_032605.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/sequoia_15_bg_082000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/sequoia_15_bg_082000.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/Images/zoo_5_bg_11302.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/NSDictionary-ImageMetadata/8e5528268f334e3ec39aa109c7f5806253fe0afc/Example/NSDictionary+ImageMetadata Example/Images/zoo_5_bg_11302.jpg -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/ImagesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/13/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ImagesViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/ImagesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/13/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "ImagesViewController.h" 10 | #import "MetadataTableViewController.h" 11 | #import "NSBundle+ExampleAdditions.h" 12 | 13 | @interface ImagesViewController () 14 | 15 | @property (nonatomic, readwrite, strong) NSArray *imageFileURLs; 16 | 17 | @end 18 | 19 | NSString *const kImageMetadataSegueIdentifier = @"ImageMetadataSegue"; 20 | NSString *const kImageCellReuseIndentifier = @"imageCell"; 21 | 22 | @implementation ImagesViewController 23 | 24 | #pragma mark - View Lifecycle 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | 30 | self.imageFileURLs = [[NSBundle mainBundle]imageURLsWithExtension:@"jpg"]; 31 | } 32 | 33 | #pragma mark - Segue 34 | 35 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 36 | { 37 | if ([segue.identifier isEqualToString:kImageMetadataSegueIdentifier]) 38 | { 39 | MetadataTableViewController *metadataTableController = (MetadataTableViewController *)segue.destinationViewController; 40 | metadataTableController.imageURL = self.imageFileURLs[self.tableView.indexPathForSelectedRow.row]; 41 | } 42 | } 43 | 44 | #pragma mark - TableViewDatasource 45 | 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 47 | { 48 | return [self.imageFileURLs count]; 49 | } 50 | 51 | - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 52 | { 53 | UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:kImageCellReuseIndentifier forIndexPath:indexPath]; 54 | 55 | NSURL *imageURL = self.imageFileURLs[indexPath.row]; 56 | UIImage *image = [[UIImage alloc]initWithContentsOfFile:[imageURL path]]; 57 | cell.imageView.image = image; 58 | cell.textLabel.text = [imageURL lastPathComponent]; 59 | return cell; 60 | } 61 | 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/MetadataTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MetadataTableViewController.h 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/14/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MetadataTableViewController : UITableViewController 12 | 13 | @property (nonatomic, readwrite, weak) IBOutlet UILabel *imageFilenameLabel; 14 | @property (nonatomic, readwrite, strong) NSURL *imageURL; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/MetadataTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MetadataTableViewController.m 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/14/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "MetadataTableViewController.h" 10 | #import "NSDictionary+ImageMetadata.h" 11 | #import "NSDictionary+MetadataDatasource.h" 12 | 13 | @interface MetadataTableViewController () 14 | 15 | @property (nonatomic, readwrite, strong) NSDictionary *metadata; 16 | 17 | @end 18 | 19 | @implementation MetadataTableViewController 20 | 21 | - (id)initWithStyle:(UITableViewStyle)style 22 | { 23 | self = [super initWithStyle:style]; 24 | if (self) { 25 | // Custom initialization 26 | } 27 | return self; 28 | } 29 | 30 | - (void)viewDidLoad 31 | { 32 | [super viewDidLoad]; 33 | self.imageFilenameLabel.text = [self.imageURL lastPathComponent]; 34 | self.metadata = [NSDictionary imageMetadataWithImageAtURL:self.imageURL]; 35 | self.tableView.dataSource = self.metadata; 36 | } 37 | 38 | - (void)didReceiveMemoryWarning 39 | { 40 | [super didReceiveMemoryWarning]; 41 | // Dispose of any resources that can be recreated. 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/NSBundle+ExampleAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+ExampleAdditions.h 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/14/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSBundle (ExampleAdditions) 12 | 13 | -(NSArray *)imageURLsWithExtension:(NSString *)ext; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/NSBundle+ExampleAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+ExampleAdditions.m 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/14/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "NSBundle+ExampleAdditions.h" 10 | 11 | @implementation NSBundle (ExampleAdditions) 12 | 13 | - (NSArray *)imageURLsWithExtension:(NSString *)ext 14 | { 15 | NSMutableArray *mArr = [[NSMutableArray alloc]init]; 16 | NSMutableArray *paths = [[NSMutableArray alloc]init]; 17 | [paths addObjectsFromArray:[self pathsForResourcesOfType:ext inDirectory:nil]]; 18 | 19 | for(NSString *aPath in paths) 20 | { 21 | NSURL *imageURL = [NSURL fileURLWithPath:aPath]; 22 | [mArr addObject:imageURL] ; 23 | } 24 | return [mArr copy]; 25 | } 26 | 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | me.stevengrace.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/NSDictionary+ImageMetadata Example-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #endif 20 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata Example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NSDictionary+ImageMetadata Example 4 | // 5 | // Created by Steven Grace on 5/13/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata ExampleTests/NSDictionary+ImageMetadata ExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | me.stevengrace.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata ExampleTests/NSDictionary_ImageMetadata_ExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary_ImageMetadata_ExampleTests.m 3 | // NSDictionary+ImageMetadata ExampleTests 4 | // 5 | // Created by Steven Grace on 5/13/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary_ImageMetadata_ExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation NSDictionary_ImageMetadata_ExampleTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Example/NSDictionary+ImageMetadata ExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Steven Grace 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /NSDictionary+ImageMetadata.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+ImageMetadata.h 3 | // NSDictionary-ImageMetadata 4 | // 5 | // Created by Steven Grace on 4/22/13. 6 | // Copyright (c) 2013 Steven Grace. All rights reserved. 7 | // www.works5.com 8 | // 9 | // Category Methods for fetching and working with Image Metadata; 10 | // More information on the specific properties can be found at in ImageIO 11 | // 12 | //#include 13 | 14 | @interface NSDictionary (ImageMetadata) 15 | 16 | + (NSDictionary*)imageMetadataWithImageAtURL:(NSURL *)url; 17 | 18 | // pass in CGImageProperty value (recursively searched in sub dictionaries) 19 | - (id)sgg_valueForProperty:(NSString *)property; 20 | 21 | // UI Formatted/Readable Variants 22 | @property (nonatomic,readonly) NSString* sgg_formattedShutterSpeed; 23 | @property (nonatomic,readonly) NSString* sgg_formattedApetureValue; 24 | 25 | // Location (calculated from GPS Metadata) 26 | @property (nonatomic,readonly) CLLocation* sgg_location; 27 | @property (nonatomic,readonly) CLLocationDirection sgg_trueHeading; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /NSDictionary+ImageMetadata.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+ImageMetadata.m 3 | // NSDictionary-ImageMetadata 4 | // 5 | // Created by Steven Grace on 4/22/13. 6 | // Copyright (c) 2013 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+ImageMetadata.h" 10 | 11 | @implementation NSDictionary (ImageMetadata) 12 | 13 | #pragma mark Metadata Fetching 14 | 15 | + (NSDictionary*)imageMetadataWithImageAtURL:(NSURL*)url 16 | { 17 | CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL); 18 | 19 | if (!imageSource) { 20 | NSLog(@"%s failed to create image at url: %@",__PRETTY_FUNCTION__,url); 21 | return nil; 22 | } 23 | NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 24 | [NSNumber numberWithBool:NO], (NSString *)kCGImageSourceShouldCache, 25 | nil]; 26 | CFDictionaryRef imageProperties =CGImageSourceCopyPropertiesAtIndex(imageSource,0,(__bridge CFDictionaryRef)options); 27 | CFRelease(imageSource); 28 | NSMutableDictionary* metadata = [NSMutableDictionary dictionaryWithDictionary:(__bridge NSDictionary*)imageProperties]; 29 | CFRelease(imageProperties); 30 | return metadata; 31 | } 32 | 33 | #pragma mark - Public Property Fetching 34 | 35 | - (id)sgg_valueForProperty:(NSString *)property 36 | { 37 | return [self sgg_recursiveObjectForKey:property]; 38 | } 39 | 40 | #pragma mark - Formatted Property Helpers 41 | 42 | - (NSString*)sgg_formattedShutterSpeed 43 | { 44 | NSNumber* time = [self sgg_recursiveObjectForKey:(id)kCGImagePropertyExifShutterSpeedValue]; 45 | float d=1/[time floatValue]; 46 | return [NSString stringWithFormat:@"1/%g",ceilf(d)]; 47 | } 48 | 49 | - (NSString*)sgg_formattedApetureValue 50 | { 51 | return [NSString stringWithFormat:@"f/%@",[self sgg_recursiveObjectForKey:(id)kCGImagePropertyExifApertureValue]]; 52 | } 53 | 54 | #pragma mark - Location 55 | 56 | - (CLLocation*)sgg_location 57 | { 58 | NSDictionary *GPSdictionary = [self objectForKey:(id)kCGImagePropertyGPSDictionary]; 59 | if (GPSdictionary) { 60 | 61 | CLLocationDegrees latituteDegress = [[GPSdictionary objectForKey:(id)kCGImagePropertyGPSLatitude] floatValue]; 62 | CLLocationDegrees longitudeDegress = [[GPSdictionary objectForKey:(id)kCGImagePropertyGPSLongitude] floatValue]; 63 | NSString *latitudeRef = [GPSdictionary objectForKey:(id)kCGImagePropertyGPSLatitudeRef]; 64 | NSString *longtiudeRef = [GPSdictionary objectForKey:(id)kCGImagePropertyGPSLongitudeRef]; 65 | 66 | if ([@"S" isEqualToString:latitudeRef]) { 67 | latituteDegress *= -1.0f; 68 | } 69 | 70 | if ([@"W" isEqualToString:longtiudeRef]) { 71 | longitudeDegress *= -1.0f; 72 | } 73 | 74 | CLLocation *location = [[CLLocation alloc] initWithLatitude:latituteDegress longitude:longitudeDegress]; 75 | return location; 76 | } 77 | return nil; 78 | } 79 | 80 | - (CLLocationDirection)sgg_trueHeading 81 | { 82 | NSDictionary *GPSinfo = [self objectForKey:(id)kCGImagePropertyGPSDictionary]; 83 | CLLocationDirection heading = 0; 84 | if (GPSinfo) { 85 | heading =[[GPSinfo objectForKey:(id)kCGImagePropertyGPSImgDirection] doubleValue]; 86 | } 87 | return heading; 88 | } 89 | 90 | #pragma mark- NSDictionary Recursive 91 | 92 | - (id)sgg_recursiveObjectForKey:(NSString *)key 93 | { 94 | if ([self.allKeys containsObject:key]) { 95 | return [self objectForKey:key]; 96 | } 97 | 98 | for (NSString *k in self.allKeys) 99 | { 100 | id obj = [self objectForKey:k]; 101 | if([obj isKindOfClass:[NSDictionary class]]) 102 | { 103 | NSDictionary *d = (NSDictionary *)obj; 104 | id child = [d sgg_recursiveObjectForKey:key]; 105 | if(child) return child; 106 | 107 | } else if([obj isKindOfClass:[NSArray class]]) { 108 | 109 | // loop through the NSArray and traverse any dictionaries found 110 | NSArray *a = (NSArray *)obj; 111 | for(id child in a) { 112 | if([child isKindOfClass:[NSDictionary class]]) { 113 | NSDictionary *d = (NSDictionary *)child; 114 | id o = [d sgg_recursiveObjectForKey:key]; 115 | if(o) return o; 116 | } 117 | } 118 | } 119 | } 120 | // the key was not found in this dictionary or any of it's children 121 | return nil; 122 | } 123 | @end 124 | -------------------------------------------------------------------------------- /NSDictionary+MetadataDatasource.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+MetadataDatasource.h 3 | // NSDictionary-ImageMetadata 4 | // 5 | // Created by Steven Grace on 4/21/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (MetadataDatasource) 12 | 13 | /* 14 | Tableview dataource 15 | */ 16 | // A default implementation using 'UITableViewCellStyleValue1' UITableViewCells 17 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; 18 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 19 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; 20 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 21 | 22 | /* 23 | IndexPath based queries 24 | */ 25 | // Use for more customized Tableviews 26 | - (NSUInteger)sgg_numberOfRowsInSection:(NSUInteger)section; 27 | - (NSString *)sgg_propertyForIndexPath:(NSIndexPath*)indexPath; 28 | - (NSString*)sgg_valueForPropertyAtIndexPath:(NSIndexPath*)indexPath; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /NSDictionary+MetadataDatasource.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+MetadataDatasource.m 3 | // NSDictionary-ImageMetadata 4 | // 5 | // Created by Steven Grace on 4/21/14. 6 | // Copyright (c) 2014 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+MetadataDatasource.h" 10 | #import "NSDictionary+ImageMetadata.h" 11 | 12 | @implementation NSDictionary (MetadataDatasource) 13 | 14 | #pragma mark - TableView datasource 15 | 16 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 17 | { 18 | return [[self allKeys]count]; 19 | } 20 | 21 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 22 | { 23 | return [self sgg_numberOfRowsInSection:section]; 24 | } 25 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 26 | { 27 | return [self sgg_titleForSection:section]; 28 | } 29 | 30 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 31 | { 32 | static NSString *CellIdentifier = @"ImageMetadataCell"; 33 | UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 34 | if (!cell) 35 | { 36 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 37 | cell.detailTextLabel.adjustsFontSizeToFitWidth = YES; 38 | } 39 | 40 | NSString *property = [self sgg_propertyForIndexPath:indexPath]; 41 | cell.textLabel.text = property; 42 | 43 | if([property isEqualToString:(id)kCGImagePropertyExifShutterSpeedValue]) 44 | { 45 | cell.detailTextLabel.text = [self sgg_formattedShutterSpeed]; 46 | } 47 | else if([property isEqualToString:(id)kCGImagePropertyExifApertureValue]) 48 | { 49 | cell.detailTextLabel.text = [self sgg_formattedApetureValue]; 50 | } 51 | else{ 52 | cell.detailTextLabel.text = [self sgg_valueForPropertyAtIndexPath:indexPath]; 53 | } 54 | return cell; 55 | } 56 | 57 | - (NSUInteger)sgg_numberOfRowsInSection:(NSUInteger)section 58 | { 59 | NSInteger count = 1; 60 | NSString* key = [[self allKeys] objectAtIndex:section]; 61 | id result =[self objectForKey:key]; 62 | if([result isKindOfClass:[NSDictionary class]]){ 63 | count = [result count]; 64 | } 65 | return count; 66 | } 67 | 68 | - (NSString*)sgg_titleForSection:(NSUInteger)section 69 | { 70 | NSString* key = [[self allKeys] objectAtIndex:section]; 71 | NSString* metatdataSectionKey = [NSString stringWithFormat:@"%@",key]; 72 | 73 | if([metatdataSectionKey rangeOfString:@"{"].length>0){ 74 | return [[metatdataSectionKey stringByReplacingOccurrencesOfString:@"{" withString:@""]stringByReplacingOccurrencesOfString:@"}" withString:@""]; 75 | } 76 | return key; 77 | } 78 | 79 | #pragma mark - Indexpath Queries 80 | 81 | - (NSString *)sgg_propertyForIndexPath:(NSIndexPath*)indexPath 82 | { 83 | NSString* key = [[self allKeys] objectAtIndex:indexPath.section]; 84 | NSInteger rowsInSection = [self sgg_numberOfRowsInSection:indexPath.section]; 85 | if (rowsInSection==1) { 86 | return key; 87 | } 88 | else { 89 | NSDictionary* info =[self objectForKey:key]; 90 | NSArray* keys = [info allKeys]; 91 | NSString* str = [keys objectAtIndex:indexPath.row]; 92 | return str; 93 | } 94 | } 95 | 96 | - (NSString*)sgg_valueForPropertyAtIndexPath:(NSIndexPath*)indexPath 97 | { 98 | NSString* key = [[self allKeys] objectAtIndex:indexPath.section]; 99 | NSInteger rowsInSection = [self sgg_numberOfRowsInSection:indexPath.section]; 100 | if(rowsInSection==1){ 101 | NSDictionary* info =[self objectForKey:key]; 102 | return [NSString stringWithFormat:@"%@",info]; 103 | } 104 | NSDictionary* info =[self objectForKey:key]; 105 | NSArray* keys = [info allKeys]; 106 | NSString* str = [keys objectAtIndex:indexPath.row]; 107 | return [NSString stringWithFormat:@"%@",[info objectForKey:str]]; 108 | } 109 | 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #NSDictionary+ImageMetadata 2 | 3 | ##Description## 4 | 5 | **NSDictionary+ImageMetadata** and **NSDictionary-MetadataDatasource** are two categories for working with image metadata provided by the ImageIO framework. 6 | 7 | The complete list of properties can be found in the [CGImageProperties reference] (https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGImageProperties_Reference/Reference/reference.html) 8 | 9 | 10 | **NSDictionary+ImageMetadata** provides a simple interface for searching and working with metadata provided by ImageIO and AssetsLibrary frameworks. 11 | 12 | **NSDictionary-MetadataDatasource** builds upon ImageMetadata methods and provides NSIndexPath based interface as well as a simple UITableViewDatasource implementation. 13 | 14 | ##Usage## 15 | 16 | // Local Image 17 | NSDictionary *metadata = [NSDictionary imageMetadataWithImageAtURL:self.imageURL]; 18 | 19 | **Note: you can pass in a remote URL but the call is synchronous and with no error handling so it’s not recommended. 20 | 21 | or 22 | 23 | // ALAsset 24 | ALAssetRepresentation *myRep.... 25 | NSDictionary *metadata = [myRep metadata]; 26 | 27 | 28 | To obtain a value for a CGImageProperty request the key from the dictionary. 29 | 30 | NSString *apetureValue= [metadata sgg_valueForProperty:(id)kCGImagePropertyExifApertureValue]; 31 | 32 | 33 | NSDictionary-MetadataDatasource Example : 34 | 35 | -(void)viewDidLoad 36 | { 37 | [super viewDidLoad]; 38 | // keep a reference to the metadata since our tableview won’t retain it. 39 | self.metadata = [NSDictionary imageMetadataWithImageAtURL:self.imageURL]; 40 | self.tableView.dataSource = self.metadata; 41 | } 42 | 43 | ##License## 44 | NSDictionary+ImageMetadata and NSDictionary-MetadataDatasource is available under the MIT license. See the LICENSE file for more info. 45 | -------------------------------------------------------------------------------- /gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### Objective-C ### 4 | # Xcode 5 | # 6 | build/ 7 | *.pbxuser 8 | !default.pbxuser 9 | *.mode1v3 10 | !default.mode1v3 11 | *.mode2v3 12 | !default.mode2v3 13 | *.perspectivev3 14 | !default.perspectivev3 15 | xcuserdata 16 | *.xccheckout 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | *.xcuserstate 22 | 23 | # CocoaPods 24 | # 25 | # We recommend against adding the Pods directory to your .gitignore. However 26 | # you should judge for yourself, the pros and cons are mentioned at: 27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 28 | # 29 | # Pods/ 30 | 31 | --------------------------------------------------------------------------------