Repository: dzenbot/DZNEmptyDataSet Branch: master Commit: 9bffa69a83a9 Files: 190 Total size: 464.5 KB Directory structure: gitextract_vznosu_2/ ├── .codecov.yml ├── .gitignore ├── .travis.yml ├── DZNEmptyDataSet/ │ ├── Applications/ │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Application.h │ │ ├── Application.m │ │ ├── Assets.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── LaunchImage-2.launchimage/ │ │ │ │ └── Contents.json │ │ │ ├── LaunchImage-3.launchimage/ │ │ │ │ └── Contents.json │ │ │ ├── LaunchImage.launchimage/ │ │ │ │ └── Contents.json │ │ │ ├── button_background_foursquare_highlight.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── button_background_foursquare_normal.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── button_background_icloud_highlight.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── button_background_icloud_normal.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── button_background_kickstarter_highlight.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── button_background_kickstarter_normal.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── header_pinterest.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── header_podcasts.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_500px.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_airbnb.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_appstore.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_camera.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_dropbox.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_facebook.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_fancy.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_foursquare.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_icloud.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_instagram.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_itunes_connect.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_kickstarter.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_path.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_photos.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_pinterest.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_podcasts.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_remote.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_safari.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_skype.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_slack.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_tumblr.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_twitter.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_vesper.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_videos.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_vine.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_whatsapp.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── icon_wwdc.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── loading_imgBlue_78x78.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_500px.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_airbnb.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_dropbox.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_facebook.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_fancy.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_foursquare.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_instagram.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_kickstarter.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_path.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_pinterest.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_skype.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_slack.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_tumblr.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_twitter.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_vesper.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── logo_vine.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_500px.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_airbnb.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_appstore.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_dropbox.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_facebook.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_fancy.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_foursquare.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_instagram.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_itunes_connect.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_kickstarter.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_path.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_remote.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_skype.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_slack.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_tumblr.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_vesper.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_videos.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── placeholder_vine.imageset/ │ │ │ │ └── Contents.json │ │ │ └── placeholder_whatsapp.imageset/ │ │ │ └── Contents.json │ │ ├── DetailViewController.h │ │ ├── DetailViewController.m │ │ ├── Fonts/ │ │ │ └── Ideal Sans/ │ │ │ └── IdealSans-Book-Pro.otf │ │ ├── MainViewController.h │ │ ├── MainViewController.m │ │ ├── Supporting Files/ │ │ │ ├── Applications-Prefix.pch │ │ │ ├── Base.lproj/ │ │ │ │ └── LaunchScreen.storyboard │ │ │ ├── Info.plist │ │ │ ├── Storyboard.storyboard │ │ │ ├── en.lproj/ │ │ │ │ └── InfoPlist.strings │ │ │ └── main.m │ │ ├── UIColor+Hexadecimal.h │ │ ├── UIColor+Hexadecimal.m │ │ └── applications.json │ ├── Colors/ │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── LaunchImage.launchimage/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ └── LaunchScreen.storyboard │ │ ├── CollectionViewController.h │ │ ├── CollectionViewController.m │ │ ├── Colors/ │ │ │ ├── Colors-Info.plist │ │ │ ├── Colors-Prefix.pch │ │ │ ├── System.xcassets/ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── LaunchImage.launchimage/ │ │ │ │ └── Contents.json │ │ │ ├── en.lproj/ │ │ │ │ └── InfoPlist.strings │ │ │ └── main.m │ │ ├── DataSource/ │ │ │ ├── Color.h │ │ │ ├── Color.m │ │ │ ├── Palette.h │ │ │ ├── Palette.m │ │ │ ├── UIColor+Hex.h │ │ │ ├── UIColor+Hex.m │ │ │ └── colors.json │ │ ├── Images.xcassets/ │ │ │ ├── empty_placeholder.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── search_icon.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── tab_collection.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── tab_search.imageset/ │ │ │ │ └── Contents.json │ │ │ └── tab_table.imageset/ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── SearchViewController.h │ │ ├── SearchViewController.m │ │ ├── Storyboard.storyboard │ │ ├── TableViewController.h │ │ ├── TableViewController.m │ │ └── main.m │ ├── DZNEmptyDataSet/ │ │ ├── DZNEmptyDataSet.h │ │ └── Info.plist │ ├── DZNEmptyDataSet.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ ├── DZNEmptyDataSet.xcscheme │ │ └── DZNEmptyDataSetTests.xcscheme │ ├── DZNEmptyDataSet.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── DZNEmptyDataSetTests/ │ │ ├── ApplicationsSnapshotTests.m │ │ └── Info.plist │ ├── EmptyDataSetTests/ │ │ └── DZNEmptyDataSetTests-Bridging-Header.h │ ├── Podfile │ └── Pods/ │ ├── Pods.xcodeproj/ │ │ └── project.pbxproj │ ├── Target Support Files/ │ │ ├── Pods-DZNEmptyDataSetTests/ │ │ │ ├── Pods-DZNEmptyDataSetTests-Info.plist │ │ │ ├── Pods-DZNEmptyDataSetTests-acknowledgements.markdown │ │ │ ├── Pods-DZNEmptyDataSetTests-acknowledgements.plist │ │ │ ├── Pods-DZNEmptyDataSetTests-dummy.m │ │ │ ├── Pods-DZNEmptyDataSetTests-frameworks.sh │ │ │ ├── Pods-DZNEmptyDataSetTests-umbrella.h │ │ │ ├── Pods-DZNEmptyDataSetTests.debug.xcconfig │ │ │ ├── Pods-DZNEmptyDataSetTests.modulemap │ │ │ └── Pods-DZNEmptyDataSetTests.release.xcconfig │ │ ├── Pods-EmptyDataSetTests/ │ │ │ ├── Pods-EmptyDataSetTests-Info.plist │ │ │ ├── Pods-EmptyDataSetTests-acknowledgements.markdown │ │ │ ├── Pods-EmptyDataSetTests-acknowledgements.plist │ │ │ ├── Pods-EmptyDataSetTests-dummy.m │ │ │ ├── Pods-EmptyDataSetTests-frameworks.sh │ │ │ ├── Pods-EmptyDataSetTests-umbrella.h │ │ │ ├── Pods-EmptyDataSetTests.debug.xcconfig │ │ │ ├── Pods-EmptyDataSetTests.modulemap │ │ │ └── Pods-EmptyDataSetTests.release.xcconfig │ │ └── iOSSnapshotTestCase/ │ │ ├── Info.plist │ │ ├── iOSSnapshotTestCase-Info.plist │ │ ├── iOSSnapshotTestCase-dummy.m │ │ ├── iOSSnapshotTestCase-prefix.pch │ │ ├── iOSSnapshotTestCase-umbrella.h │ │ ├── iOSSnapshotTestCase.modulemap │ │ └── iOSSnapshotTestCase.xcconfig │ └── iOSSnapshotTestCase/ │ ├── FBSnapshotTestCase/ │ │ ├── Categories/ │ │ │ ├── UIImage+Compare.h │ │ │ ├── UIImage+Compare.m │ │ │ ├── UIImage+Diff.h │ │ │ ├── UIImage+Diff.m │ │ │ ├── UIImage+Snapshot.h │ │ │ └── UIImage+Snapshot.m │ │ ├── FBSnapshotTestCase.h │ │ ├── FBSnapshotTestCase.m │ │ ├── FBSnapshotTestCasePlatform.h │ │ ├── FBSnapshotTestCasePlatform.m │ │ ├── FBSnapshotTestController.h │ │ ├── FBSnapshotTestController.m │ │ └── SwiftSupport.swift │ ├── LICENSE │ └── README.md ├── DZNEmptyDataSet.podspec ├── Dangerfile ├── Gemfile ├── LICENSE ├── Package.swift ├── README.md └── Source/ ├── UIScrollView+EmptyDataSet.h └── UIScrollView+EmptyDataSet.m ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codecov.yml ================================================ codecov: token: coverage: precision: 2 round: nearest range: 70...100 ignore: - ./DZNEmptyDataSet/.* status: project: true patch: true changes: false comment: layout: "header, diff, tree, changes" behavior: default branches: master ================================================ FILE: .gitignore ================================================ # Xcode .DS_Store build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata profile *.moved-aside DerivedData .idea/ /.swiftpm ================================================ FILE: .travis.yml ================================================ osx_image: xcode11.3 language: objective-c sudo: required cache: - bundler - cocoapods before_install: - bundle install #- bundle exec danger env: global: - LANG=en_US.UTF-8 - WORKSPACE="DZNEmptyDataSet/DZNEmptyDataSet.xcworkspace" - IOS_SCHEME="DZNEmptyDataSet" - IOS_SDK="iphonesimulator13.3" matrix: - DESTINATION="OS=13.3,name=iPhone 8" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" script: - xcodebuild clean build test -scheme "$SCHEME" -workspace "$WORKSPACE" SDK="$IOS_SDK" -destination "$DESTINATION" -configuration Debug GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES after_success: - bash <(curl -s https://codecov.io/bash) ================================================ FILE: DZNEmptyDataSet/Applications/AppDelegate.h ================================================ // // AppDelegate.h // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: DZNEmptyDataSet/Applications/AppDelegate.m ================================================ // // AppDelegate.m // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "AppDelegate.h" #import "MainViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window.backgroundColor = [UIColor whiteColor]; return YES; } @end ================================================ FILE: DZNEmptyDataSet/Applications/Application.h ================================================ // // Application.h // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import typedef NS_ENUM(NSUInteger, ApplicationType) { ApplicationTypeUndefined = 0, ApplicationType500px = 1, ApplicationTypeAirbnb, ApplicationTypeAppstore, ApplicationTypeCamera, ApplicationTypeDropbox, ApplicationTypeFacebook, ApplicationTypeFancy, ApplicationTypeFoursquare, ApplicationTypeiCloud, ApplicationTypeInstagram, ApplicationTypeiTunesConnect, ApplicationTypeKickstarter, ApplicationTypePath, ApplicationTypePinterest, ApplicationTypePhotos, ApplicationTypePodcasts, ApplicationTypeRemote, ApplicationTypeSafari, ApplicationTypeSkype, ApplicationTypeSlack, ApplicationTypeTumblr, ApplicationTypeTwitter, ApplicationTypeVideos, ApplicationTypeVesper, ApplicationTypeVine, ApplicationTypeWhatsapp, ApplicationTypeWWDC, ApplicationCount // Used for count (27) }; @interface Application : NSObject @property (nonatomic, strong) NSString *displayName; @property (nonatomic, strong) NSString *developerName; @property (nonatomic, strong) NSString *identifier; @property (nonatomic, strong) NSString *iconName; @property (nonatomic) ApplicationType type; - (instancetype)initWithDictionary:(NSDictionary *)dict; + (NSArray *)applicationsFromJSONAtPath:(NSString *)path; + (NSArray *)applicationsFromJSON:(id)JSON; @end ================================================ FILE: DZNEmptyDataSet/Applications/Application.m ================================================ // // Application.m // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "Application.h" @implementation Application - (instancetype)initWithDictionary:(NSDictionary *)dict { self = [super init]; if (self) { self.displayName = dict[@"display_name"]; self.developerName = dict[@"developer_name"]; self.identifier = dict[@"identifier"]; } return self; } + (NSArray *)applicationsFromJSONAtPath:(NSString *)path { NSData *data = [NSData dataWithContentsOfFile:path]; NSArray *JSON = [[NSJSONSerialization JSONObjectWithData:data options:kNilOptions|NSJSONWritingPrettyPrinted error:nil] mutableCopy]; return [self applicationsFromJSON:JSON]; } + (NSArray *)applicationsFromJSON:(id)JSON { NSMutableArray *objects = [NSMutableArray new]; for (NSDictionary *dictionary in JSON) { Application *obj = [[Application alloc] initWithDictionary:dictionary]; [objects addObject:obj]; } return objects; } - (void)setDisplayName:(NSString *)displayName { _displayName = displayName; self.iconName = [[[NSString stringWithFormat:@"icon_%@", self.displayName] lowercaseString] stringByReplacingOccurrencesOfString:@" " withString:@"_"]; self.type = applicationTypeFromString(self.displayName) + 1; } ApplicationType applicationTypeFromString(NSString *string) { NSArray *arr = @[ @"500px", @"Airbnb", @"AppStore", @"Camera", @"Dropbox", @"Facebook", @"Fancy", @"Foursquare", @"iCloud", @"Instagram", @"iTunes Connect", @"Kickstarter", @"Path", @"Pinterest", @"Photos", @"Podcasts", @"Remote", @"Safari", @"Skype", @"Slack", @"Tumblr", @"Twitter", @"Videos", @"Vesper", @"Vine", @"WhatsApp", @"WWDC" ]; return (ApplicationType)[arr indexOfObject:string]; } @end ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@3x.png", "scale" : "3x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon-57.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon-57@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@3x.png", "scale" : "3x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "icon-29~ipad.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "icon-29@2x~ipad.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "icon-40~ipad.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "icon-40@2x~ipad.png", "scale" : "2x" }, { "size" : "50x50", "idiom" : "ipad", "filename" : "icon-50~ipad.png", "scale" : "1x" }, { "size" : "50x50", "idiom" : "ipad", "filename" : "icon-50@2x~ipad.png", "scale" : "2x" }, { "size" : "72x72", "idiom" : "ipad", "filename" : "icon-72~ipad.png", "scale" : "1x" }, { "size" : "72x72", "idiom" : "ipad", "filename" : "icon-72@2x~ipad.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "icon-76~ipad.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "icon-76@2x~ipad.png", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/LaunchImage-2.launchimage/Contents.json ================================================ { "images" : [ { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/LaunchImage-3.launchimage/Contents.json ================================================ { "images" : [ { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/LaunchImage.launchimage/Contents.json ================================================ { "images" : [ { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "736h", "filename" : "Default-hd-plus@2x.png", "minimum-system-version" : "8.0", "orientation" : "portrait", "scale" : "3x" }, { "orientation" : "landscape", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "8.0", "subtype" : "736h", "scale" : "3x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "667h", "filename" : "Default-hd@2x.png", "minimum-system-version" : "8.0", "orientation" : "portrait", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "filename" : "Default@2x.png", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "retina4", "filename" : "Default-568h@2x.png", "minimum-system-version" : "7.0", "orientation" : "portrait", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "filename" : "Default.png", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "iphone", "filename" : "Default@2x-1.png", "extent" : "full-screen", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "filename" : "Default-568h@2x-1.png", "extent" : "full-screen", "subtype" : "retina4", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/button_background_foursquare_highlight.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "button_background_foursquare_highlight.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "button_background_foursquare_highlight@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/button_background_foursquare_normal.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "button_background_foursquare_normal.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "button_background_foursquare_normal@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/button_background_icloud_highlight.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "button_background_icloud_highlight.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "button_background_icloud_highlight@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/button_background_icloud_normal.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "button_background_icloud_normal.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "button_background_icloud_normal@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/button_background_kickstarter_highlight.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "button_background_kickstarter_highlight.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "button_background_kickstarter_highlight@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/button_background_kickstarter_normal.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "button_background_kickstarter_normal.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "button_background_kickstarter_normal@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/header_pinterest.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "header_pinterest.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "header_pinterest@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/header_podcasts.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "header_podcasts.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "header_podcasts@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_500px.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_500px.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_500px@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_airbnb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_airbnb.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_airbnb@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_appstore.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_appstore.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_appstore@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_camera.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_camera.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_camera@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_dropbox.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_dropbox.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_dropbox@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_facebook.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_facebook.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_facebook@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_fancy.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_fancy.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_fancy@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_foursquare.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_foursquare.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_foursquare@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_icloud.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_icloud.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_icloud@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_instagram.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_instagram.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_instagram@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_itunes_connect.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_itunesconnect.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_itunesconnect@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_kickstarter.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_kickstarter.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_kickstarter@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_path.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_path.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_path@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_photos.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_photos.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_photos@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_pinterest.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_pinterest.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_pinterest@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_podcasts.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_podcasts.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_podcasts@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_remote.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_remote.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_remote@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_safari.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_safari.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_safari@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_skype.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_skype.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_skype@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_slack.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_slack.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_slack@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_tumblr.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_tumblr.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_tumblr@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_twitter.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_twitter.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_twitter@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_vesper.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_vesper.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_vesper@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_videos.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_videos.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_videos@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_vine.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_vine.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_vine@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_whatsapp.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_whatsapp.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_whatsapp@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/icon_wwdc.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "icon_wwdc.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "icon_wwdc@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/loading_imgBlue_78x78.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "loading_imgBlue_78x78@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "loading_imgBlue_78x78@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_500px.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_500px.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_500px@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_airbnb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_airbnb.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_airbnb@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_dropbox.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_dropbox.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_dropbox@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_facebook.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_facebook.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_facebook@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_fancy.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_fancy.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_fancy@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_foursquare.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_foursquare.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_foursquare@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_instagram.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_instagram.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_instagram@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_kickstarter.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_kickstarter.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_kickstarter@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_path.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_path.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_path@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_pinterest.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_pinterest.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_pinterest@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_skype.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_skype.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_skype@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_slack.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_slack.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_slack@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_tumblr.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_tumblr.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_tumblr@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_twitter.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_twitter.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_twitter@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_vesper.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_vesper.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_vesper@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/logo_vine.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "logo_vine.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "logo_vine@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_500px.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_500px.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_500px@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_airbnb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_airbnb.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_airbnb@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_appstore.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_appstore.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_appstore@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_dropbox.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_dropbox.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_dropbox@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_facebook.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_facebook.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_facebook@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_fancy.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_fancy.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_fancy@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_foursquare.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_foursquare.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_foursquare@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_instagram.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_instagram.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_instagram@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_itunes_connect.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_itunes_connect.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_itunes_connect@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_kickstarter.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_kickstarter.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_kickstarter@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_path.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_path.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_path@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_remote.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_remote.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_remote@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_skype.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_skype.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_skype@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_slack.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_slack.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_slack@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_tumblr.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_tumblr.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_tumblr@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_vesper.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_vesper.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_vesper@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_videos.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_videos.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_videos@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_vine.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_vine.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_vine@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/Assets.xcassets/placeholder_whatsapp.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "placeholder_whatsapp.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "placeholder_whatsapp@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Applications/DetailViewController.h ================================================ // // DetailViewController.h // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import #import "Application.h" @interface DetailViewController : UITableViewController @property (nonatomic, weak) NSArray *applications; @property (nonatomic) BOOL allowShuffling; - (instancetype)initWithApplication:(Application *)app; @end ================================================ FILE: DZNEmptyDataSet/Applications/DetailViewController.m ================================================ // // DetailViewController.m // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "DetailViewController.h" #import "UIColor+Hexadecimal.h" #import @interface DetailViewController () @property (nonatomic, strong) Application *application; @property (nonatomic, getter=isLoading) BOOL loading; @end @implementation DetailViewController - (instancetype)initWithApplication:(Application *)application { self = [super initWithStyle:UITableViewStylePlain]; if (self) { self.application = application; self.title = application.displayName; } return self; } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; self.edgesForExtendedLayout = UIRectEdgeNone; self.tableView.emptyDataSetSource = self; self.tableView.emptyDataSetDelegate = self; [self configureHeaderAndFooter]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self configureNavigationBar]; [self setNeedsStatusBarAppearanceUpdate]; } #pragma mark - Configuration and Event Methods - (void)configureNavigationBar { UIColor *barColor = nil; UIColor *tintColor = nil; self.navigationController.navigationBar.titleTextAttributes = nil; switch (self.application.type) { case ApplicationType500px: { barColor = [UIColor colorWithHex:@"242424"]; tintColor = [UIColor colorWithHex:@"d7d7d7"]; break; } case ApplicationTypeAirbnb: { barColor = [UIColor colorWithHex:@"f8f8f8"]; tintColor = [UIColor colorWithHex:@"08aeff"]; break; } case ApplicationTypeCamera: { barColor = [UIColor colorWithHex:@"595959"]; tintColor = [UIColor whiteColor]; self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: tintColor}; break; } case ApplicationTypeDropbox: { barColor = [UIColor whiteColor]; tintColor = [UIColor colorWithHex:@"007ee5"]; break; } case ApplicationTypeFacebook: { barColor = [UIColor colorWithHex:@"506da8"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeFancy: { barColor = [UIColor colorWithHex:@"353b49"]; tintColor = [UIColor colorWithHex:@"c4c7cb"]; break; } case ApplicationTypeFoursquare: { barColor = [UIColor colorWithHex:@"00aeef"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeInstagram: { barColor = [UIColor colorWithHex:@"2e5e86"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeKickstarter: { barColor = [UIColor colorWithHex:@"f7f8f8"]; tintColor = [UIColor colorWithHex:@"2bde73"]; break; } case ApplicationTypePath: { barColor = [UIColor colorWithHex:@"544f49"]; tintColor = [UIColor colorWithHex:@"fffff2"]; break; } case ApplicationTypePinterest: { barColor = [UIColor colorWithHex:@"f4f4f4"]; tintColor = [UIColor colorWithHex:@"cb2027"]; break; } case ApplicationTypeSlack: { barColor = [UIColor colorWithHex:@"f4f5f6"]; tintColor = [UIColor colorWithHex:@"3eba92"]; break; } case ApplicationTypeSkype: { barColor = [UIColor colorWithHex:@"00aff0"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeTumblr: { barColor = [UIColor colorWithHex:@"2e3e53"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeTwitter: { barColor = [UIColor colorWithHex:@"58aef0"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeVesper: { barColor = [UIColor colorWithHex:@"5e7d9a"]; tintColor = [UIColor colorWithHex:@"f8f8f8"]; break; } case ApplicationTypeVideos: { barColor = [UIColor colorWithHex:@"4a4b4d"]; tintColor = [UIColor blackColor]; break; } case ApplicationTypeVine: { barColor = [UIColor colorWithHex:@"00bf8f"]; tintColor = [UIColor whiteColor]; break; } case ApplicationTypeWWDC: { tintColor = [UIColor colorWithHex:@"fc6246"]; break; } default: barColor = [UIColor colorWithHex:@"f8f8f8"]; tintColor = [UIApplication sharedApplication].keyWindow.tintColor; break; } UIImage *logo = [UIImage imageNamed:[NSString stringWithFormat:@"logo_%@", [self.application.displayName lowercaseString]]]; if (logo) { self.navigationItem.titleView = [[UIImageView alloc] initWithImage:logo]; } else { self.navigationItem.titleView = nil; self.navigationItem.title = self.application.displayName; } self.navigationController.navigationBar.barTintColor = barColor; self.navigationController.navigationBar.tintColor = tintColor; } - (void)configureHeaderAndFooter { NSString *imageName = nil; if (self.application.type == ApplicationTypePinterest) { imageName = @"header_pinterest"; } if (self.application.type == ApplicationTypePodcasts) { imageName = @"header_podcasts"; } if (imageName) { UIImage *image = [UIImage imageNamed:imageName inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; imageView.userInteractionEnabled = YES; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapHeaderView:)]; [imageView addGestureRecognizer:tapGesture]; CGRect frame = self.view.bounds; frame.size.height = image.size.height; UIView *headerView = [[UIView alloc] initWithFrame:frame]; headerView.backgroundColor = [UIColor whiteColor]; imageView.center = CGPointMake(frame.size.width/2.0, frame.size.height/2.0); [headerView addSubview:imageView]; self.tableView.tableHeaderView = headerView; } else { self.tableView.tableHeaderView = [UIView new]; } self.tableView.tableFooterView = [UIView new]; } - (UIStatusBarStyle)preferredStatusBarStyle { switch (self.application.type) { case ApplicationType500px: case ApplicationTypeCamera: case ApplicationTypeFacebook: case ApplicationTypeFancy: case ApplicationTypeFoursquare: case ApplicationTypeInstagram: case ApplicationTypePath: case ApplicationTypeSkype: case ApplicationTypeTumblr: case ApplicationTypeTwitter: case ApplicationTypeVesper: case ApplicationTypeVine: return UIStatusBarStyleLightContent; default: return UIStatusBarStyleDefault; } } - (void)setAllowShuffling:(BOOL)allow { _allowShuffling = allow; UIBarButtonItem *rightItem = nil; if (allow) { rightItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(shuffle:)]; } self.navigationItem.rightBarButtonItem = rightItem; } - (void)didTapHeaderView:(id)sender { NSLog(@"%s",__FUNCTION__); } - (void)shuffle:(id)sender { Application *randomApp = [self randomApplication]; while ([randomApp.identifier isEqualToString:self.application.identifier] || randomApp.type == ApplicationTypeUndefined) { randomApp = [self randomApplication]; } self.application = randomApp; [self configureHeaderAndFooter]; [self configureNavigationBar]; [self.tableView reloadEmptyDataSet]; } - (Application *)randomApplication { ApplicationType randomType = arc4random() % ApplicationCount; NSPredicate *query = [NSPredicate predicateWithFormat:@"type == %d", randomType]; return [[self.applications filteredArrayUsingPredicate:query] firstObject]; } - (void)setLoading:(BOOL)loading { if (self.isLoading == loading) { return; } _loading = loading; [self.tableView reloadEmptyDataSet]; } #pragma mark - UITableViewDataSource Methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; } return cell; } #pragma mark - DZNEmptyDataSetSource Methods - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = nil; UIFont *font = nil; UIColor *textColor = nil; NSMutableDictionary *attributes = [NSMutableDictionary new]; switch (self.application.type) { case ApplicationType500px: { text = @"No Photos"; font = [UIFont boldSystemFontOfSize:17.0]; textColor = [UIColor colorWithHex:@"545454"]; break; } case ApplicationTypeAirbnb: { text = @"No Messages"; font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22.0]; textColor = [UIColor colorWithHex:@"c9c9c9"]; break; } case ApplicationTypeCamera: { text = @"Please Allow Photo Access"; font = [UIFont boldSystemFontOfSize:18.0]; textColor = [UIColor colorWithHex:@"5f6978"]; break; } case ApplicationTypeDropbox: { text = @"Star Your Favorite Files"; font = [UIFont boldSystemFontOfSize:17.0]; textColor = [UIColor colorWithHex:@"25282b"]; break; } case ApplicationTypeFacebook: { text = @"No friends to show."; font = [UIFont boldSystemFontOfSize:22.0]; textColor = [UIColor colorWithHex:@"acafbd"]; NSShadow *shadow = [NSShadow new]; shadow.shadowColor = [UIColor whiteColor]; shadow.shadowOffset = CGSizeMake(0.0, 1.0); [attributes setObject:shadow forKey:NSShadowAttributeName]; break; } case ApplicationTypeFancy: { text = @"No Owns yet"; font = [UIFont boldSystemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"494c53"]; break; } case ApplicationTypeiCloud: { text = @"iCloud Photo Sharing"; break; } case ApplicationTypeInstagram: { text = @"Instagram Direct"; font = [UIFont fontWithName:@"HelveticaNeue-Light" size:26.0]; textColor = [UIColor colorWithHex:@"444444"]; break; } case ApplicationTypeiTunesConnect: { text = @"No Favorites"; font = [UIFont systemFontOfSize:22.0]; break; } case ApplicationTypeKickstarter: { text = @"Activity empty"; font = [UIFont boldSystemFontOfSize:16.0]; textColor = [UIColor colorWithHex:@"828587"]; [attributes setObject:@(-0.10) forKey:NSKernAttributeName]; break; } case ApplicationTypePath: { text = @"Message Your Friends"; font = [UIFont boldSystemFontOfSize:14.0]; textColor = [UIColor whiteColor]; break; } case ApplicationTypePinterest: { text = @"No boards to display"; font = [UIFont boldSystemFontOfSize:18.0]; textColor = [UIColor colorWithHex:@"666666"]; break; } case ApplicationTypePhotos: { text = @"No Photos or Videos"; break; } case ApplicationTypePodcasts: { text = @"No Podcasts"; break; } case ApplicationTypeRemote: { text = @"Cannot Connect to a Local Network"; font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:18.0]; textColor = [UIColor colorWithHex:@"555555"]; break; } case ApplicationTypeTumblr: { text = @"This is your Dashboard."; font = [UIFont boldSystemFontOfSize:18.0]; textColor = [UIColor colorWithHex:@"aab6c4"]; break; } case ApplicationTypeTwitter: { text = @"No lists"; font = [UIFont boldSystemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"292f33"]; break; } case ApplicationTypeVesper: { text = @"No Notes"; font = [UIFont fontWithName:@"IdealSans-Book-Pro" size:16.0]; textColor = [UIColor colorWithHex:@"d9dce1"]; break; } case ApplicationTypeVideos: { text = @"AirPlay"; font = [UIFont systemFontOfSize:17.0]; textColor = [UIColor colorWithHex:@"414141"]; break; } case ApplicationTypeVine: { text = @"Welcome to VMs"; font = [UIFont boldSystemFontOfSize:22.0]; textColor = [UIColor colorWithHex:@"595959"]; [attributes setObject:@(0.45) forKey:NSKernAttributeName]; break; } case ApplicationTypeWhatsapp: { text = @"No Media"; font = [UIFont systemFontOfSize:20.0]; textColor = [UIColor colorWithHex:@"808080"]; break; } case ApplicationTypeWWDC: { text = @"No Favorites"; font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:16.0]; textColor = [UIColor colorWithHex:@"b9b9b9"]; break; } default: return nil; } if (!text) { return nil; } if (font) [attributes setObject:font forKey:NSFontAttributeName]; if (textColor) [attributes setObject:textColor forKey:NSForegroundColorAttributeName]; return [[NSAttributedString alloc] initWithString:text attributes:attributes]; } - (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = nil; UIFont *font = nil; UIColor *textColor = nil; NSMutableDictionary *attributes = [NSMutableDictionary new]; NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new]; paragraph.lineBreakMode = NSLineBreakByWordWrapping; paragraph.alignment = NSTextAlignmentCenter; switch (self.application.type) { case ApplicationType500px: { text = @"Get started by uploading a photo."; font = [UIFont boldSystemFontOfSize:15.0]; textColor = [UIColor colorWithHex:@"545454"]; break; } case ApplicationTypeAirbnb: { text = @"When you have messages, you’ll see them here."; font = [UIFont systemFontOfSize:13.0]; textColor = [UIColor colorWithHex:@"cfcfcf"]; paragraph.lineSpacing = 4.0; break; } case ApplicationTypeAppstore: { text = @"There are no results for “wwdc2014”."; font = [UIFont systemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"333333"]; break; } case ApplicationTypeCamera: { text = @"This allows you to share photos from your library and save photos to your camera roll."; font = [UIFont systemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"5f6978"]; break; } case ApplicationTypeDropbox: { text = @"Favorites are saved for offline access."; font = [UIFont systemFontOfSize:14.5]; textColor = [UIColor colorWithHex:@"7b8994"]; break; } case ApplicationTypeFancy: { text = @"Tap Add to List and add things to Owns"; font = [UIFont systemFontOfSize:13.0]; textColor = [UIColor colorWithHex:@"7a7d83"]; break; } case ApplicationTypeFoursquare: { text = @"Nobody has liked or commented on your check-ins yet."; font = [UIFont boldSystemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"cecbc6"]; break; } case ApplicationTypeiCloud: { text = @"Share photos and videos with just the people you choose, and let them add photos, videos, and comments."; paragraph.lineSpacing = 2.0; break; } case ApplicationTypeInstagram: { text = @"Send photos and videos directly to your friends. Only the people you send to can see these posts."; font = [UIFont systemFontOfSize:16.0]; textColor = [UIColor colorWithHex:@"444444"]; paragraph.lineSpacing = 4.0; break; } case ApplicationTypeiTunesConnect: { text = @"To add a favorite, tap the star icon next to an App's name."; font = [UIFont systemFontOfSize:14.0]; break; } case ApplicationTypeKickstarter: { text = @"When you back a project or follow a friend, their activity will show up here."; font = [UIFont systemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"828587"]; break; } case ApplicationTypePath: { text = @"Send a message or create a group."; font = [UIFont systemFontOfSize:14.0]; textColor = [UIColor colorWithHex:@"a6978d"]; break; } case ApplicationTypePhotos: { text = @"You can sync photos and videos onto your iPhone using iTunes."; break; } case ApplicationTypePodcasts: { text = @"You can subscribe to podcasts in Top Charts or Featured."; break; } case ApplicationTypeRemote: { text = @"You must connect to a Wi-Fi network to control iTunes or Apple TV"; font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:11.75]; textColor = [UIColor colorWithHex:@"555555"]; break; } case ApplicationTypeSafari: { text = @"Safari cannot open the page because your iPhone is not connected to the Internet."; textColor = [UIColor colorWithHex:@"7d7f7f"]; paragraph.lineSpacing = 2.0; break; } case ApplicationTypeSkype: { text = @"Keep all your favorite people together, add favorites."; font = [UIFont fontWithName:@"HelveticaNeue-Light" size:17.75]; textColor = [UIColor colorWithHex:@"a6c3d1"]; paragraph.lineSpacing = 3.0; break; } case ApplicationTypeSlack: { text = @"You don't have any recent mentions"; font = [UIFont fontWithName:@"Lato-Regular" size:19.0]; textColor = [UIColor colorWithHex:@"d7d7d7"]; break; } case ApplicationTypeTumblr: { text = @"When you follow some blogs, their latest posts will show up here!"; font = [UIFont systemFontOfSize:17.0]; textColor = [UIColor colorWithHex:@"828e9c"]; break; } case ApplicationTypeTwitter: { text = @"You aren’t subscribed to any lists yet."; font = [UIFont systemFontOfSize:12.0]; textColor = [UIColor colorWithHex:@"8899a6"]; break; } case ApplicationTypeVideos: { text = @"This video is playing on “Apple TV”."; font = [UIFont systemFontOfSize:12.0]; textColor = [UIColor colorWithHex:@"737373"]; break; } case ApplicationTypeVine: { text = @"This is where your private conversations will live"; font = [UIFont systemFontOfSize:17.0]; textColor = [UIColor colorWithHex:@"a6a6a6"]; break; } case ApplicationTypeWhatsapp: { text = @"You can exchange media with Ignacio by tapping on the Arrow Up icon in the conversation screen."; font = [UIFont systemFontOfSize:15.0]; textColor = [UIColor colorWithHex:@"989898"]; break; } case ApplicationTypeWWDC: { text = @"Favorites are only available to Registered Apple Developers."; font = [UIFont systemFontOfSize:16.0]; textColor = [UIColor colorWithHex:@"b9b9b9"]; break; } default: return nil; } if (!text) { return nil; } if (font) [attributes setObject:font forKey:NSFontAttributeName]; if (textColor) [attributes setObject:textColor forKey:NSForegroundColorAttributeName]; if (paragraph) [attributes setObject:paragraph forKey:NSParagraphStyleAttributeName]; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; switch (self.application.type) { case ApplicationTypeSkype: [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithHex:@"00adf1"] range:[attributedString.string rangeOfString:@"add favorites"]]; break; default: break; } return attributedString; } - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView { if (self.isLoading) { return [UIImage imageNamed:@"loading_imgBlue_78x78" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; } else { NSString *imageName = [[[NSString stringWithFormat:@"placeholder_%@", self.application.displayName] lowercaseString] stringByReplacingOccurrencesOfString:@" " withString:@"_"]; UIImage *image = [UIImage imageNamed:imageName inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; return image; } } - (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"]; animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; animation.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0) ]; animation.duration = 0.25; animation.cumulative = YES; animation.repeatCount = MAXFLOAT; return animation; } - (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { NSString *text = nil; UIFont *font = nil; UIColor *textColor = nil; switch (self.application.type) { case ApplicationTypeAirbnb: { text = @"Start Browsing"; font = [UIFont boldSystemFontOfSize:16.0]; textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"05adff" : @"6bceff"]; break; } case ApplicationTypeCamera: { text = @"Continue"; font = [UIFont boldSystemFontOfSize:17.0]; textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"007ee5" : @"48a1ea"]; break; } case ApplicationTypeDropbox: { text = @"Learn more"; font = [UIFont systemFontOfSize:15.0]; textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"007ee5" : @"48a1ea"]; break; } case ApplicationTypeFoursquare: { text = @"Add friends to get started!"; font = [UIFont boldSystemFontOfSize:14.0]; textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"00aeef" : @"ffffff"]; break; } case ApplicationTypeiCloud: { text = @"Create New Stream"; font = [UIFont systemFontOfSize:14.0]; textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"999999" : @"ebebeb"]; break; } case ApplicationTypeKickstarter: { text = @"Discover projects"; font = [UIFont boldSystemFontOfSize:14.0]; textColor = [UIColor whiteColor]; break; } case ApplicationTypeWWDC: { text = @"Sign In"; font = [UIFont systemFontOfSize:16.0]; textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"fc6246" : @"fdbbb2"]; break; } default: return nil; } if (!text) { return nil; } NSMutableDictionary *attributes = [NSMutableDictionary new]; if (font) [attributes setObject:font forKey:NSFontAttributeName]; if (textColor) [attributes setObject:textColor forKey:NSForegroundColorAttributeName]; return [[NSAttributedString alloc] initWithString:text attributes:attributes]; } - (UIImage *)buttonBackgroundImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { NSString *imageName = [[NSString stringWithFormat:@"button_background_%@", self.application.displayName] lowercaseString]; if (state == UIControlStateNormal) imageName = [imageName stringByAppendingString:@"_normal"]; if (state == UIControlStateHighlighted) imageName = [imageName stringByAppendingString:@"_highlight"]; UIEdgeInsets capInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0); UIEdgeInsets rectInsets = UIEdgeInsetsZero; switch (self.application.type) { case ApplicationTypeFoursquare: capInsets = UIEdgeInsetsMake(25.0, 25.0, 25.0, 25.0); rectInsets = UIEdgeInsetsMake(0.0, 10, 0.0, 10); break; case ApplicationTypeiCloud: rectInsets = UIEdgeInsetsMake(-19.0, -61.0, -19.0, -61.0); break; case ApplicationTypeKickstarter: capInsets = UIEdgeInsetsMake(22.0, 22.0, 22.0, 22.0); rectInsets = UIEdgeInsetsMake(0.0, -20, 0.0, -20); break; default: break; } UIImage *image = [UIImage imageNamed:imageName inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; return [[image resizableImageWithCapInsets:capInsets resizingMode:UIImageResizingModeStretch] imageWithAlignmentRectInsets:rectInsets]; } - (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView { switch (self.application.type) { case ApplicationType500px: return [UIColor blackColor]; case ApplicationTypeAirbnb: return [UIColor whiteColor]; case ApplicationTypeDropbox: return [UIColor colorWithHex:@"f0f3f5"]; case ApplicationTypeFacebook: return [UIColor colorWithHex:@"eceef7"]; case ApplicationTypeFancy: return [UIColor colorWithHex:@"f0f0f0"]; case ApplicationTypeFoursquare: return [UIColor colorWithHex:@"fcfcfa"]; case ApplicationTypeInstagram: return [UIColor whiteColor]; case ApplicationTypeKickstarter:return [UIColor colorWithHex:@"f7fafa"]; case ApplicationTypePath: return [UIColor colorWithHex:@"726d67"]; case ApplicationTypePinterest: return [UIColor colorWithHex:@"e1e1e1"]; case ApplicationTypeSlack: return [UIColor whiteColor]; case ApplicationTypeTumblr: return [UIColor colorWithHex:@"34465c"]; case ApplicationTypeTwitter: return [UIColor colorWithHex:@"f5f8fa"]; case ApplicationTypeVesper: return [UIColor colorWithHex:@"f8f8f8"]; case ApplicationTypeVideos: return [UIColor blackColor]; case ApplicationTypeWhatsapp: return [UIColor colorWithHex:@"f2f2f2"]; default: return nil; } } - (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView { if (self.application.type == ApplicationTypeKickstarter) { CGFloat offset = CGRectGetHeight([UIApplication sharedApplication].statusBarFrame); offset += CGRectGetHeight(self.navigationController.navigationBar.frame); return -offset; } if (self.application.type == ApplicationTypeTwitter) { return -roundf(self.tableView.frame.size.height/2.5); } return 0.0; } - (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView { switch (self.application.type) { case ApplicationType500px: return 9.0; case ApplicationTypeAirbnb: return 24.0; case ApplicationTypeAppstore: return 34.0; case ApplicationTypeFacebook: return 30.0; case ApplicationTypeFancy: return 1.0; case ApplicationTypeFoursquare: return 9.0; case ApplicationTypeInstagram: return 24.0; case ApplicationTypeiTunesConnect: return 9.0; case ApplicationTypeKickstarter: return 15.0; case ApplicationTypePath: return 1.0; case ApplicationTypePodcasts: return 35.0; case ApplicationTypeTumblr: return 10.0; case ApplicationTypeTwitter: return 0.1; case ApplicationTypeVesper: return 22.0; case ApplicationTypeVideos: return 0.1; case ApplicationTypeVine: return 0.1; case ApplicationTypeWWDC: return 18.0; default: return 0.0; } } #pragma mark - DZNEmptyDataSetDelegate Methods - (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView { return self.isLoading; } - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { self.loading = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.loading = NO; }); } - (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button { self.loading = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.loading = NO; }); } @end ================================================ FILE: DZNEmptyDataSet/Applications/MainViewController.h ================================================ // // MainViewController.h // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import #import "DetailViewController.h" #import "Application.h" @interface MainViewController : UITableViewController @end ================================================ FILE: DZNEmptyDataSet/Applications/MainViewController.m ================================================ // // MainViewController.m // Applications // // Created by Ignacio on 6/6/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "MainViewController.h" #import "UIColor+Hexadecimal.h" #import @interface MainViewController () @property (nonatomic, strong) NSArray *applications; @property (nonatomic, strong) UISearchController *searchController; @end @implementation MainViewController - (void)awakeFromNib { [super awakeFromNib]; NSString *path = [[NSBundle mainBundle] pathForResource:@"applications" ofType:@"json"]; self.applications = [Application applicationsFromJSONAtPath:path]; } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; self.title = @"Applications"; self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:NULL]; self.tableView.tableFooterView = [UIView new]; self.searchDisplayController.searchResultsTableView.emptyDataSetSource = self; self.searchDisplayController.searchResultsTableView.emptyDataSetDelegate = self; self.searchDisplayController.searchResultsTableView.tableFooterView = [UIView new]; [self.searchDisplayController setValue:@"" forKey:@"noResultsMessage"]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // Resets styling self.navigationController.navigationBar.titleTextAttributes = nil; self.navigationController.navigationBar.barTintColor = [UIColor colorWithHex:@"f8f8f8"];; self.navigationController.navigationBar.translucent = NO; self.navigationController.navigationBar.barStyle = UIBarStyleDefault; } #pragma mark - Getters - (NSArray *)filteredApps { UISearchBar *searchBar = self.searchDisplayController.searchBar; if ([searchBar isFirstResponder] && searchBar.text.length > 0) { NSPredicate *precidate = [NSPredicate predicateWithFormat:@"displayName CONTAINS[cd] %@", searchBar.text]; return [self.applications filteredArrayUsingPredicate:precidate]; } return self.applications; } #pragma mark - DZNEmptyDataSetSource Methods - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"No Application Found"; return [[NSAttributedString alloc] initWithString:text attributes:nil]; } - (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { UISearchBar *searchBar = self.searchDisplayController.searchBar; NSString *text = [NSString stringWithFormat:@"There are no empty dataset examples for \"%@\".", searchBar.text]; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:nil]; [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:17.0] range:[attributedString.string rangeOfString:searchBar.text]]; return attributedString; } - (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { NSString *text = @"Search on the App Store"; UIFont *font = [UIFont systemFontOfSize:16.0]; UIColor *textColor = [UIColor colorWithHex:(state == UIControlStateNormal) ? @"007aff" : @"c6def9"]; NSMutableDictionary *attributes = [NSMutableDictionary new]; [attributes setObject:font forKey:NSFontAttributeName]; [attributes setObject:textColor forKey:NSForegroundColorAttributeName]; return [[NSAttributedString alloc] initWithString:text attributes:attributes]; } - (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView { return [UIColor whiteColor]; } - (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView { return -64.0; } #pragma mark - DZNEmptyDataSetDelegate Methods - (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return YES; } - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { NSLog(@"%s",__FUNCTION__); } - (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button { UISearchBar *searchBar = self.searchDisplayController.searchBar; NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.com/apps/%@", searchBar.text]]; if ([[UIApplication sharedApplication] canOpenURL:URL]) { [[UIApplication sharedApplication] openURL:URL]; } } #pragma mark - UITableViewDataSource Methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger rowCount = [self filteredApps].count; return rowCount; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"app_cell_identifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; } Application *app = [[self filteredApps] objectAtIndex:indexPath.row]; cell.textLabel.text = app.displayName; cell.detailTextLabel.text = app.developerName; UIImage *image = [UIImage imageNamed:app.iconName]; cell.imageView.image = image; cell.imageView.layer.cornerRadius = image.size.width*0.2; cell.imageView.layer.masksToBounds = YES; cell.imageView.layer.borderColor = [UIColor colorWithWhite:0.0 alpha:0.2].CGColor; cell.imageView.layer.borderWidth = 0.5; cell.imageView.layer.shouldRasterize = YES; cell.imageView.layer.rasterizationScale = [UIScreen mainScreen].scale; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 70.0; } #pragma mark - UITableViewDelegate Methods - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { Application *app = [[self filteredApps] objectAtIndex:indexPath.row]; DetailViewController *controller = [[DetailViewController alloc] initWithApplication:app]; controller.applications = self.applications; controller.allowShuffling = YES; if ([controller preferredStatusBarStyle] == UIStatusBarStyleLightContent) { self.navigationController.navigationBar.barStyle = UIBarStyleBlack; } [self.navigationController pushViewController:controller animated:YES]; } #pragma mark - UISearchBarDelegate Methods - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { return YES; } - (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar { return YES; } - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { // Do something } - (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar { // Do something } - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { // Do something } - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { // Do something } - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { // Do something } #pragma mark - UISearchDisplayDelegate Methods - (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller { // Do something } - (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller { // Do something } - (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView { // Do something } - (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView { // Do something } #pragma mark - View Auto-Rotation - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleDefault; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } - (BOOL)shouldAutorotate { return YES; } @end ================================================ FILE: DZNEmptyDataSet/Applications/Supporting Files/Applications-Prefix.pch ================================================ // // Prefix header // // The contents of this file are implicitly included at the beginning of every source file. // #import #ifndef __IPHONE_5_0 #warning "This project uses features only available in iOS SDK 5.0 and later." #endif #ifdef __OBJC__ #import #import #endif ================================================ FILE: DZNEmptyDataSet/Applications/Supporting Files/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: DZNEmptyDataSet/Applications/Supporting Files/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleVersion 1 LSRequiresIPhoneOS UIAppFonts IdealSans-Book-Pro.otf Lato-Regular.ttf UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Storyboard UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: DZNEmptyDataSet/Applications/Supporting Files/Storyboard.storyboard ================================================ ================================================ FILE: DZNEmptyDataSet/Applications/Supporting Files/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: DZNEmptyDataSet/Applications/Supporting Files/main.m ================================================ // // main.m // Applications // // Created by Ignacio Romero on 2/28/17. // Copyright © 2017 DZN. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: DZNEmptyDataSet/Applications/UIColor+Hexadecimal.h ================================================ // // UIColor+Hexadecimal.h // Applications // // Created by Ignacio on 6/7/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @interface UIColor (Hexadecimal) + (UIColor *)colorWithHex:(NSString *)string; @end ================================================ FILE: DZNEmptyDataSet/Applications/UIColor+Hexadecimal.m ================================================ // // UIColor+Hexadecimal.m // Applications // // Created by Ignacio on 6/7/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "UIColor+Hexadecimal.h" @implementation UIColor (Hexadecimal) + (UIColor *)colorWithHex:(NSString *)string { NSString *cleanString = [string stringByReplacingOccurrencesOfString:@"#" withString:@""]; if([cleanString length] == 3) { cleanString = [NSString stringWithFormat:@"%@%@%@%@%@%@", [cleanString substringWithRange:NSMakeRange(0, 1)],[cleanString substringWithRange:NSMakeRange(0, 1)], [cleanString substringWithRange:NSMakeRange(1, 1)],[cleanString substringWithRange:NSMakeRange(1, 1)], [cleanString substringWithRange:NSMakeRange(2, 1)],[cleanString substringWithRange:NSMakeRange(2, 1)]]; } if([cleanString length] == 6) { cleanString = [cleanString stringByAppendingString:@"ff"]; } unsigned int baseValue; [[NSScanner scannerWithString:cleanString] scanHexInt:&baseValue]; float red = ((baseValue >> 24) & 0xFF)/255.0f; float green = ((baseValue >> 16) & 0xFF)/255.0f; float blue = ((baseValue >> 8) & 0xFF)/255.0f; return [UIColor colorWithRed:red green:green blue:blue alpha:1.0]; } @end ================================================ FILE: DZNEmptyDataSet/Applications/applications.json ================================================ [ { "display_name": "500px", "developer_name": "500px", "identifier": "471965292" }, { "display_name": "Airbnb", "developer_name": "Airbnb, Inc.", "identifier": "401626263" }, { "display_name": "AppStore", "developer_name": "Apple, Inc.", "identifier": "" }, { "display_name": "Camera", "developer_name": "Apple, Inc.", "identifier": "" }, { "display_name": "Dropbox", "developer_name": "Dropbox, Inc.", "identifier": "327630330" }, { "display_name": "Facebook", "developer_name": "Facebook, Inc.", "identifier": "284882215" }, { "display_name": "Fancy", "developer_name": "Thing Daemon, Inc.", "identifier": "407324335" }, { "display_name": "Foursquare", "developer_name": "Foursquare Labs", "identifier": "306934924" }, { "display_name": "iCloud", "developer_name": "Apple, Inc.", "identifier": "" }, { "display_name": "Instagram", "developer_name": "Instagram, Inc.", "identifier": "389801252" }, { "display_name": "iTunes Connect", "developer_name": "Apple, Inc.", "identifier": "376771144" }, { "display_name": "Kickstarter", "developer_name": "Kickstarter, Inc.", "identifier": "596961532" }, { "display_name": "Path", "developer_name": "Path, Inc.", "identifier": "403639508" }, { "display_name": "Pinterest", "developer_name": "Pinterest, Inc.", "identifier": "429047995" }, { "display_name": "Photos", "developer_name": "Apple, Inc.", "identifier": "" }, { "display_name": "Podcasts", "developer_name": "Apple, Inc.", "identifier": "525463029" }, { "display_name": "Remote", "developer_name": "Apple, Inc.", "identifier": "284417350" }, { "display_name": "Safari", "developer_name": "Apple, Inc.", "identifier": "" }, { "display_name": "Skype", "developer_name": "Skype Communications S.a.r.l", "identifier": "304878510" }, { "display_name": "Slack", "developer_name": "Tiny Speck, Inc.", "identifier": "618783545" }, { "display_name": "Tumblr", "developer_name": "Tumblr, Inc.", "identifier": "305343404" }, { "display_name": "Twitter", "developer_name": "Twitter, Inc.", "identifier": "333903271" }, { "display_name": "Vesper", "developer_name": "Q Branch", "identifier": "655895325" }, { "display_name": "Videos", "developer_name": "Apple, Inc.", "identifier": "" }, { "display_name": "Vine", "developer_name": "Vine Labs, Inc.", "identifier": "592447445" }, { "display_name": "WhatsApp", "developer_name": "WhatsApp, Inc.", "identifier": "310633997" }, { "display_name": "WWDC", "developer_name": "Apple, Inc.", "identifier": "640199958" }, ] ================================================ FILE: DZNEmptyDataSet/Colors/AppDelegate.h ================================================ // // AppDelegate.h // Colors // // Created by Ignacio Romero Z. on 6/19/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: DZNEmptyDataSet/Colors/AppDelegate.m ================================================ // // AppDelegate.m // Colors // // Created by Ignacio Romero Z. on 6/19/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "AppDelegate.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window.backgroundColor = [UIColor whiteColor]; return YES; } @end ================================================ FILE: DZNEmptyDataSet/Colors/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@3x.png", "scale" : "3x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon-57.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon-57@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@3x.png", "scale" : "3x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "icon-29~ipad.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "icon-29@2x~ipad.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "icon-40~ipad.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "icon-40@2x~ipad.png", "scale" : "2x" }, { "size" : "50x50", "idiom" : "ipad", "filename" : "icon-50~ipad.png", "scale" : "1x" }, { "size" : "50x50", "idiom" : "ipad", "filename" : "icon-50@2x~ipad.png", "scale" : "2x" }, { "size" : "72x72", "idiom" : "ipad", "filename" : "icon-72~ipad.png", "scale" : "1x" }, { "size" : "72x72", "idiom" : "ipad", "filename" : "icon-72@2x~ipad.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "icon-76~ipad.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "icon-76@2x~ipad.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "icon-120~car.png", "scale" : "2x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Assets.xcassets/LaunchImage.launchimage/Contents.json ================================================ { "images" : [ { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "736h", "filename" : "Default-hd-plus@2x.png", "minimum-system-version" : "8.0", "orientation" : "portrait", "scale" : "3x" }, { "orientation" : "landscape", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "8.0", "subtype" : "736h", "scale" : "3x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "667h", "filename" : "Default-hd@2x.png", "minimum-system-version" : "8.0", "orientation" : "portrait", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "7.0", "filename" : "Default@2x.png", "scale" : "2x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "retina4", "filename" : "Default-568h@2x.png", "minimum-system-version" : "7.0", "orientation" : "portrait", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "subtype" : "retina4", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: DZNEmptyDataSet/Colors/CollectionViewController.h ================================================ // // CollectionViewController.h // Colors // // Created by Ignacio Romero Z. on 6/19/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @interface CollectionViewController : UICollectionViewController - (IBAction)refreshColors:(id)sender; - (IBAction)removeColors:(id)sender; @end ================================================ FILE: DZNEmptyDataSet/Colors/CollectionViewController.m ================================================ // // CollectionViewController.m // Colors // // Created by Ignacio Romero Z. on 6/19/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "CollectionViewController.h" #import "SearchViewController.h" #import "Palette.h" #import "Color.h" #import #define kColumnCountMax 7 #define kColumnCountMin 5 static NSString *CellIdentifier = @"ColorViewCell"; @interface CollectionViewController () @property (nonatomic) NSInteger columnCount; @property (nonatomic, strong) NSMutableArray *filteredPalette; @end @implementation CollectionViewController #pragma mark - View lifecycle - (void)awakeFromNib { [super awakeFromNib]; self.title = @"Collection"; self.tabBarItem = [[UITabBarItem alloc] initWithTitle:self.title image:[UIImage imageNamed:@"tab_collection"] tag:self.title.hash]; } - (void)viewDidLoad { [super viewDidLoad]; UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionViewLayout; layout.minimumLineSpacing = 2.0; layout.minimumInteritemSpacing = 2; layout.scrollDirection = UICollectionViewScrollDirectionVertical; CGFloat inset = layout.minimumLineSpacing*1.5; self.collectionView.contentInset = UIEdgeInsetsMake(inset, 0.0, inset, 0.0); self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0); [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier]; self.collectionView.emptyDataSetSource = self; self.collectionView.emptyDataSetDelegate = self; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } #pragma mark - Getters - (NSInteger)columnCount { return UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? kColumnCountMax : kColumnCountMin; } - (CGSize)cellSize { UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; CGFloat size = (self.navigationController.view.bounds.size.width/self.columnCount) - flowLayout.minimumLineSpacing; return CGSizeMake(size, size); } - (NSMutableArray *)filteredPalette { // Randomly filtered palette if (!_filteredPalette) { _filteredPalette = [[NSMutableArray alloc] initWithArray:[[Palette sharedPalette] colors]]; for (NSInteger i = _filteredPalette.count-1; i > 0; i--) { [_filteredPalette exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform(i+1.0)]; } } return _filteredPalette; } #pragma mark - Actions - (IBAction)refreshColors:(id)sender { [[Palette sharedPalette] reloadAll]; [self setFilteredPalette:nil]; [self.collectionView reloadData]; } - (IBAction)removeColors:(id)sender { [[Palette sharedPalette] removeAll]; [_filteredPalette removeAllObjects]; [self.collectionView reloadData]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"collection_push_detail"]) { SearchViewController *controller = [segue destinationViewController]; controller.selectedColor = sender; } } #pragma mark - DZNEmptyDataSetSource Methods - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"No colors loaded"; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0], NSForegroundColorAttributeName: [UIColor colorWithRed:170/255.0 green:171/255.0 blue:179/255.0 alpha:1.0], NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"To show a list of random colors, tap on the refresh icon in the right top corner.\n\nTo clean the list, tap on the trash icon."; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:15.0], NSForegroundColorAttributeName: [UIColor colorWithRed:170/255.0 green:171/255.0 blue:179/255.0 alpha:1.0], NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { return nil; } - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView { return [UIImage imageNamed:@"empty_placeholder"]; } - (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView { return [UIColor whiteColor]; } - (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView { return nil; } - (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView { return 0; } #pragma mark - DZNEmptyDataSetSource Methods - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return YES; } - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { NSLog(@"%s",__FUNCTION__); } - (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button { NSLog(@"%s",__FUNCTION__); } #pragma mark - UICollectionViewDataSource methods - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return [self.filteredPalette count]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath]; cell.selectedBackgroundView = [UIView new]; cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.25]; Color *color = self.filteredPalette[indexPath.row]; cell.backgroundColor = color.color; return cell; } #pragma mark - UICollectionViewDataDelegate methods - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { Color *color = self.filteredPalette[indexPath.row]; if ([self shouldPerformSegueWithIdentifier:@"collection_push_detail" sender:color]) { [self performSegueWithIdentifier:@"collection_push_detail" sender:color]; } } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return [self cellSize]; } - (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) { return YES; } return NO; } - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) { Color *color = self.filteredPalette[indexPath.row]; if (color.hex.length > 0) [[UIPasteboard generalPasteboard] setString:color.hex]; } }); } #pragma mark - View Auto-Rotation - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (![UIInputViewController class]) { [self.collectionView reloadData]; } } - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id)coordinator { [self.collectionView reloadData]; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } - (BOOL)shouldAutorotate { return YES; } @end ================================================ FILE: DZNEmptyDataSet/Colors/Colors/Colors-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIcons CFBundleIcons~ipad CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 LSRequiresIPhoneOS UIMainStoryboardFile Storyboard UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: DZNEmptyDataSet/Colors/Colors/Colors-Prefix.pch ================================================ // // Prefix header // // The contents of this file are implicitly included at the beginning of every source file. // #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 ================================================ FILE: DZNEmptyDataSet/Colors/Colors/System.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@3x.png", "scale" : "3x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon-57.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon-57@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "icon-29~ipad.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "icon-29@2x~ipad.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "icon-40~ipad.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "icon-40@2x~ipad.png", "scale" : "2x" }, { "size" : "50x50", "idiom" : "ipad", "filename" : "icon-50~ipad.png", "scale" : "1x" }, { "size" : "50x50", "idiom" : "ipad", "filename" : "icon-50@2x~ipad.png", "scale" : "2x" }, { "size" : "72x72", "idiom" : "ipad", "filename" : "icon-72~ipad.png", "scale" : "1x" }, { "size" : "72x72", "idiom" : "ipad", "filename" : "icon-72@2x~ipad.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "icon-76~ipad.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "icon-76@2x~ipad.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "icon-120~car.png", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Colors/System.xcassets/LaunchImage.launchimage/Contents.json ================================================ { "images" : [ { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "736h", "filename" : "Default-hd-plus@2x.png", "minimum-system-version" : "8.0", "orientation" : "portrait", "scale" : "3x" }, { "orientation" : "landscape", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "8.0", "subtype" : "736h", "scale" : "3x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "667h", "filename" : "Default-hd@2x.png", "minimum-system-version" : "8.0", "orientation" : "portrait", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "7.0", "filename" : "Default@2x.png", "scale" : "2x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "retina4", "filename" : "Default-568h@2x.png", "minimum-system-version" : "7.0", "orientation" : "portrait", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "subtype" : "retina4", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "to-status-bar", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Colors/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: DZNEmptyDataSet/Colors/Colors/main.m ================================================ // // main.m // Colors // // Created by Ignacio Romero Z. on 6/19/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/Color.h ================================================ // // Palette.h // Colors // // Created by Ignacio Romero Z. on 7/4/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @interface Color : NSObject @property (nonatomic, strong) NSString *hex; @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *rgb; @property (nonatomic, weak) UIColor *color; - (instancetype)initWithDictionary:(NSDictionary *)dict; + (UIImage *)roundThumbWithColor:(UIColor *)color; + (UIImage *)roundImageForSize:(CGSize)size withColor:(UIColor *)color; @end ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/Color.m ================================================ // // Palette.m // Colors // // Created by Ignacio Romero Z. on 7/4/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "Color.h" #import "UIColor+Hex.h" @implementation Color - (instancetype)initWithDictionary:(NSDictionary *)dict { if (!dict) { return nil; } self = [super init]; if (self) { self.hex = [dict objectForKey:@"hex"]; self.name = [dict objectForKey:@"name"]; self.rgb = [dict objectForKey:@"rgb"]; } return self; } - (UIColor *)color { return [UIColor colorFromHex:self.hex]; } + (UIImage *)roundThumbWithColor:(UIColor *)color { return [self roundImageForSize:CGSizeMake(32.0, 32.0) withColor:color]; } + (UIImage *)roundImageForSize:(CGSize)size withColor:(UIColor *)color { if (!color) { return nil; } // Constants CGRect bounds = CGRectMake(0, 0, size.width, size.height); // Create the image context UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); //// Oval Drawing UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect:bounds]; [color setFill]; [ovalPath fill]; //Create the image using the current context. UIImage *_image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return _image; } @end ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/Palette.h ================================================ // // ColorPalette.h // Colors // // Created by Ignacio Romero Z. on 7/1/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @class Color; @interface Palette : NSObject @property (nonatomic, readonly) NSMutableArray *colors; + (instancetype)sharedPalette; - (void)reloadAll; - (void)removeColor:(Color *)color; - (void)removeAll; @end ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/Palette.m ================================================ // // ColorSource.m // Colors // // Created by Ignacio Romero Z. on 7/1/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "Palette.h" #import "Color.h" @interface Palette () @end static Palette *_sharedPalette = nil; @implementation Palette @synthesize colors = _colors; + (instancetype)sharedPalette { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedPalette = [[Palette alloc] init]; [_sharedPalette loadColors]; }); return _sharedPalette; } - (void)loadColors { // A list of crayola colors in JSON by Jjdelc https://gist.github.com/jjdelc/1868136 NSString *path = [[NSBundle mainBundle] pathForResource:@"colors" ofType:@"json"]; NSData *data = [NSData dataWithContentsOfFile:path]; NSArray *objects = [[NSJSONSerialization JSONObjectWithData:data options:kNilOptions|NSJSONWritingPrettyPrinted error:nil] mutableCopy]; _colors = [[NSMutableArray alloc] initWithCapacity:objects.count]; for (NSDictionary *dictionary in objects) { Color *color = [[Color alloc] initWithDictionary:dictionary]; [_colors addObject:color]; } } - (void)reloadAll { [self removeAll]; [self loadColors]; } - (void)removeColor:(Color *)color { NSInteger idx = [_colors indexOfObject:color]; if (idx >= 0 && idx < _colors.count) { [_colors removeObjectAtIndex:idx]; } } - (void)removeAll { [_colors removeAllObjects]; _colors = nil; } @end ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/UIColor+Hex.h ================================================ // // UIColor+Hex.h // Colors // // Created by Ignacio Romero on 4/26/16. // Copyright © 2016 DZN Labs. All rights reserved. // #import @interface UIColor (Hex) + (UIColor *)colorFromHex:(NSString *)hex; @end ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/UIColor+Hex.m ================================================ // // UIColor+Hex.m // Colors // // Created by Ignacio Romero on 4/26/16. // Copyright © 2016 DZN Labs. All rights reserved. // #import "UIColor+Hex.h" @implementation UIColor (Hex) + (UIColor *)colorFromHex:(NSString *)hex { return [self colorFromHex:hex alpha:1.0]; } + (UIColor *)colorFromHex:(NSString *)hex alpha:(CGFloat)alpha { NSUInteger offset = 0; if ([hex hasPrefix:@"#"]) { offset = 1; } NSString *string = [hex substringFromIndex:offset]; if (string.length == 3) { string = [NSString stringWithFormat:@"%@%@%@%@%@%@", [string substringWithRange:NSMakeRange(0, 1)], [string substringWithRange:NSMakeRange(0, 1)], [string substringWithRange:NSMakeRange(1, 1)], [string substringWithRange:NSMakeRange(1, 1)], [string substringWithRange:NSMakeRange(2, 1)], [string substringWithRange:NSMakeRange(2, 1)]]; } if (string.length == 6) { string = [string stringByAppendingString:@"ff"]; } if (string == nil) { return nil; } unsigned int baseValue; [[NSScanner scannerWithString:string] scanHexInt:&baseValue]; float red = ((baseValue >> 24) & 0xFF)/255.0f; float green = ((baseValue >> 16) & 0xFF)/255.0f; float blue = ((baseValue >> 8) & 0xFF)/255.0f; return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; } @end ================================================ FILE: DZNEmptyDataSet/Colors/DataSource/colors.json ================================================ [ { "hex": "EFDECD", "name": "Almond", "rgb": "(239, 222, 205)" }, { "hex": "CD9575", "name": "Antique Brass", "rgb": "(205, 149, 117)" }, { "hex": "FDD9B5", "name": "Apricot", "rgb": "(253, 217, 181)" }, { "hex": "78DBE2", "name": "Aquamarine", "rgb": "(120, 219, 226)" }, { "hex": "87A96B", "name": "Asparagus", "rgb": "(135, 169, 107)" }, { "hex": "FFA474", "name": "Atomic Tangerine", "rgb": "(255, 164, 116)" }, { "hex": "FAE7B5", "name": "Banana Mania", "rgb": "(250, 231, 181)" }, { "hex": "9F8170", "name": "Beaver", "rgb": "(159, 129, 112)" }, { "hex": "FD7C6E", "name": "Bittersweet", "rgb": "(253, 124, 110)" }, { "hex": "000000", "name": "Black", "rgb": "(0,0,0)" }, { "hex": "ACE5EE", "name": "Blizzard Blue", "rgb": "(172, 229, 238)" }, { "hex": "1F75FE", "name": "Blue", "rgb": "(31, 117, 254)" }, { "hex": "A2A2D0", "name": "Blue Bell", "rgb": "(162, 162, 208)" }, { "hex": "6699CC", "name": "Blue Gray", "rgb": "(102, 153, 204)" }, { "hex": "0D98BA", "name": "Blue Green", "rgb": "(13, 152, 186)" }, { "hex": "7366BD", "name": "Blue Violet", "rgb": "(115, 102, 189)" }, { "hex": "DE5D83", "name": "Blush", "rgb": "(222, 93, 131)" }, { "hex": "CB4154", "name": "Brick Red", "rgb": "(203, 65, 84)" }, { "hex": "B4674D", "name": "Brown", "rgb": "(180, 103, 77)" }, { "hex": "FF7F49", "name": "Burnt Orange", "rgb": "(255, 127, 73)" }, { "hex": "EA7E5D", "name": "Burnt Sienna", "rgb": "(234, 126, 93)" }, { "hex": "B0B7C6", "name": "Cadet Blue", "rgb": "(176, 183, 198)" }, { "hex": "FFFF99", "name": "Canary", "rgb": "(255, 255, 153)" }, { "hex": "1CD3A2", "name": "Caribbean Green", "rgb": "(28, 211, 162)" }, { "hex": "FFAACC", "name": "Carnation Pink", "rgb": "(255, 170, 204)" }, { "hex": "DD4492", "name": "Cerise", "rgb": "(221, 68, 146)" }, { "hex": "1DACD6", "name": "Cerulean", "rgb": "(29, 172, 214)" }, { "hex": "BC5D58", "name": "Chestnut", "rgb": "(188, 93, 88)" }, { "hex": "DD9475", "name": "Copper", "rgb": "(221, 148, 117)" }, { "hex": "9ACEEB", "name": "Cornflower", "rgb": "(154, 206, 235)" }, { "hex": "FFBCD9", "name": "Cotton Candy", "rgb": "(255, 188, 217)" }, { "hex": "FDDB6D", "name": "Dandelion", "rgb": "(253, 219, 109)" }, { "hex": "2B6CC4", "name": "Denim", "rgb": "(43, 108, 196)" }, { "hex": "EFCDB8", "name": "Desert Sand", "rgb": "(239, 205, 184)" }, { "hex": "6E5160", "name": "Eggplant", "rgb": "(110, 81, 96)" }, { "hex": "CEFF1D", "name": "Electric Lime", "rgb": "(206, 255, 29)" }, { "hex": "71BC78", "name": "Fern", "rgb": "(113, 188, 120)" }, { "hex": "6DAE81", "name": "Forest Green", "rgb": "(109, 174, 129)" }, { "hex": "C364C5", "name": "Fuchsia", "rgb": "(195, 100, 197)" }, { "hex": "CC6666", "name": "Fuzzy Wuzzy", "rgb": "(204, 102, 102)" }, { "hex": "E7C697", "name": "Gold", "rgb": "(231, 198, 151)" }, { "hex": "FCD975", "name": "Goldenrod", "rgb": "(252, 217, 117)" }, { "hex": "A8E4A0", "name": "Granny Smith Apple", "rgb": "(168, 228, 160)" }, { "hex": "95918C", "name": "Gray", "rgb": "(149, 145, 140)" }, { "hex": "1CAC78", "name": "Green", "rgb": "(28, 172, 120)" }, { "hex": "1164B4", "name": "Green Blue", "rgb": "(17, 100, 180)" }, { "hex": "F0E891", "name": "Green Yellow", "rgb": "(240, 232, 145)" }, { "hex": "FF1DCE", "name": "Hot Magenta", "rgb": "(255, 29, 206)" }, { "hex": "B2EC5D", "name": "Inchworm", "rgb": "(178, 236, 93)" }, { "hex": "5D76CB", "name": "Indigo", "rgb": "(93, 118, 203)" }, { "hex": "CA3767", "name": "Jazzberry Jam", "rgb": "(202, 55, 103)" }, { "hex": "3BB08F", "name": "Jungle Green", "rgb": "(59, 176, 143)" }, { "hex": "FEFE22", "name": "Laser Lemon", "rgb": "(254, 254, 34)" }, { "hex": "FCB4D5", "name": "Lavender", "rgb": "(252, 180, 213)" }, { "hex": "FFF44F", "name": "Lemon Yellow", "rgb": "(255, 244, 79)" }, { "hex": "FFBD88", "name": "Macaroni and Cheese", "rgb": "(255, 189, 136)" }, { "hex": "F664AF", "name": "Magenta", "rgb": "(246, 100, 175)" }, { "hex": "AAF0D1", "name": "Magic Mint", "rgb": "(170, 240, 209)" }, { "hex": "CD4A4C", "name": "Mahogany", "rgb": "(205, 74, 76)" }, { "hex": "EDD19C", "name": "Maize", "rgb": "(237, 209, 156)" }, { "hex": "979AAA", "name": "Manatee", "rgb": "(151, 154, 170)" }, { "hex": "FF8243", "name": "Mango Tango", "rgb": "(255, 130, 67)" }, { "hex": "C8385A", "name": "Maroon", "rgb": "(200, 56, 90)" }, { "hex": "EF98AA", "name": "Mauvelous", "rgb": "(239, 152, 170)" }, { "hex": "FDBCB4", "name": "Melon", "rgb": "(253, 188, 180)" }, { "hex": "1A4876", "name": "Midnight Blue", "rgb": "(26, 72, 118)" }, { "hex": "30BA8F", "name": "Mountain Meadow", "rgb": "(48, 186, 143)" }, { "hex": "C54B8C", "name": "Mulberry", "rgb": "(197, 75, 140)" }, { "hex": "1974D2", "name": "Navy Blue", "rgb": "(25, 116, 210)" }, { "hex": "FFA343", "name": "Neon Carrot", "rgb": "(255, 163, 67)" }, { "hex": "BAB86C", "name": "Olive Green", "rgb": "(186, 184, 108)" }, { "hex": "FF7538", "name": "Orange", "rgb": "(255, 117, 56)" }, { "hex": "FF2B2B", "name": "Orange Red", "rgb": "(255, 43, 43)" }, { "hex": "F8D568", "name": "Orange Yellow", "rgb": "(248, 213, 104)" }, { "hex": "E6A8D7", "name": "Orchid", "rgb": "(230, 168, 215)" }, { "hex": "414A4C", "name": "Outer Space", "rgb": "(65, 74, 76)" }, { "hex": "FF6E4A", "name": "Outrageous Orange", "rgb": "(255, 110, 74)" }, { "hex": "1CA9C9", "name": "Pacific Blue", "rgb": "(28, 169, 201)" }, { "hex": "FFCFAB", "name": "Peach", "rgb": "(255, 207, 171)" }, { "hex": "C5D0E6", "name": "Periwinkle", "rgb": "(197, 208, 230)" }, { "hex": "FDDDE6", "name": "Piggy Pink", "rgb": "(253, 221, 230)" }, { "hex": "158078", "name": "Pine Green", "rgb": "(21, 128, 120)" }, { "hex": "FC74FD", "name": "Pink Flamingo", "rgb": "(252, 116, 253)" }, { "hex": "F78FA7", "name": "Pink Sherbet", "rgb": "(247, 143, 167)" }, { "hex": "8E4585", "name": "Plum", "rgb": "(142, 69, 133)" }, { "hex": "7442C8", "name": "Purple Heart", "rgb": "(116, 66, 200)" }, { "hex": "9D81BA", "name": "Purple Mountain's Majesty", "rgb": "(157, 129, 186)" }, { "hex": "FE4EDA", "name": "Purple Pizzazz", "rgb": "(254, 78, 218)" }, { "hex": "FF496C", "name": "Radical Red", "rgb": "(255, 73, 108)" }, { "hex": "D68A59", "name": "Raw Sienna", "rgb": "(214, 138, 89)" }, { "hex": "714B23", "name": "Raw Umber", "rgb": "(113, 75, 35)" }, { "hex": "FF48D0", "name": "Razzle Dazzle Rose", "rgb": "(255, 72, 208)" }, { "hex": "E3256B", "name": "Razzmatazz", "rgb": "(227, 37, 107)" }, { "hex": "EE204D", "name": "Red", "rgb": "(238,32 ,77 )" }, { "hex": "FF5349", "name": "Red Orange", "rgb": "(255, 83, 73)" }, { "hex": "C0448F", "name": "Red Violet", "rgb": "(192, 68, 143)" }, { "hex": "1FCECB", "name": "Robin's Egg Blue", "rgb": "(31, 206, 203)" }, { "hex": "7851A9", "name": "Royal Purple", "rgb": "(120, 81, 169)" }, { "hex": "FF9BAA", "name": "Salmon", "rgb": "(255, 155, 170)" }, { "hex": "FC2847", "name": "Scarlet", "rgb": "(252, 40, 71)" }, { "hex": "76FF7A", "name": "Screamin' Green", "rgb": "(118, 255, 122)" }, { "hex": "9FE2BF", "name": "Sea Green", "rgb": "(159, 226, 191)" }, { "hex": "A5694F", "name": "Sepia", "rgb": "(165, 105, 79)" }, { "hex": "8A795D", "name": "Shadow", "rgb": "(138, 121, 93)" }, { "hex": "45CEA2", "name": "Shamrock", "rgb": "(69, 206, 162)" }, { "hex": "FB7EFD", "name": "Shocking Pink", "rgb": "(251, 126, 253)" }, { "hex": "CDC5C2", "name": "Silver", "rgb": "(205, 197, 194)" }, { "hex": "80DAEB", "name": "Sky Blue", "rgb": "(128, 218, 235)" }, { "hex": "ECEABE", "name": "Spring Green", "rgb": "(236, 234, 190)" }, { "hex": "FFCF48", "name": "Sunglow", "rgb": "(255, 207, 72)" }, { "hex": "FD5E53", "name": "Sunset Orange", "rgb": "(253, 94, 83)" }, { "hex": "FAA76C", "name": "Tan", "rgb": "(250, 167, 108)" }, { "hex": "18A7B5", "name": "Teal Blue", "rgb": "(24, 167, 181)" }, { "hex": "EBC7DF", "name": "Thistle", "rgb": "(235, 199, 223)" }, { "hex": "FC89AC", "name": "Tickle Me Pink", "rgb": "(252, 137, 172)" }, { "hex": "DBD7D2", "name": "Timberwolf", "rgb": "(219, 215, 210)" }, { "hex": "17806D", "name": "Tropical Rain Forest", "rgb": "(23, 128, 109)" }, { "hex": "DEAA88", "name": "Tumbleweed", "rgb": "(222, 170, 136)" }, { "hex": "77DDE7", "name": "Turquoise Blue", "rgb": "(119, 221, 231)" }, { "hex": "FFFF66", "name": "Unmellow Yellow", "rgb": "(255, 255, 102)" }, { "hex": "926EAE", "name": "Violet (Purple)", "rgb": "(146, 110, 174)" }, { "hex": "324AB2", "name": "Violet Blue", "rgb": "(50, 74, 178)" }, { "hex": "F75394", "name": "Violet Red", "rgb": "(247, 83, 148)" }, { "hex": "FFA089", "name": "Vivid Tangerine", "rgb": "(255, 160, 137)" }, { "hex": "8F509D", "name": "Vivid Violet", "rgb": "(143, 80, 157)" }, { "hex": "FFFFFF", "name": "White", "rgb": "(255, 255, 255)" }, { "hex": "A2ADD0", "name": "Wild Blue Yonder", "rgb": "(162, 173, 208)" }, { "hex": "FF43A4", "name": "Wild Strawberry", "rgb": "(255, 67, 164)" }, { "hex": "FC6C85", "name": "Wild Watermelon", "rgb": "(252, 108, 133)" }, { "hex": "CDA4DE", "name": "Wisteria", "rgb": "(205, 164, 222)" }, { "hex": "FCE883", "name": "Yellow", "rgb": "(252, 232, 131)" }, { "hex": "C5E384", "name": "Yellow Green", "rgb": "(197, 227, 132)" }, { "hex": "FFAE42", "name": "Yellow Orange", "rgb": "(255, 174, 66)" } ] ================================================ FILE: DZNEmptyDataSet/Colors/Images.xcassets/empty_placeholder.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "empty_placeholder.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "empty_placeholder@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Images.xcassets/search_icon.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "search_icon.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "search_icon@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Images.xcassets/tab_collection.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "tab_collection.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "tab_collection@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Images.xcassets/tab_search.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "tab_search.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "tab_search@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Images.xcassets/tab_table.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "tab_table.png" }, { "idiom" : "universal", "scale" : "2x", "filename" : "tab_table@2x.png" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DZNEmptyDataSet/Colors/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Storyboard UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: DZNEmptyDataSet/Colors/SearchViewController.h ================================================ // // SearchViewController.h // Colors // // Created by Ignacio Romero Z. on 7/4/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @class Color; @interface SearchViewController : UIViewController @property (nonatomic, strong) Color *selectedColor; @property (nonatomic, weak) IBOutlet UIImageView *colorView; @property (nonatomic, weak) IBOutlet UILabel *nameLabel; @property (nonatomic, weak) IBOutlet UILabel *hexLabel; @property (nonatomic, weak) IBOutlet UILabel *rgbLabel; @property (nonatomic, weak) IBOutlet UILabel *hexLegend; @property (nonatomic, weak) IBOutlet UILabel *rgbLegend; @end ================================================ FILE: DZNEmptyDataSet/Colors/SearchViewController.m ================================================ // // SearchViewController.m // Colors // // Created by Ignacio Romero Z. on 7/4/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "SearchViewController.h" #import "Palette.h" #import "Color.h" #import @interface SearchViewController () @property (nonatomic, strong) NSArray *searchResult; @property (nonatomic, getter = isShowingLandscape) BOOL showingLandscape; @end @implementation SearchViewController #pragma mark - View lifecycle - (void)awakeFromNib { [super awakeFromNib]; self.title = @"Search"; self.tabBarItem = [[UITabBarItem alloc] initWithTitle:self.title image:[UIImage imageNamed:@"tab_search"] tag:self.title.hash]; } - (void)loadView { [super loadView]; if ([self.navigationController.viewControllers count] == 1) { self.searchDisplayController.displaysSearchBarInNavigationBar = YES; } else { self.title = @"Detail"; } self.searchDisplayController.searchResultsTableView.emptyDataSetSource = self; self.searchDisplayController.searchResultsTableView.emptyDataSetDelegate = self; self.searchDisplayController.searchBar.placeholder = @"Search color"; self.searchDisplayController.searchResultsTableView.tableFooterView = [UIView new]; [self.searchDisplayController setValue:@"" forKey:@"_noResultsMessage"]; for (UIView *subview in self.view.subviews) { subview.autoresizingMask = UIViewAutoresizingNone; } } - (void)viewDidLoad { [super viewDidLoad]; self.showingLandscape = UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation); [self updateLayoutAnimatedWithDuration:0.0]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self updateContent]; } #pragma mark - Getters - (NSArray *)searchResult { if (_searchResult) { return _searchResult; } NSString *searchString = self.searchDisplayController.searchBar.text; if (searchString.length == 0) { return nil; } NSArray *colors = [[Palette sharedPalette] colors]; NSPredicate *precidate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@ || hex CONTAINS[cd] %@", searchString, searchString]; _searchResult = [colors filteredArrayUsingPredicate:precidate]; return _searchResult; } #pragma mark - Actions - (void)updateLayoutAnimatedWithDuration:(NSTimeInterval)duration { [UIView beginAnimations:@"" context:nil]; [UIView setAnimationDuration:duration]; [UIView setAnimationBeginsFromCurrentState:YES]; if (self.showingLandscape) { self.colorView.frame = CGRectMake(45.0, 88.0, 160.0, 160.0); self.nameLabel.frame = CGRectMake(240.0, 114.0, 280.0, 35.0); self.hexLabel.frame = CGRectMake(300.0, 170.0, 140.0, 20.0); self.rgbLabel.frame = CGRectMake(300.0, 200.0, 140.0, 20.0); self.hexLegend.frame = CGRectMake(240.0, 170.0, 60.0, 20.0); self.rgbLegend.frame = CGRectMake(240.0, 200.0, 60.0, 20.0); self.nameLabel.textAlignment = NSTextAlignmentLeft; } else { self.colorView.frame = CGRectMake(60.0, 130.0, 200.0, 200.0); self.nameLabel.frame = CGRectMake(20.0, 350.0, 280.0, 35.0); self.hexLabel.frame = CGRectMake(120.0, 420.0, 140.0, 20.0); self.rgbLabel.frame = CGRectMake(120.0, 450.0, 140.0, 20.0); self.hexLegend.frame = CGRectMake(60.0, 420.0, 60.0, 20.0); self.rgbLegend.frame = CGRectMake(60.0, 450.0, 60.0, 20.0); self.nameLabel.textAlignment = NSTextAlignmentCenter; } [UIView commitAnimations]; } - (void)updateContent { BOOL hide = self.selectedColor ? NO : YES; self.colorView.hidden = hide; self.nameLabel.hidden = hide; self.hexLabel.hidden = hide; self.rgbLabel.hidden = hide; self.hexLegend.hidden = hide; self.rgbLegend.hidden = hide; self.colorView.image = [Color roundImageForSize:self.colorView.frame.size withColor:self.selectedColor.color]; self.nameLabel.text = self.selectedColor.name; self.hexLabel.text = [NSString stringWithFormat:@"#%@", self.selectedColor.hex]; self.rgbLabel.text = self.selectedColor.rgb; } - (void)adjustToDeviceOrientation { self.showingLandscape = UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation); [self updateLayoutAnimatedWithDuration:0.25]; [self.searchDisplayController.searchResultsTableView reloadEmptyDataSet]; } #pragma mark - DZNEmptyDataSetSource Methods - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"No colors Found"; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0], NSForegroundColorAttributeName: [UIColor colorWithRed:170/255.0 green:171/255.0 blue:179/255.0 alpha:1.0], NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"Make sure that all words are\nspelled correctly."; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:15.0], NSForegroundColorAttributeName: [UIColor colorWithRed:170/255.0 green:171/255.0 blue:179/255.0 alpha:1.0], NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { NSString *text = @"Add a New Color"; UIColor *color = nil; if (state == UIControlStateNormal) color = [UIColor colorWithRed:44/255.0 green:137/255.0 blue:202/255.0 alpha:1.0]; if (state == UIControlStateHighlighted) color = [UIColor colorWithRed:106/255.0 green:187/255.0 blue:227/255.0 alpha:1.0]; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:14.0], NSForegroundColorAttributeName: color, NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView { if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) { return nil; } return [UIImage imageNamed:@"search_icon"]; } - (UIColor *)imageTintColorForEmptyDataSet:(UIScrollView *)scrollView { return [UIColor grayColor]; } - (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView { return [UIColor whiteColor]; } - (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView { return nil; } #pragma mark - DZNEmptyDataSetSource Methods - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return NO; } - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { [self.searchDisplayController setActive:NO animated:YES]; } - (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button { NSLog(@"%s",__FUNCTION__); } #pragma mark - UITableViewDataSource Methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.searchResult.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.selectionStyle = UITableViewCellSelectionStyleDefault; cell.selectedBackgroundView = [UIView new]; cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; cell.textLabel.textColor = [UIColor colorWithWhite:0.125 alpha:1.0]; cell.detailTextLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1.0]; } Color *color = self.searchResult[indexPath.row]; cell.textLabel.text = color.name; cell.detailTextLabel.text = [NSString stringWithFormat:@"#%@", color.hex]; cell.imageView.image = [Color roundThumbWithColor:color.color]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 56.0; } #pragma mark - UITableViewDelegate Methods - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selectedColor = self.searchResult[indexPath.row]; [self updateContent]; [self.searchDisplayController setActive:NO animated:YES]; } #pragma mark - UISearchDisplayControllerDelegate Methods - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { _searchResult = nil; return YES; } - (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView { // Do something } - (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView { // Do something } #pragma mark - View Auto-Rotation - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (![self respondsToSelector:@selector(willTransitionToTraitCollection:withTransitionCoordinator:)]) { [self adjustToDeviceOrientation]; } } - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id)coordinator { [self adjustToDeviceOrientation]; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } - (BOOL)shouldAutorotate { return YES; } @end ================================================ FILE: DZNEmptyDataSet/Colors/Storyboard.storyboard ================================================ ================================================ FILE: DZNEmptyDataSet/Colors/TableViewController.h ================================================ // // TableViewController.h // Colors // // Created by Ignacio Romero Z. on 6/29/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import @interface TableViewController : UITableViewController - (IBAction)refreshColors:(id)sender; - (IBAction)removeColors:(id)sender; @end ================================================ FILE: DZNEmptyDataSet/Colors/TableViewController.m ================================================ // // TableViewController.m // Colors // // Created by Ignacio Romero Z. on 6/29/14. // Copyright (c) 2014 DZN Labs. All rights reserved. // #import "TableViewController.h" #import "SearchViewController.h" #import "Palette.h" #import "Color.h" #import @interface TableViewController () @end @implementation TableViewController #pragma mark - View lifecycle - (void)awakeFromNib { [super awakeFromNib]; self.title = @"Table"; self.tabBarItem = [[UITabBarItem alloc] initWithTitle:self.title image:[UIImage imageNamed:@"tab_table"] tag:self.title.hash]; } - (void)loadView { [super loadView]; self.tableView.tableFooterView = [UIView new]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.tableView reloadData]; } #pragma mark - Actions - (IBAction)refreshColors:(id)sender { [[Palette sharedPalette] reloadAll]; [self.tableView reloadData]; } - (IBAction)removeColors:(id)sender { [[Palette sharedPalette] removeAll]; [self.tableView reloadData]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"table_push_detail"]) { SearchViewController *controller = [segue destinationViewController]; controller.selectedColor = sender; } } #pragma mark - DZNEmptyDataSetSource Methods - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"No colors loaded"; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0], NSForegroundColorAttributeName: [UIColor colorWithRed:170/255.0 green:171/255.0 blue:179/255.0 alpha:1.0], NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"To show a list of random colors, tap on the refresh icon in the right top corner.\n\nTo clean the list, tap on the trash icon."; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:15.0], NSForegroundColorAttributeName: [UIColor colorWithRed:170/255.0 green:171/255.0 blue:179/255.0 alpha:1.0], NSParagraphStyleAttributeName: paragraphStyle}; return [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; } - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView { return [UIImage imageNamed:@"empty_placeholder"]; } - (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView { return [UIColor whiteColor]; } - (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView { return nil; } - (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView { return 0; } #pragma mark - DZNEmptyDataSetSource Methods - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return NO; } - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { NSLog(@"%s",__FUNCTION__); } #pragma mark - UITableViewDataSource Methods - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [[Palette sharedPalette] colors].count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.selectionStyle = UITableViewCellSelectionStyleDefault; cell.selectedBackgroundView = [UIView new]; cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; cell.textLabel.textColor = [UIColor colorWithWhite:0.125 alpha:1.0]; cell.detailTextLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1.0]; } Color *color = [[Palette sharedPalette] colors][indexPath.row]; cell.textLabel.text = color.name; cell.detailTextLabel.text = [NSString stringWithFormat:@"#%@", color.hex]; cell.imageView.image = [Color roundThumbWithColor:color.color]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 56.0; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { Color *color = [[Palette sharedPalette] colors][indexPath.row]; [[Palette sharedPalette] removeColor:color]; [tableView beginUpdates]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableView endUpdates]; } } #pragma mark - UITableViewDelegate Methods - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { Color *color = [[Palette sharedPalette] colors][indexPath.row]; if ([self shouldPerformSegueWithIdentifier:@"table_push_detail" sender:color]) { [self performSegueWithIdentifier:@"table_push_detail" sender:color]; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) { return YES; } return NO; } - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) { Color *color = [[Palette sharedPalette] colors][indexPath.row]; if (color.hex.length > 0) [[UIPasteboard generalPasteboard] setString:color.hex]; } }); } #pragma mark - View Auto-Rotation - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } - (BOOL)shouldAutorotate { return YES; } @end ================================================ FILE: DZNEmptyDataSet/Colors/main.m ================================================ // // main.m // Colors // // Created by Ignacio Romero on 3/8/17. // Copyright © 2017 DZN. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet/DZNEmptyDataSet.h ================================================ // // DZNEmptyDataSet.h // DZNEmptyDataSet // // Created by Ignacio Romero on 2/28/17. // Copyright © 2017 DZN. All rights reserved. // #import //! Project version number for DZNEmptyDataSet. FOUNDATION_EXPORT double DZNEmptyDataSetVersionNumber; //! Project version string for DZNEmptyDataSet. FOUNDATION_EXPORT const unsigned char DZNEmptyDataSetVersionString[]; #import ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 3AC13C2C04A330F6731CD271 /* Pods_DZNEmptyDataSetTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C5DC4B343BE997FFAA0048 /* Pods_DZNEmptyDataSetTests.framework */; }; F56CEC4B1E67430000E2FACA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E7F1E66B62F0086E0EF /* Assets.xcassets */; }; F58A3E3C1E66AEE90086E0EF /* DZNEmptyDataSet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */; }; F58A3E411E66AEE90086E0EF /* ApplicationsSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E401E66AEE90086E0EF /* ApplicationsSnapshotTests.m */; }; F58A3E431E66AEE90086E0EF /* DZNEmptyDataSet.h in Headers */ = {isa = PBXBuildFile; fileRef = F58A3E351E66AEE90086E0EF /* DZNEmptyDataSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; F58A3E4E1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h in Headers */ = {isa = PBXBuildFile; fileRef = F58A3E4C1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; F58A3E4F1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E4D1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m */; }; F58A3E931E66B62F0086E0EF /* Application.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E7B1E66B62F0086E0EF /* Application.m */; }; F58A3E951E66B62F0086E0EF /* applications.json in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E7E1E66B62F0086E0EF /* applications.json */; }; F58A3E961E66B62F0086E0EF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E7F1E66B62F0086E0EF /* Assets.xcassets */; }; F58A3E971E66B62F0086E0EF /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E811E66B62F0086E0EF /* DetailViewController.m */; }; F58A3E981E66B62F0086E0EF /* IdealSans-Book-Pro.otf in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E841E66B62F0086E0EF /* IdealSans-Book-Pro.otf */; }; F58A3E991E66B62F0086E0EF /* Lato-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E861E66B62F0086E0EF /* Lato-Regular.ttf */; }; F58A3E9A1E66B62F0086E0EF /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E881E66B62F0086E0EF /* MainViewController.m */; }; F58A3E9C1E66B62F0086E0EF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E8B1E66B62F0086E0EF /* LaunchScreen.storyboard */; }; F58A3E9F1E66B62F0086E0EF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E901E66B62F0086E0EF /* main.m */; }; F58A3EA01E66B62F0086E0EF /* UIColor+Hexadecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E921E66B62F0086E0EF /* UIColor+Hexadecimal.m */; }; F58A3EA31E66B6C70086E0EF /* Applications-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = F58A3EA21E66B6C70086E0EF /* Applications-Prefix.pch */; }; F58A3EA51E66B6D70086E0EF /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F58A3EA41E66B6D70086E0EF /* Storyboard.storyboard */; }; F58A3EA81E66B6F10086E0EF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3EA71E66B6F10086E0EF /* AppDelegate.m */; }; F58A3EA91E66B7940086E0EF /* DZNEmptyDataSet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */; }; F58A3EAA1E66BD5A0086E0EF /* applications.json in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E7E1E66B62F0086E0EF /* applications.json */; }; F58A3EAB1E66BD5D0086E0EF /* Application.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E7B1E66B62F0086E0EF /* Application.m */; }; F58A3EAC1E66BD620086E0EF /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E811E66B62F0086E0EF /* DetailViewController.m */; }; F58A3EAD1E66BF270086E0EF /* UIColor+Hexadecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E921E66B62F0086E0EF /* UIColor+Hexadecimal.m */; }; F5BE15291E713E2100F6FBEA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE15281E713E2100F6FBEA /* main.m */; }; F5BE152C1E713E2100F6FBEA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE152B1E713E2100F6FBEA /* AppDelegate.m */; }; F5BE15341E713E2100F6FBEA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F5BE15331E713E2100F6FBEA /* Assets.xcassets */; }; F5BE15371E713E2100F6FBEA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F5BE15351E713E2100F6FBEA /* LaunchScreen.storyboard */; }; F5BE154A1E713E9300F6FBEA /* CollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE153D1E713E9300F6FBEA /* CollectionViewController.m */; }; F5BE154B1E713E9300F6FBEA /* Color.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE15401E713E9300F6FBEA /* Color.m */; }; F5BE154C1E713E9300F6FBEA /* colors.json in Resources */ = {isa = PBXBuildFile; fileRef = F5BE15411E713E9300F6FBEA /* colors.json */; }; F5BE154D1E713E9300F6FBEA /* Palette.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE15431E713E9300F6FBEA /* Palette.m */; }; F5BE154E1E713E9300F6FBEA /* UIColor+Hex.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE15451E713E9300F6FBEA /* UIColor+Hex.m */; }; F5BE154F1E713E9300F6FBEA /* SearchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE15471E713E9300F6FBEA /* SearchViewController.m */; }; F5BE15501E713E9300F6FBEA /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BE15491E713E9300F6FBEA /* TableViewController.m */; }; F5BE15521E713E9B00F6FBEA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F5BE15511E713E9B00F6FBEA /* Images.xcassets */; }; F5BE15561E713EC800F6FBEA /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F5BE15551E713EC800F6FBEA /* Storyboard.storyboard */; }; F5BE15571E71446300F6FBEA /* DZNEmptyDataSet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ F58A3E3D1E66AEE90086E0EF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F58A3E291E66AEE90086E0EF /* Project object */; proxyType = 1; remoteGlobalIDString = F58A3E311E66AEE90086E0EF; remoteInfo = DZNEmptyDataSet; }; F5BE151F1E713A7100F6FBEA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F58A3E291E66AEE90086E0EF /* Project object */; proxyType = 1; remoteGlobalIDString = F58A3E621E66B5410086E0EF; remoteInfo = Applications; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 1C26D4C95382E14DAC506EE2 /* Pods-EmptyDataSetTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EmptyDataSetTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.debug.xcconfig"; sourceTree = ""; }; 23BB766D928F8635A201F389 /* Pods_EmptyDataSetTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EmptyDataSetTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3456B9A6D72D48F19A7F61 /* Pods-DZNEmptyDataSetTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DZNEmptyDataSetTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.debug.xcconfig"; sourceTree = ""; }; 78C5DC4B343BE997FFAA0048 /* Pods_DZNEmptyDataSetTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DZNEmptyDataSetTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84189CEC4210484C1F24D3A8 /* Pods-DZNEmptyDataSetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DZNEmptyDataSetTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.release.xcconfig"; sourceTree = ""; }; DC2B63699C936D9C9CDB1740 /* Pods-EmptyDataSetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EmptyDataSetTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.release.xcconfig"; sourceTree = ""; }; F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DZNEmptyDataSet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F58A3E351E66AEE90086E0EF /* DZNEmptyDataSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DZNEmptyDataSet.h; sourceTree = ""; }; F58A3E361E66AEE90086E0EF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F58A3E3B1E66AEE90086E0EF /* DZNEmptyDataSetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DZNEmptyDataSetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F58A3E401E66AEE90086E0EF /* ApplicationsSnapshotTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ApplicationsSnapshotTests.m; sourceTree = ""; }; F58A3E421E66AEE90086E0EF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F58A3E4C1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIScrollView+EmptyDataSet.h"; path = "../../Source/UIScrollView+EmptyDataSet.h"; sourceTree = ""; }; F58A3E4D1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIScrollView+EmptyDataSet.m"; path = "../../Source/UIScrollView+EmptyDataSet.m"; sourceTree = ""; }; F58A3E631E66B5410086E0EF /* Applications.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Applications.app; sourceTree = BUILT_PRODUCTS_DIR; }; F58A3E7A1E66B62F0086E0EF /* Application.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Application.h; sourceTree = ""; }; F58A3E7B1E66B62F0086E0EF /* Application.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Application.m; sourceTree = ""; }; F58A3E7E1E66B62F0086E0EF /* applications.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = applications.json; sourceTree = ""; }; F58A3E7F1E66B62F0086E0EF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; F58A3E801E66B62F0086E0EF /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; F58A3E811E66B62F0086E0EF /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; F58A3E841E66B62F0086E0EF /* IdealSans-Book-Pro.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "IdealSans-Book-Pro.otf"; sourceTree = ""; }; F58A3E861E66B62F0086E0EF /* Lato-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Lato-Regular.ttf"; sourceTree = ""; }; F58A3E871E66B62F0086E0EF /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; F58A3E881E66B62F0086E0EF /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; F58A3E8C1E66B62F0086E0EF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; F58A3E8E1E66B62F0086E0EF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; F58A3E8F1E66B62F0086E0EF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F58A3E901E66B62F0086E0EF /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; F58A3E911E66B62F0086E0EF /* UIColor+Hexadecimal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Hexadecimal.h"; sourceTree = ""; }; F58A3E921E66B62F0086E0EF /* UIColor+Hexadecimal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Hexadecimal.m"; sourceTree = ""; }; F58A3EA21E66B6C70086E0EF /* Applications-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Applications-Prefix.pch"; sourceTree = ""; }; F58A3EA41E66B6D70086E0EF /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; F58A3EA61E66B6F10086E0EF /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; F58A3EA71E66B6F10086E0EF /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; F5BE15251E713E2100F6FBEA /* Colors.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Colors.app; sourceTree = BUILT_PRODUCTS_DIR; }; F5BE15281E713E2100F6FBEA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; F5BE152A1E713E2100F6FBEA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; F5BE152B1E713E2100F6FBEA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; F5BE15331E713E2100F6FBEA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; F5BE15361E713E2100F6FBEA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; F5BE15381E713E2100F6FBEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F5BE153C1E713E9300F6FBEA /* CollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionViewController.h; sourceTree = ""; }; F5BE153D1E713E9300F6FBEA /* CollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CollectionViewController.m; sourceTree = ""; }; F5BE153F1E713E9300F6FBEA /* Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Color.h; sourceTree = ""; }; F5BE15401E713E9300F6FBEA /* Color.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Color.m; sourceTree = ""; }; F5BE15411E713E9300F6FBEA /* colors.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = colors.json; sourceTree = ""; }; F5BE15421E713E9300F6FBEA /* Palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Palette.h; sourceTree = ""; }; F5BE15431E713E9300F6FBEA /* Palette.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Palette.m; sourceTree = ""; }; F5BE15441E713E9300F6FBEA /* UIColor+Hex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Hex.h"; sourceTree = ""; }; F5BE15451E713E9300F6FBEA /* UIColor+Hex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Hex.m"; sourceTree = ""; }; F5BE15461E713E9300F6FBEA /* SearchViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchViewController.h; sourceTree = ""; }; F5BE15471E713E9300F6FBEA /* SearchViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchViewController.m; sourceTree = ""; }; F5BE15481E713E9300F6FBEA /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; F5BE15491E713E9300F6FBEA /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; F5BE15511E713E9B00F6FBEA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; F5BE15551E713EC800F6FBEA /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ F58A3E2E1E66AEE90086E0EF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; F58A3E381E66AEE90086E0EF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( F58A3E3C1E66AEE90086E0EF /* DZNEmptyDataSet.framework in Frameworks */, 3AC13C2C04A330F6731CD271 /* Pods_DZNEmptyDataSetTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; F58A3E601E66B5410086E0EF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( F58A3EA91E66B7940086E0EF /* DZNEmptyDataSet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; F5BE15221E713E2100F6FBEA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( F5BE15571E71446300F6FBEA /* DZNEmptyDataSet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 242E9BB031D3264D62C731D6 /* Pods */ = { isa = PBXGroup; children = ( 1C26D4C95382E14DAC506EE2 /* Pods-EmptyDataSetTests.debug.xcconfig */, DC2B63699C936D9C9CDB1740 /* Pods-EmptyDataSetTests.release.xcconfig */, 3B3456B9A6D72D48F19A7F61 /* Pods-DZNEmptyDataSetTests.debug.xcconfig */, 84189CEC4210484C1F24D3A8 /* Pods-DZNEmptyDataSetTests.release.xcconfig */, ); name = Pods; sourceTree = ""; }; A7CC5E0B0809CA256BDA9067 /* Frameworks */ = { isa = PBXGroup; children = ( 23BB766D928F8635A201F389 /* Pods_EmptyDataSetTests.framework */, 78C5DC4B343BE997FFAA0048 /* Pods_DZNEmptyDataSetTests.framework */, ); name = Frameworks; sourceTree = ""; }; F58A3E281E66AEE90086E0EF = { isa = PBXGroup; children = ( F58A3E341E66AEE90086E0EF /* DZNEmptyDataSet */, F58A3E3F1E66AEE90086E0EF /* DZNEmptyDataSetTests */, F58A3E641E66B5410086E0EF /* Sample - Applications */, F5BE15261E713E2100F6FBEA /* Sample - Colors */, F58A3E331E66AEE90086E0EF /* Products */, 242E9BB031D3264D62C731D6 /* Pods */, A7CC5E0B0809CA256BDA9067 /* Frameworks */, ); sourceTree = ""; }; F58A3E331E66AEE90086E0EF /* Products */ = { isa = PBXGroup; children = ( F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */, F58A3E3B1E66AEE90086E0EF /* DZNEmptyDataSetTests.xctest */, F58A3E631E66B5410086E0EF /* Applications.app */, F5BE15251E713E2100F6FBEA /* Colors.app */, ); name = Products; sourceTree = ""; }; F58A3E341E66AEE90086E0EF /* DZNEmptyDataSet */ = { isa = PBXGroup; children = ( F58A3E351E66AEE90086E0EF /* DZNEmptyDataSet.h */, F58A3E4C1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h */, F58A3E4D1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m */, F58A3E361E66AEE90086E0EF /* Info.plist */, ); path = DZNEmptyDataSet; sourceTree = ""; }; F58A3E3F1E66AEE90086E0EF /* DZNEmptyDataSetTests */ = { isa = PBXGroup; children = ( F58A3E401E66AEE90086E0EF /* ApplicationsSnapshotTests.m */, F58A3E421E66AEE90086E0EF /* Info.plist */, ); path = DZNEmptyDataSetTests; sourceTree = ""; }; F58A3E641E66B5410086E0EF /* Sample - Applications */ = { isa = PBXGroup; children = ( F58A3EA61E66B6F10086E0EF /* AppDelegate.h */, F58A3EA71E66B6F10086E0EF /* AppDelegate.m */, F58A3E871E66B62F0086E0EF /* MainViewController.h */, F58A3E881E66B62F0086E0EF /* MainViewController.m */, F58A3E801E66B62F0086E0EF /* DetailViewController.h */, F58A3E811E66B62F0086E0EF /* DetailViewController.m */, F58A3E7A1E66B62F0086E0EF /* Application.h */, F58A3E7B1E66B62F0086E0EF /* Application.m */, F58A3E911E66B62F0086E0EF /* UIColor+Hexadecimal.h */, F58A3E921E66B62F0086E0EF /* UIColor+Hexadecimal.m */, F58A3EA11E66B6970086E0EF /* Resources */, F58A3E8A1E66B62F0086E0EF /* Supporting Files */, ); name = "Sample - Applications"; path = Applications; sourceTree = ""; }; F58A3E821E66B62F0086E0EF /* Fonts */ = { isa = PBXGroup; children = ( F58A3E831E66B62F0086E0EF /* Ideal Sans */, F58A3E851E66B62F0086E0EF /* Lato */, ); path = Fonts; sourceTree = ""; }; F58A3E831E66B62F0086E0EF /* Ideal Sans */ = { isa = PBXGroup; children = ( F58A3E841E66B62F0086E0EF /* IdealSans-Book-Pro.otf */, ); path = "Ideal Sans"; sourceTree = ""; }; F58A3E851E66B62F0086E0EF /* Lato */ = { isa = PBXGroup; children = ( F58A3E861E66B62F0086E0EF /* Lato-Regular.ttf */, ); path = Lato; sourceTree = ""; }; F58A3E8A1E66B62F0086E0EF /* Supporting Files */ = { isa = PBXGroup; children = ( F58A3EA41E66B6D70086E0EF /* Storyboard.storyboard */, F58A3E8B1E66B62F0086E0EF /* LaunchScreen.storyboard */, F58A3EA21E66B6C70086E0EF /* Applications-Prefix.pch */, F58A3E8D1E66B62F0086E0EF /* InfoPlist.strings */, F58A3E8F1E66B62F0086E0EF /* Info.plist */, F58A3E901E66B62F0086E0EF /* main.m */, ); path = "Supporting Files"; sourceTree = ""; }; F58A3EA11E66B6970086E0EF /* Resources */ = { isa = PBXGroup; children = ( F58A3E7E1E66B62F0086E0EF /* applications.json */, F58A3E821E66B62F0086E0EF /* Fonts */, F58A3E7F1E66B62F0086E0EF /* Assets.xcassets */, ); name = Resources; sourceTree = ""; }; F5BE15261E713E2100F6FBEA /* Sample - Colors */ = { isa = PBXGroup; children = ( F5BE152A1E713E2100F6FBEA /* AppDelegate.h */, F5BE152B1E713E2100F6FBEA /* AppDelegate.m */, F5BE153C1E713E9300F6FBEA /* CollectionViewController.h */, F5BE153D1E713E9300F6FBEA /* CollectionViewController.m */, F5BE15461E713E9300F6FBEA /* SearchViewController.h */, F5BE15471E713E9300F6FBEA /* SearchViewController.m */, F5BE15481E713E9300F6FBEA /* TableViewController.h */, F5BE15491E713E9300F6FBEA /* TableViewController.m */, F5BE153E1E713E9300F6FBEA /* DataSource */, F5BE15551E713EC800F6FBEA /* Storyboard.storyboard */, F5BE15511E713E9B00F6FBEA /* Images.xcassets */, F5BE15331E713E2100F6FBEA /* Assets.xcassets */, F5BE15351E713E2100F6FBEA /* LaunchScreen.storyboard */, F5BE15381E713E2100F6FBEA /* Info.plist */, F5BE15271E713E2100F6FBEA /* Supporting Files */, ); name = "Sample - Colors"; path = Colors; sourceTree = ""; }; F5BE15271E713E2100F6FBEA /* Supporting Files */ = { isa = PBXGroup; children = ( F5BE15281E713E2100F6FBEA /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; F5BE153E1E713E9300F6FBEA /* DataSource */ = { isa = PBXGroup; children = ( F5BE15411E713E9300F6FBEA /* colors.json */, F5BE153F1E713E9300F6FBEA /* Color.h */, F5BE15401E713E9300F6FBEA /* Color.m */, F5BE15421E713E9300F6FBEA /* Palette.h */, F5BE15431E713E9300F6FBEA /* Palette.m */, F5BE15441E713E9300F6FBEA /* UIColor+Hex.h */, F5BE15451E713E9300F6FBEA /* UIColor+Hex.m */, ); path = DataSource; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ F58A3E2F1E66AEE90086E0EF /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( F58A3EA31E66B6C70086E0EF /* Applications-Prefix.pch in Headers */, F58A3E431E66AEE90086E0EF /* DZNEmptyDataSet.h in Headers */, F58A3E4E1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ F58A3E311E66AEE90086E0EF /* DZNEmptyDataSet */ = { isa = PBXNativeTarget; buildConfigurationList = F58A3E461E66AEE90086E0EF /* Build configuration list for PBXNativeTarget "DZNEmptyDataSet" */; buildPhases = ( F58A3E2D1E66AEE90086E0EF /* Sources */, F58A3E2E1E66AEE90086E0EF /* Frameworks */, F58A3E2F1E66AEE90086E0EF /* Headers */, F58A3E301E66AEE90086E0EF /* Resources */, ); buildRules = ( ); dependencies = ( ); name = DZNEmptyDataSet; productName = DZNEmptyDataSet; productReference = F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */; productType = "com.apple.product-type.framework"; }; F58A3E3A1E66AEE90086E0EF /* DZNEmptyDataSetTests */ = { isa = PBXNativeTarget; buildConfigurationList = F58A3E491E66AEE90086E0EF /* Build configuration list for PBXNativeTarget "DZNEmptyDataSetTests" */; buildPhases = ( F1ACE1C014266E81F005B941 /* [CP] Check Pods Manifest.lock */, F58A3E371E66AEE90086E0EF /* Sources */, F58A3E381E66AEE90086E0EF /* Frameworks */, F58A3E391E66AEE90086E0EF /* Resources */, DDD9C9F5302171B78206FE07 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( F58A3E3E1E66AEE90086E0EF /* PBXTargetDependency */, F5BE15201E713A7100F6FBEA /* PBXTargetDependency */, ); name = DZNEmptyDataSetTests; productName = DZNEmptyDataSetTests; productReference = F58A3E3B1E66AEE90086E0EF /* DZNEmptyDataSetTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; F58A3E621E66B5410086E0EF /* Applications */ = { isa = PBXNativeTarget; buildConfigurationList = F58A3E791E66B5410086E0EF /* Build configuration list for PBXNativeTarget "Applications" */; buildPhases = ( F58A3E5F1E66B5410086E0EF /* Sources */, F58A3E601E66B5410086E0EF /* Frameworks */, F58A3E611E66B5410086E0EF /* Resources */, ); buildRules = ( ); dependencies = ( ); name = Applications; productName = Applications; productReference = F58A3E631E66B5410086E0EF /* Applications.app */; productType = "com.apple.product-type.application"; }; F5BE15241E713E2100F6FBEA /* Colors */ = { isa = PBXNativeTarget; buildConfigurationList = F5BE15391E713E2100F6FBEA /* Build configuration list for PBXNativeTarget "Colors" */; buildPhases = ( F5BE15211E713E2100F6FBEA /* Sources */, F5BE15221E713E2100F6FBEA /* Frameworks */, F5BE15231E713E2100F6FBEA /* Resources */, ); buildRules = ( ); dependencies = ( ); name = Colors; productName = Colors; productReference = F5BE15251E713E2100F6FBEA /* Colors.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ F58A3E291E66AEE90086E0EF /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1130; LastUpgradeCheck = 1130; ORGANIZATIONNAME = DZN; TargetAttributes = { F58A3E311E66AEE90086E0EF = { CreatedOnToolsVersion = 8.2.1; ProvisioningStyle = Manual; }; F58A3E3A1E66AEE90086E0EF = { CreatedOnToolsVersion = 8.2.1; LastSwiftMigration = 1130; ProvisioningStyle = Manual; }; F58A3E621E66B5410086E0EF = { CreatedOnToolsVersion = 8.2.1; ProvisioningStyle = Manual; }; F5BE15241E713E2100F6FBEA = { CreatedOnToolsVersion = 8.2.1; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = F58A3E2C1E66AEE90086E0EF /* Build configuration list for PBXProject "DZNEmptyDataSet" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = F58A3E281E66AEE90086E0EF; productRefGroup = F58A3E331E66AEE90086E0EF /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( F58A3E311E66AEE90086E0EF /* DZNEmptyDataSet */, F58A3E3A1E66AEE90086E0EF /* DZNEmptyDataSetTests */, F58A3E621E66B5410086E0EF /* Applications */, F5BE15241E713E2100F6FBEA /* Colors */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ F58A3E301E66AEE90086E0EF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; F58A3E391E66AEE90086E0EF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( F56CEC4B1E67430000E2FACA /* Assets.xcassets in Resources */, F58A3EAA1E66BD5A0086E0EF /* applications.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; F58A3E611E66B5410086E0EF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( F58A3E951E66B62F0086E0EF /* applications.json in Resources */, F58A3E961E66B62F0086E0EF /* Assets.xcassets in Resources */, F58A3E991E66B62F0086E0EF /* Lato-Regular.ttf in Resources */, F58A3E9C1E66B62F0086E0EF /* LaunchScreen.storyboard in Resources */, F58A3E981E66B62F0086E0EF /* IdealSans-Book-Pro.otf in Resources */, F58A3EA51E66B6D70086E0EF /* Storyboard.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; F5BE15231E713E2100F6FBEA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( F5BE15371E713E2100F6FBEA /* LaunchScreen.storyboard in Resources */, F5BE15521E713E9B00F6FBEA /* Images.xcassets in Resources */, F5BE154C1E713E9300F6FBEA /* colors.json in Resources */, F5BE15341E713E2100F6FBEA /* Assets.xcassets in Resources */, F5BE15561E713EC800F6FBEA /* Storyboard.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ DDD9C9F5302171B78206FE07 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-frameworks.sh", "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSnapshotTestCase.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; F1ACE1C014266E81F005B941 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-DZNEmptyDataSetTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ F58A3E2D1E66AEE90086E0EF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F58A3E4F1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; F58A3E371E66AEE90086E0EF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F58A3EAB1E66BD5D0086E0EF /* Application.m in Sources */, F58A3EAD1E66BF270086E0EF /* UIColor+Hexadecimal.m in Sources */, F58A3E411E66AEE90086E0EF /* ApplicationsSnapshotTests.m in Sources */, F58A3EAC1E66BD620086E0EF /* DetailViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; F58A3E5F1E66B5410086E0EF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F58A3E931E66B62F0086E0EF /* Application.m in Sources */, F58A3E9A1E66B62F0086E0EF /* MainViewController.m in Sources */, F58A3EA81E66B6F10086E0EF /* AppDelegate.m in Sources */, F58A3EA01E66B62F0086E0EF /* UIColor+Hexadecimal.m in Sources */, F58A3E9F1E66B62F0086E0EF /* main.m in Sources */, F58A3E971E66B62F0086E0EF /* DetailViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; F5BE15211E713E2100F6FBEA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F5BE154A1E713E9300F6FBEA /* CollectionViewController.m in Sources */, F5BE154B1E713E9300F6FBEA /* Color.m in Sources */, F5BE154D1E713E9300F6FBEA /* Palette.m in Sources */, F5BE15501E713E9300F6FBEA /* TableViewController.m in Sources */, F5BE154E1E713E9300F6FBEA /* UIColor+Hex.m in Sources */, F5BE152C1E713E2100F6FBEA /* AppDelegate.m in Sources */, F5BE154F1E713E9300F6FBEA /* SearchViewController.m in Sources */, F5BE15291E713E2100F6FBEA /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ F58A3E3E1E66AEE90086E0EF /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = F58A3E311E66AEE90086E0EF /* DZNEmptyDataSet */; targetProxy = F58A3E3D1E66AEE90086E0EF /* PBXContainerItemProxy */; }; F5BE15201E713A7100F6FBEA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = F58A3E621E66B5410086E0EF /* Applications */; targetProxy = F5BE151F1E713A7100F6FBEA /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ F58A3E8B1E66B62F0086E0EF /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( F58A3E8C1E66B62F0086E0EF /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; F58A3E8D1E66B62F0086E0EF /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( F58A3E8E1E66B62F0086E0EF /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; F5BE15351E713E2100F6FBEA /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( F5BE15361E713E2100F6FBEA /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ F58A3E441E66AEE90086E0EF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; F58A3E451E66AEE90086E0EF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; F58A3E471E66AEE90086E0EF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = ""; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = DZNEmptyDataSet/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.DZNEmptyDataSet; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; name = Debug; }; F58A3E481E66AEE90086E0EF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = ""; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = DZNEmptyDataSet/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.DZNEmptyDataSet; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; name = Release; }; F58A3E4A1E66AEE90086E0EF /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3B3456B9A6D72D48F19A7F61 /* Pods-DZNEmptyDataSetTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = DZNEmptyDataSetTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.DZNEmptyDataSetTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "DZNEmptyDataSetTests/DZNEmptyDataSetTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; }; name = Debug; }; F58A3E4B1E66AEE90086E0EF /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 84189CEC4210484C1F24D3A8 /* Pods-DZNEmptyDataSetTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = DZNEmptyDataSetTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.DZNEmptyDataSetTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "DZNEmptyDataSetTests/DZNEmptyDataSetTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; }; name = Release; }; F58A3E771E66B5410086E0EF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "LaunchImage-3"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/Applications/Supporting Files/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.Applications; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; F58A3E781E66B5410086E0EF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "LaunchImage-3"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/Applications/Supporting Files/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.Applications; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; F5BE153A1E713E2100F6FBEA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Colors/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.Colors; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; F5BE153B1E713E2100F6FBEA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Colors/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.dzn.Colors; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ F58A3E2C1E66AEE90086E0EF /* Build configuration list for PBXProject "DZNEmptyDataSet" */ = { isa = XCConfigurationList; buildConfigurations = ( F58A3E441E66AEE90086E0EF /* Debug */, F58A3E451E66AEE90086E0EF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; F58A3E461E66AEE90086E0EF /* Build configuration list for PBXNativeTarget "DZNEmptyDataSet" */ = { isa = XCConfigurationList; buildConfigurations = ( F58A3E471E66AEE90086E0EF /* Debug */, F58A3E481E66AEE90086E0EF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; F58A3E491E66AEE90086E0EF /* Build configuration list for PBXNativeTarget "DZNEmptyDataSetTests" */ = { isa = XCConfigurationList; buildConfigurations = ( F58A3E4A1E66AEE90086E0EF /* Debug */, F58A3E4B1E66AEE90086E0EF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; F58A3E791E66B5410086E0EF /* Build configuration list for PBXNativeTarget "Applications" */ = { isa = XCConfigurationList; buildConfigurations = ( F58A3E771E66B5410086E0EF /* Debug */, F58A3E781E66B5410086E0EF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; F5BE15391E713E2100F6FBEA /* Build configuration list for PBXNativeTarget "Colors" */ = { isa = XCConfigurationList; buildConfigurations = ( F5BE153A1E713E2100F6FBEA /* Debug */, F5BE153B1E713E2100F6FBEA /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = F58A3E291E66AEE90086E0EF /* Project object */; } ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/DZNEmptyDataSet.xcscheme ================================================ ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/DZNEmptyDataSetTests.xcscheme ================================================ ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSet.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSetTests/ApplicationsSnapshotTests.m ================================================ // // DZNEmptyDataSetTests.m // DZNEmptyDataSetTests // // Created by Ignacio Romero on 2/28/17. // Copyright © 2017 DZN. All rights reserved. // #import #import #import #import "Application.h" #import "DetailViewController.h" @interface ApplicationsSnapshotTests : FBSnapshotTestCase @end @implementation ApplicationsSnapshotTests - (void)setUp { [super setUp]; self.recordMode = NO; // Snaphot tests are not yet configured to be running for multiple hardware configuration (device type, system version, screen density, etc.). // We make sure tests are only ran for @2x iPhone simulators, with iOS 10 or above. static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ UIDevice *device = [UIDevice currentDevice]; UIScreen *screen = [UIScreen mainScreen]; // Using XCTAssert instead of NSAssert since these do not cause the tests to fail. XCTAssert([device.name containsString:@"iPhone 8"], @"Please run snapshot tests on an iPhone 8 simulator."); XCTAssert([device.systemVersion doubleValue] > 11.0, @"Please run snapshot tests on a simulator with iOS 11.0 or above."); XCTAssert(screen.scale == 2.0, @"Please run snapshot tests on a @2x density simulator."); }); } - (void)tearDown { [super tearDown]; } - (void)testApplicationEmptyDataSets { NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path = [bundle pathForResource:@"applications" ofType:@"json"]; NSArray *applications = [Application applicationsFromJSONAtPath:path]; for (Application *app in applications) { UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; window.rootViewController = [[DetailViewController alloc] initWithApplication:app]; [window makeKeyAndVisible]; [self verifyView:window withIdentifier:app.displayName]; } } #pragma mark - FBSnapshotTestCase - (NSString *)getReferenceImageDirectoryWithDefault:(NSString *)dir { NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path = [[bundle infoDictionary] valueForKey:@"XCodeProjectPath"]; return [NSString stringWithFormat:@"%@/DZNEmptyDataSetTests/ReferenceImages", path]; } - (void)verifyView:(UIView *)view withIdentifier:(NSString *)identifier { FBSnapshotVerifyViewWithOptions(view, identifier, FBSnapshotTestCaseDefaultSuffixes(), 0); } @end ================================================ FILE: DZNEmptyDataSet/DZNEmptyDataSetTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 XCodeProjectPath $(SOURCE_ROOT) ================================================ FILE: DZNEmptyDataSet/EmptyDataSetTests/DZNEmptyDataSetTests-Bridging-Header.h ================================================ // // Use this file to import your target's public headers that you would like to expose to Swift. // //#import "Applications.h" ================================================ FILE: DZNEmptyDataSet/Podfile ================================================ platform :ios, '10.0' use_frameworks! inhibit_all_warnings! workspace 'DZNEmptyDataSet.xcworkspace' target 'DZNEmptyDataSetTests' do pod 'iOSSnapshotTestCase' end ================================================ FILE: DZNEmptyDataSet/Pods/Pods.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 09F3021D3323D0B64812EE10886827AB /* UIImage+Diff.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EE0D8468132004B33C282270003A158 /* UIImage+Diff.h */; settings = {ATTRIBUTES = (Private, ); }; }; 115B9F2A343D1880D138F41B9491C125 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD4ED544B638D07C7D755AF1C27116A /* Foundation.framework */; }; 144F29212101A4D03109E989BE0A4F92 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F2628B40D6A150C1ADD3875C92B9792 /* FBSnapshotTestController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 20D8C7C8698B7ED12643ECC31666C8C1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD4ED544B638D07C7D755AF1C27116A /* Foundation.framework */; }; 2416486B5F64697AC5FCDFD6FD6E019E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD4ED544B638D07C7D755AF1C27116A /* Foundation.framework */; }; 2643963F8600F16366AF89ABF6D91F82 /* UIImage+Compare.h in Headers */ = {isa = PBXBuildFile; fileRef = F98662B97F340866723F7EA90CF3D26C /* UIImage+Compare.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2CA412DDC41031745F66213AD86238FE /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 432D328D5B1788520371534F0EC9AA67 /* SwiftSupport.swift */; }; 338DD760BB611C08829BEC825B2BB816 /* UIImage+Snapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 85F5D23833B7C650DB2B9B5EA95B43F7 /* UIImage+Snapshot.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 3B1E085DF7CFF7E649546346F4A0BC13 /* Pods-EmptyDataSetTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E91C64E07DBA5087F6C91BDCA0B09C1F /* Pods-EmptyDataSetTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3B540469AF7772C156A3AD0CC6184734 /* FBSnapshotTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF0D8E3529AAF9DD2F8B3378FD89216 /* FBSnapshotTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3CE95FD1D722818A524677118DF557BA /* UIImage+Snapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EBD54FBC707C522306409616608E03F7 /* UIImage+Snapshot.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4A00FE44F3F789ABEB88E16D122FD321 /* Pods-DZNEmptyDataSetTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 641D5F8E6F0E23700685EE1559119B27 /* Pods-DZNEmptyDataSetTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6543CE32DD97E4F24919522FE4E79A94 /* FBSnapshotTestCasePlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = DC37D45B91EAA34C1B307819F4FBFA48 /* FBSnapshotTestCasePlatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; 796D4CB4F4AB8ECBBD931B099A74E833 /* FBSnapshotTestController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BFB7DE40547F6148458C28227213A42 /* FBSnapshotTestController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 82CE8E0DC98452F08E1A03D3CA91B763 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CAA89EEF1039078430D7A886477E365 /* UIKit.framework */; }; 82EFF24AA6839F02578915C72F7582AC /* Pods-EmptyDataSetTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C3D8F63D7253014B7E075D445E3444 /* Pods-EmptyDataSetTests-dummy.m */; }; 86BC25FD2CC085B17A374500C747062D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 716A9972B9D9103B54DB950893FAF104 /* QuartzCore.framework */; }; 968B5318A745263F0D3A72023217CD12 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E601BD54DA9BF4071437E60125281FA /* XCTest.framework */; }; 97F75B96103369BE6F6040DFD8BC2910 /* iOSSnapshotTestCase-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 796F28118D863DD7DDE14D1F6AC3DC9C /* iOSSnapshotTestCase-dummy.m */; }; A2DF2053A890C10FE0B6ADA21A5A0FED /* UIImage+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = EB07CC184E97597B5EF96293FD8D6775 /* UIImage+Compare.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; AA2A80FACDE8BCA52EFF8948A50C070B /* UIImage+Diff.m in Sources */ = {isa = PBXBuildFile; fileRef = 078903AE75C1D7D5C61C8DE620D53A5A /* UIImage+Diff.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; AF16498E0663C46FD75357313DBE3D39 /* Pods-DZNEmptyDataSetTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B75DE7FCA97B3F0088F9BF1D274F226 /* Pods-DZNEmptyDataSetTests-dummy.m */; }; C930BCB1B395E19ABBE9D4D491867353 /* iOSSnapshotTestCase-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 58F4181C8833BE6DB86CDA8C805A00A9 /* iOSSnapshotTestCase-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; C9E1F1A48507326B8AF0EFDBE3C0EC75 /* FBSnapshotTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 523B65C5434BF857787C7B495D48070A /* FBSnapshotTestCase.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; EAC1544AADA392F95DEF08C5C89DAA93 /* FBSnapshotTestCasePlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = BD3E11CFF525A7BE0F5090E39A8A725C /* FBSnapshotTestCasePlatform.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 1970170B56D3F0BE38BD9DD9C582A769 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = C393038B0BEF088C1B93E6528005862D; remoteInfo = iOSSnapshotTestCase; }; 974C9C9D02D9F34F3F4008C7FE80EE21 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = C393038B0BEF088C1B93E6528005862D; remoteInfo = iOSSnapshotTestCase; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 027896DEC86092765C2A760ED6F9480C /* Pods-EmptyDataSetTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-EmptyDataSetTests-acknowledgements.plist"; sourceTree = ""; }; 078903AE75C1D7D5C61C8DE620D53A5A /* UIImage+Diff.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Diff.m"; path = "FBSnapshotTestCase/Categories/UIImage+Diff.m"; sourceTree = ""; }; 0BFB7DE40547F6148458C28227213A42 /* FBSnapshotTestController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestController.h; path = FBSnapshotTestCase/FBSnapshotTestController.h; sourceTree = ""; }; 0F2628B40D6A150C1ADD3875C92B9792 /* FBSnapshotTestController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestController.m; path = FBSnapshotTestCase/FBSnapshotTestController.m; sourceTree = ""; }; 1729263C6AF4C3457DF5FAF67D6CFE5D /* Pods_EmptyDataSetTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_EmptyDataSetTests.framework; path = "Pods-EmptyDataSetTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 1B75DE7FCA97B3F0088F9BF1D274F226 /* Pods-DZNEmptyDataSetTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-DZNEmptyDataSetTests-dummy.m"; sourceTree = ""; }; 219C55A87100C3F768EA58AB6A011319 /* Pods-DZNEmptyDataSetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DZNEmptyDataSetTests.release.xcconfig"; sourceTree = ""; }; 290FE9C065FB341E697628A988F8EEBD /* Pods-DZNEmptyDataSetTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DZNEmptyDataSetTests-frameworks.sh"; sourceTree = ""; }; 2EE0D8468132004B33C282270003A158 /* UIImage+Diff.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Diff.h"; path = "FBSnapshotTestCase/Categories/UIImage+Diff.h"; sourceTree = ""; }; 332524405EDFD5162E55CBC3D200E051 /* Pods-EmptyDataSetTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-EmptyDataSetTests.debug.xcconfig"; sourceTree = ""; }; 3BF0D8E3529AAF9DD2F8B3378FD89216 /* FBSnapshotTestCase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestCase.h; path = FBSnapshotTestCase/FBSnapshotTestCase.h; sourceTree = ""; }; 432D328D5B1788520371534F0EC9AA67 /* SwiftSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftSupport.swift; path = FBSnapshotTestCase/SwiftSupport.swift; sourceTree = ""; }; 5069A3FAA385B1F702DF6F5C83461EF2 /* iOSSnapshotTestCase-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "iOSSnapshotTestCase-prefix.pch"; sourceTree = ""; }; 523B65C5434BF857787C7B495D48070A /* FBSnapshotTestCase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestCase.m; path = FBSnapshotTestCase/FBSnapshotTestCase.m; sourceTree = ""; }; 58F4181C8833BE6DB86CDA8C805A00A9 /* iOSSnapshotTestCase-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "iOSSnapshotTestCase-umbrella.h"; sourceTree = ""; }; 5E601BD54DA9BF4071437E60125281FA /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 61C3D8F63D7253014B7E075D445E3444 /* Pods-EmptyDataSetTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-EmptyDataSetTests-dummy.m"; sourceTree = ""; }; 641D5F8E6F0E23700685EE1559119B27 /* Pods-DZNEmptyDataSetTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-DZNEmptyDataSetTests-umbrella.h"; sourceTree = ""; }; 64860ED4D1469506201CA2ECB2F54AF9 /* iOSSnapshotTestCase-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "iOSSnapshotTestCase-Info.plist"; sourceTree = ""; }; 6E410EBBDD4A8BFC1EAA1CC501B302E8 /* Pods-EmptyDataSetTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-EmptyDataSetTests.modulemap"; sourceTree = ""; }; 716A9972B9D9103B54DB950893FAF104 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 796F28118D863DD7DDE14D1F6AC3DC9C /* iOSSnapshotTestCase-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "iOSSnapshotTestCase-dummy.m"; sourceTree = ""; }; 7BD4ED544B638D07C7D755AF1C27116A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 83AE7D1AEFB339AD0959403003751CA7 /* Pods-EmptyDataSetTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-EmptyDataSetTests-acknowledgements.markdown"; sourceTree = ""; }; 85F5D23833B7C650DB2B9B5EA95B43F7 /* UIImage+Snapshot.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Snapshot.m"; path = "FBSnapshotTestCase/Categories/UIImage+Snapshot.m"; sourceTree = ""; }; 8CAA89EEF1039078430D7A886477E365 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 900C95C1DE73EA90A623D23D95C912B0 /* iOSSnapshotTestCase.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = iOSSnapshotTestCase.modulemap; sourceTree = ""; }; 90865ABAFFD6A5A298617AB51BBCAF91 /* Pods-DZNEmptyDataSetTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DZNEmptyDataSetTests-Info.plist"; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 9E40F32945DC9CF56B2E7A875BDF9DBE /* Pods-DZNEmptyDataSetTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DZNEmptyDataSetTests.debug.xcconfig"; sourceTree = ""; }; A93D16E4190310C154EA0253BFD291D9 /* Pods_DZNEmptyDataSetTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_DZNEmptyDataSetTests.framework; path = "Pods-DZNEmptyDataSetTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; B75A47899E602A5CA9E833F7D136622D /* iOSSnapshotTestCase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = iOSSnapshotTestCase.xcconfig; sourceTree = ""; }; B91B00F8BE943329D633234BD67AE0AC /* FBSnapshotTestCase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FBSnapshotTestCase.framework; path = iOSSnapshotTestCase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BBCACE771CD60C1357EF2772ACFA9A5A /* Pods-EmptyDataSetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-EmptyDataSetTests.release.xcconfig"; sourceTree = ""; }; BD356F3D59B3BBE571310DBB3B97F84E /* Pods-EmptyDataSetTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-EmptyDataSetTests-Info.plist"; sourceTree = ""; }; BD3E11CFF525A7BE0F5090E39A8A725C /* FBSnapshotTestCasePlatform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestCasePlatform.m; path = FBSnapshotTestCase/FBSnapshotTestCasePlatform.m; sourceTree = ""; }; DC37D45B91EAA34C1B307819F4FBFA48 /* FBSnapshotTestCasePlatform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestCasePlatform.h; path = FBSnapshotTestCase/FBSnapshotTestCasePlatform.h; sourceTree = ""; }; DC6B74AAA9CE469BC6631EACB90FC966 /* Pods-DZNEmptyDataSetTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-DZNEmptyDataSetTests.modulemap"; sourceTree = ""; }; DFE3F6CF133FD4C8FBF9601D099051B3 /* Pods-DZNEmptyDataSetTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-DZNEmptyDataSetTests-acknowledgements.markdown"; sourceTree = ""; }; E57FBF63C1E571D185BC40FC4FD0124B /* Pods-EmptyDataSetTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-EmptyDataSetTests-frameworks.sh"; sourceTree = ""; }; E91C64E07DBA5087F6C91BDCA0B09C1F /* Pods-EmptyDataSetTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-EmptyDataSetTests-umbrella.h"; sourceTree = ""; }; EB07CC184E97597B5EF96293FD8D6775 /* UIImage+Compare.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Compare.m"; path = "FBSnapshotTestCase/Categories/UIImage+Compare.m"; sourceTree = ""; }; EB9D7FBC181BDEA4FFA12454B4DDA6E7 /* Pods-DZNEmptyDataSetTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DZNEmptyDataSetTests-acknowledgements.plist"; sourceTree = ""; }; EBD54FBC707C522306409616608E03F7 /* UIImage+Snapshot.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Snapshot.h"; path = "FBSnapshotTestCase/Categories/UIImage+Snapshot.h"; sourceTree = ""; }; F98662B97F340866723F7EA90CF3D26C /* UIImage+Compare.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Compare.h"; path = "FBSnapshotTestCase/Categories/UIImage+Compare.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 7A35EDA086C304554C2338DC74768756 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 2416486B5F64697AC5FCDFD6FD6E019E /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 8ADC0E40B07D5BA0567CF010759D43B6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 20D8C7C8698B7ED12643ECC31666C8C1 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; FDD1A2F6F0C7CD64F79B3E79FC562312 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 115B9F2A343D1880D138F41B9491C125 /* Foundation.framework in Frameworks */, 86BC25FD2CC085B17A374500C747062D /* QuartzCore.framework in Frameworks */, 82CE8E0DC98452F08E1A03D3CA91B763 /* UIKit.framework in Frameworks */, 968B5318A745263F0D3A72023217CD12 /* XCTest.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 17758483808FFC630062D87E87BA22CD /* Products */ = { isa = PBXGroup; children = ( B91B00F8BE943329D633234BD67AE0AC /* FBSnapshotTestCase.framework */, A93D16E4190310C154EA0253BFD291D9 /* Pods_DZNEmptyDataSetTests.framework */, 1729263C6AF4C3457DF5FAF67D6CFE5D /* Pods_EmptyDataSetTests.framework */, ); name = Products; sourceTree = ""; }; 22F3ECA726DE45D34B3ADFE5F42DC86C /* Core */ = { isa = PBXGroup; children = ( 3BF0D8E3529AAF9DD2F8B3378FD89216 /* FBSnapshotTestCase.h */, 523B65C5434BF857787C7B495D48070A /* FBSnapshotTestCase.m */, DC37D45B91EAA34C1B307819F4FBFA48 /* FBSnapshotTestCasePlatform.h */, BD3E11CFF525A7BE0F5090E39A8A725C /* FBSnapshotTestCasePlatform.m */, 0BFB7DE40547F6148458C28227213A42 /* FBSnapshotTestController.h */, 0F2628B40D6A150C1ADD3875C92B9792 /* FBSnapshotTestController.m */, F98662B97F340866723F7EA90CF3D26C /* UIImage+Compare.h */, EB07CC184E97597B5EF96293FD8D6775 /* UIImage+Compare.m */, 2EE0D8468132004B33C282270003A158 /* UIImage+Diff.h */, 078903AE75C1D7D5C61C8DE620D53A5A /* UIImage+Diff.m */, EBD54FBC707C522306409616608E03F7 /* UIImage+Snapshot.h */, 85F5D23833B7C650DB2B9B5EA95B43F7 /* UIImage+Snapshot.m */, ); name = Core; sourceTree = ""; }; 33C026A8A479CAC5A2B0ADF596B17FFC /* Targets Support Files */ = { isa = PBXGroup; children = ( C64175448BD262912DD6E8DA8A7A1045 /* Pods-DZNEmptyDataSetTests */, 8A3E0554708D94F3E07DFBB2E998F53B /* Pods-EmptyDataSetTests */, ); name = "Targets Support Files"; sourceTree = ""; }; 435489B56C63D57B6F480411D2ECC160 /* Pods */ = { isa = PBXGroup; children = ( EFF1EAE44DF5397EE93427776ECDDC88 /* iOSSnapshotTestCase */, ); name = Pods; sourceTree = ""; }; 7DE5752EED0A4C4A430975244947611A /* iOS */ = { isa = PBXGroup; children = ( 7BD4ED544B638D07C7D755AF1C27116A /* Foundation.framework */, 716A9972B9D9103B54DB950893FAF104 /* QuartzCore.framework */, 8CAA89EEF1039078430D7A886477E365 /* UIKit.framework */, 5E601BD54DA9BF4071437E60125281FA /* XCTest.framework */, ); name = iOS; sourceTree = ""; }; 8A3E0554708D94F3E07DFBB2E998F53B /* Pods-EmptyDataSetTests */ = { isa = PBXGroup; children = ( 6E410EBBDD4A8BFC1EAA1CC501B302E8 /* Pods-EmptyDataSetTests.modulemap */, 83AE7D1AEFB339AD0959403003751CA7 /* Pods-EmptyDataSetTests-acknowledgements.markdown */, 027896DEC86092765C2A760ED6F9480C /* Pods-EmptyDataSetTests-acknowledgements.plist */, 61C3D8F63D7253014B7E075D445E3444 /* Pods-EmptyDataSetTests-dummy.m */, E57FBF63C1E571D185BC40FC4FD0124B /* Pods-EmptyDataSetTests-frameworks.sh */, BD356F3D59B3BBE571310DBB3B97F84E /* Pods-EmptyDataSetTests-Info.plist */, E91C64E07DBA5087F6C91BDCA0B09C1F /* Pods-EmptyDataSetTests-umbrella.h */, 332524405EDFD5162E55CBC3D200E051 /* Pods-EmptyDataSetTests.debug.xcconfig */, BBCACE771CD60C1357EF2772ACFA9A5A /* Pods-EmptyDataSetTests.release.xcconfig */, ); name = "Pods-EmptyDataSetTests"; path = "Target Support Files/Pods-EmptyDataSetTests"; sourceTree = ""; }; A222A9C1427FEE47EF8DE5C03195EBC3 /* SwiftSupport */ = { isa = PBXGroup; children = ( 432D328D5B1788520371534F0EC9AA67 /* SwiftSupport.swift */, ); name = SwiftSupport; sourceTree = ""; }; BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */ = { isa = PBXGroup; children = ( 7DE5752EED0A4C4A430975244947611A /* iOS */, ); name = Frameworks; sourceTree = ""; }; C64175448BD262912DD6E8DA8A7A1045 /* Pods-DZNEmptyDataSetTests */ = { isa = PBXGroup; children = ( DC6B74AAA9CE469BC6631EACB90FC966 /* Pods-DZNEmptyDataSetTests.modulemap */, DFE3F6CF133FD4C8FBF9601D099051B3 /* Pods-DZNEmptyDataSetTests-acknowledgements.markdown */, EB9D7FBC181BDEA4FFA12454B4DDA6E7 /* Pods-DZNEmptyDataSetTests-acknowledgements.plist */, 1B75DE7FCA97B3F0088F9BF1D274F226 /* Pods-DZNEmptyDataSetTests-dummy.m */, 290FE9C065FB341E697628A988F8EEBD /* Pods-DZNEmptyDataSetTests-frameworks.sh */, 90865ABAFFD6A5A298617AB51BBCAF91 /* Pods-DZNEmptyDataSetTests-Info.plist */, 641D5F8E6F0E23700685EE1559119B27 /* Pods-DZNEmptyDataSetTests-umbrella.h */, 9E40F32945DC9CF56B2E7A875BDF9DBE /* Pods-DZNEmptyDataSetTests.debug.xcconfig */, 219C55A87100C3F768EA58AB6A011319 /* Pods-DZNEmptyDataSetTests.release.xcconfig */, ); name = "Pods-DZNEmptyDataSetTests"; path = "Target Support Files/Pods-DZNEmptyDataSetTests"; sourceTree = ""; }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */, 435489B56C63D57B6F480411D2ECC160 /* Pods */, 17758483808FFC630062D87E87BA22CD /* Products */, 33C026A8A479CAC5A2B0ADF596B17FFC /* Targets Support Files */, ); sourceTree = ""; }; E8F185C38F4D0FECED758E1073BF7128 /* Support Files */ = { isa = PBXGroup; children = ( 900C95C1DE73EA90A623D23D95C912B0 /* iOSSnapshotTestCase.modulemap */, B75A47899E602A5CA9E833F7D136622D /* iOSSnapshotTestCase.xcconfig */, 796F28118D863DD7DDE14D1F6AC3DC9C /* iOSSnapshotTestCase-dummy.m */, 64860ED4D1469506201CA2ECB2F54AF9 /* iOSSnapshotTestCase-Info.plist */, 5069A3FAA385B1F702DF6F5C83461EF2 /* iOSSnapshotTestCase-prefix.pch */, 58F4181C8833BE6DB86CDA8C805A00A9 /* iOSSnapshotTestCase-umbrella.h */, ); name = "Support Files"; path = "../Target Support Files/iOSSnapshotTestCase"; sourceTree = ""; }; EFF1EAE44DF5397EE93427776ECDDC88 /* iOSSnapshotTestCase */ = { isa = PBXGroup; children = ( 22F3ECA726DE45D34B3ADFE5F42DC86C /* Core */, E8F185C38F4D0FECED758E1073BF7128 /* Support Files */, A222A9C1427FEE47EF8DE5C03195EBC3 /* SwiftSupport */, ); name = iOSSnapshotTestCase; path = iOSSnapshotTestCase; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 12F90A431FB27F32CAD4D4DFFEE32FF7 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 3B1E085DF7CFF7E649546346F4A0BC13 /* Pods-EmptyDataSetTests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; A1F0BF3267CFE49DA92D818F3B3A46DA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 3B540469AF7772C156A3AD0CC6184734 /* FBSnapshotTestCase.h in Headers */, 6543CE32DD97E4F24919522FE4E79A94 /* FBSnapshotTestCasePlatform.h in Headers */, 796D4CB4F4AB8ECBBD931B099A74E833 /* FBSnapshotTestController.h in Headers */, C930BCB1B395E19ABBE9D4D491867353 /* iOSSnapshotTestCase-umbrella.h in Headers */, 2643963F8600F16366AF89ABF6D91F82 /* UIImage+Compare.h in Headers */, 09F3021D3323D0B64812EE10886827AB /* UIImage+Diff.h in Headers */, 3CE95FD1D722818A524677118DF557BA /* UIImage+Snapshot.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; D6B54FF9A1E85667A0622B61E0BD8B72 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4A00FE44F3F789ABEB88E16D122FD321 /* Pods-DZNEmptyDataSetTests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ B1EE7C977B6484DAE578FFC4A25371F7 /* Pods-DZNEmptyDataSetTests */ = { isa = PBXNativeTarget; buildConfigurationList = 010084C73E57B1D0D7124269DE2FB5B8 /* Build configuration list for PBXNativeTarget "Pods-DZNEmptyDataSetTests" */; buildPhases = ( D6B54FF9A1E85667A0622B61E0BD8B72 /* Headers */, 0BD8C839914C19929CCB23D680CA392D /* Sources */, 8ADC0E40B07D5BA0567CF010759D43B6 /* Frameworks */, 5DE2A9DA7B2817224FE72F17AB02A9FB /* Resources */, ); buildRules = ( ); dependencies = ( 3C5DED3F5269999C13BBB8A7637252DE /* PBXTargetDependency */, ); name = "Pods-DZNEmptyDataSetTests"; productName = "Pods-DZNEmptyDataSetTests"; productReference = A93D16E4190310C154EA0253BFD291D9 /* Pods_DZNEmptyDataSetTests.framework */; productType = "com.apple.product-type.framework"; }; C393038B0BEF088C1B93E6528005862D /* iOSSnapshotTestCase */ = { isa = PBXNativeTarget; buildConfigurationList = A2580343E01EF46F4A1E600895C7753A /* Build configuration list for PBXNativeTarget "iOSSnapshotTestCase" */; buildPhases = ( A1F0BF3267CFE49DA92D818F3B3A46DA /* Headers */, 81064F7606D6A421CDB262423B7A682F /* Sources */, FDD1A2F6F0C7CD64F79B3E79FC562312 /* Frameworks */, B8848E61F4166ABF3DCCE39D45C21A1B /* Resources */, ); buildRules = ( ); dependencies = ( ); name = iOSSnapshotTestCase; productName = iOSSnapshotTestCase; productReference = B91B00F8BE943329D633234BD67AE0AC /* FBSnapshotTestCase.framework */; productType = "com.apple.product-type.framework"; }; F22E9EB6070A0734E7A865931D24105B /* Pods-EmptyDataSetTests */ = { isa = PBXNativeTarget; buildConfigurationList = D4D79C952AF7010F341E080CC0AE2F38 /* Build configuration list for PBXNativeTarget "Pods-EmptyDataSetTests" */; buildPhases = ( 12F90A431FB27F32CAD4D4DFFEE32FF7 /* Headers */, 6E84AE3570D939BABEDFC6C999094782 /* Sources */, 7A35EDA086C304554C2338DC74768756 /* Frameworks */, C6D0DA03E5855DD9518529DE26678B3D /* Resources */, ); buildRules = ( ); dependencies = ( 4C2E33AF65BD368F9FA201F3F24CE3CF /* PBXTargetDependency */, ); name = "Pods-EmptyDataSetTests"; productName = "Pods-EmptyDataSetTests"; productReference = 1729263C6AF4C3457DF5FAF67D6CFE5D /* Pods_EmptyDataSetTests.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ BFDFE7DC352907FC980B868725387E98 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1100; LastUpgradeCheck = 1100; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; productRefGroup = 17758483808FFC630062D87E87BA22CD /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( C393038B0BEF088C1B93E6528005862D /* iOSSnapshotTestCase */, B1EE7C977B6484DAE578FFC4A25371F7 /* Pods-DZNEmptyDataSetTests */, F22E9EB6070A0734E7A865931D24105B /* Pods-EmptyDataSetTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 5DE2A9DA7B2817224FE72F17AB02A9FB /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; B8848E61F4166ABF3DCCE39D45C21A1B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; C6D0DA03E5855DD9518529DE26678B3D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 0BD8C839914C19929CCB23D680CA392D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AF16498E0663C46FD75357313DBE3D39 /* Pods-DZNEmptyDataSetTests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 6E84AE3570D939BABEDFC6C999094782 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 82EFF24AA6839F02578915C72F7582AC /* Pods-EmptyDataSetTests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 81064F7606D6A421CDB262423B7A682F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C9E1F1A48507326B8AF0EFDBE3C0EC75 /* FBSnapshotTestCase.m in Sources */, EAC1544AADA392F95DEF08C5C89DAA93 /* FBSnapshotTestCasePlatform.m in Sources */, 144F29212101A4D03109E989BE0A4F92 /* FBSnapshotTestController.m in Sources */, 97F75B96103369BE6F6040DFD8BC2910 /* iOSSnapshotTestCase-dummy.m in Sources */, 2CA412DDC41031745F66213AD86238FE /* SwiftSupport.swift in Sources */, A2DF2053A890C10FE0B6ADA21A5A0FED /* UIImage+Compare.m in Sources */, AA2A80FACDE8BCA52EFF8948A50C070B /* UIImage+Diff.m in Sources */, 338DD760BB611C08829BEC825B2BB816 /* UIImage+Snapshot.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 3C5DED3F5269999C13BBB8A7637252DE /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = iOSSnapshotTestCase; target = C393038B0BEF088C1B93E6528005862D /* iOSSnapshotTestCase */; targetProxy = 1970170B56D3F0BE38BD9DD9C582A769 /* PBXContainerItemProxy */; }; 4C2E33AF65BD368F9FA201F3F24CE3CF /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = iOSSnapshotTestCase; target = C393038B0BEF088C1B93E6528005862D /* iOSSnapshotTestCase */; targetProxy = 974C9C9D02D9F34F3F4008C7FE80EE21 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 196DFA3E4A09A28224918543529A1885 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_DEBUG=1", "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; 4B756B0C319E4C27F01C0781C4A33A48 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 219C55A87100C3F768EA58AB6A011319 /* Pods-DZNEmptyDataSetTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 589AAD4B6B784B8CBCCCF62BA0C7C7D4 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = BBCACE771CD60C1357EF2772ACFA9A5A /* Pods-EmptyDataSetTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 6393F6295629B82BB95C294654C46850 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 332524405EDFD5162E55CBC3D200E051 /* Pods-EmptyDataSetTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; B01D14FDC83DCF9D4BE53066BEA96D05 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; name = Release; }; E30677E30722EED4EFAAF96B70FB53E0 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = B75A47899E602A5CA9E833F7D136622D /* iOSSnapshotTestCase.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREFIX_HEADER = "Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-prefix.pch"; INFOPLIST_FILE = "Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase.modulemap"; PRODUCT_MODULE_NAME = FBSnapshotTestCase; PRODUCT_NAME = FBSnapshotTestCase; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.1; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; EC06F4BCD0F4CC10B27E32823A6F0935 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = B75A47899E602A5CA9E833F7D136622D /* iOSSnapshotTestCase.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREFIX_HEADER = "Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-prefix.pch"; INFOPLIST_FILE = "Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase.modulemap"; PRODUCT_MODULE_NAME = FBSnapshotTestCase; PRODUCT_NAME = FBSnapshotTestCase; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.1; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; F8191286B6058D8C892B2D45D81C7670 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9E40F32945DC9CF56B2E7A875BDF9DBE /* Pods-DZNEmptyDataSetTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 010084C73E57B1D0D7124269DE2FB5B8 /* Build configuration list for PBXNativeTarget "Pods-DZNEmptyDataSetTests" */ = { isa = XCConfigurationList; buildConfigurations = ( F8191286B6058D8C892B2D45D81C7670 /* Debug */, 4B756B0C319E4C27F01C0781C4A33A48 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( 196DFA3E4A09A28224918543529A1885 /* Debug */, B01D14FDC83DCF9D4BE53066BEA96D05 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; A2580343E01EF46F4A1E600895C7753A /* Build configuration list for PBXNativeTarget "iOSSnapshotTestCase" */ = { isa = XCConfigurationList; buildConfigurations = ( E30677E30722EED4EFAAF96B70FB53E0 /* Debug */, EC06F4BCD0F4CC10B27E32823A6F0935 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; D4D79C952AF7010F341E080CC0AE2F38 /* Build configuration list for PBXNativeTarget "Pods-EmptyDataSetTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 6393F6295629B82BB95C294654C46850 /* Debug */, 589AAD4B6B784B8CBCCCF62BA0C7C7D4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; } ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-acknowledgements.markdown ================================================ # Acknowledgements This application makes use of the following third party libraries: ## iOSSnapshotTestCase MIT License Copyright (c) 2017-2018, Uber Technologies, Inc. Copyright (c) 2013-2018, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Generated by CocoaPods - https://cocoapods.org ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-acknowledgements.plist ================================================ PreferenceSpecifiers FooterText This application makes use of the following third party libraries: Title Acknowledgements Type PSGroupSpecifier FooterText MIT License Copyright (c) 2017-2018, Uber Technologies, Inc. Copyright (c) 2013-2018, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License MIT Title iOSSnapshotTestCase Type PSGroupSpecifier FooterText Generated by CocoaPods - https://cocoapods.org Title Type PSGroupSpecifier StringsTable Acknowledgements Title Acknowledgements ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-dummy.m ================================================ #import @interface PodsDummy_Pods_DZNEmptyDataSetTests : NSObject @end @implementation PodsDummy_Pods_DZNEmptyDataSetTests @end ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-frameworks.sh ================================================ #!/bin/sh set -e set -u set -o pipefail function on_error { echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" } trap 'on_error $LINENO' ERR if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy # frameworks to, so exit 0 (signalling the script phase was successful). exit 0 fi echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" # Used as a return value for each invocation of `strip_invalid_archs` function. STRIP_BINARY_RETVAL=0 # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") # Copies and strips a vendored framework install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then local source="${BUILT_PRODUCTS_DIR}/$1" elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" elif [ -r "$1" ]; then local source="$1" fi local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" if [ -L "${source}" ]; then echo "Symlinked..." source="$(readlink "${source}")" fi # Use filter instead of exclude so missing patterns don't throw errors. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" binary="${destination}/${basename}.framework/${basename}" if ! [ -r "$binary" ]; then binary="${destination}/${basename}" elif [ -L "${binary}" ]; then echo "Destination binary is symlinked..." dirname="$(dirname "${binary}")" binary="${dirname}/$(readlink "${binary}")" fi # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then strip_invalid_archs "$binary" fi # Resign the code if required by the build settings to avoid unstable apps code_sign_if_enabled "${destination}/$(basename "$1")" # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then local swift_runtime_libs swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) for lib in $swift_runtime_libs; do echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" code_sign_if_enabled "${destination}/${lib}" done fi } # Copies and strips a vendored dSYM install_dsym() { local source="$1" if [ -r "$source" ]; then # Copy the dSYM into a the targets temp dir. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" local basename basename="$(basename -s .framework.dSYM "$source")" binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then strip_invalid_archs "$binary" fi if [[ $STRIP_BINARY_RETVAL == 1 ]]; then # Move the stripped file into its final destination. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" else # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" fi fi } # Copies the bcsymbolmap files of a vendored framework install_bcsymbolmap() { local bcsymbolmap_path="$1" local destination="${BUILT_PRODUCTS_DIR}" echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" } # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identity echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then code_sign_cmd="$code_sign_cmd &" fi echo "$code_sign_cmd" eval "$code_sign_cmd" fi } # Strip invalid architectures strip_invalid_archs() { binary="$1" # Get architectures for current target binary binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" # Intersect them with the architectures we are building for intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" # If there are no archs supported by this binary then warn the user if [[ -z "$intersected_archs" ]]; then echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." STRIP_BINARY_RETVAL=0 return fi stripped="" for arch in $binary_archs; do if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" stripped="$stripped $arch" fi done if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi STRIP_BINARY_RETVAL=1 } if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then wait fi ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests-umbrella.h ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif FOUNDATION_EXPORT double Pods_DZNEmptyDataSetTestsVersionNumber; FOUNDATION_EXPORT const unsigned char Pods_DZNEmptyDataSetTestsVersionString[]; ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.debug.xcconfig ================================================ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" -iframework "$(PLATFORM_DIR)/Developer/Library/Frameworks" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.modulemap ================================================ framework module Pods_DZNEmptyDataSetTests { umbrella header "Pods-DZNEmptyDataSetTests-umbrella.h" export * module * { export * } } ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.release.xcconfig ================================================ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" -iframework "$(PLATFORM_DIR)/Developer/Library/Frameworks" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-acknowledgements.markdown ================================================ # Acknowledgements This application makes use of the following third party libraries: ## iOSSnapshotTestCase MIT License Copyright (c) 2017-2018, Uber Technologies, Inc. Copyright (c) 2013-2018, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Generated by CocoaPods - https://cocoapods.org ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-acknowledgements.plist ================================================ PreferenceSpecifiers FooterText This application makes use of the following third party libraries: Title Acknowledgements Type PSGroupSpecifier FooterText MIT License Copyright (c) 2017-2018, Uber Technologies, Inc. Copyright (c) 2013-2018, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License MIT Title iOSSnapshotTestCase Type PSGroupSpecifier FooterText Generated by CocoaPods - https://cocoapods.org Title Type PSGroupSpecifier StringsTable Acknowledgements Title Acknowledgements ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-dummy.m ================================================ #import @interface PodsDummy_Pods_EmptyDataSetTests : NSObject @end @implementation PodsDummy_Pods_EmptyDataSetTests @end ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-frameworks.sh ================================================ #!/bin/sh set -e set -u set -o pipefail function on_error { echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" } trap 'on_error $LINENO' ERR if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy # frameworks to, so exit 0 (signalling the script phase was successful). exit 0 fi echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" # Used as a return value for each invocation of `strip_invalid_archs` function. STRIP_BINARY_RETVAL=0 # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") # Copies and strips a vendored framework install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then local source="${BUILT_PRODUCTS_DIR}/$1" elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" elif [ -r "$1" ]; then local source="$1" fi local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" if [ -L "${source}" ]; then echo "Symlinked..." source="$(readlink "${source}")" fi # Use filter instead of exclude so missing patterns don't throw errors. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" binary="${destination}/${basename}.framework/${basename}" if ! [ -r "$binary" ]; then binary="${destination}/${basename}" elif [ -L "${binary}" ]; then echo "Destination binary is symlinked..." dirname="$(dirname "${binary}")" binary="${dirname}/$(readlink "${binary}")" fi # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then strip_invalid_archs "$binary" fi # Resign the code if required by the build settings to avoid unstable apps code_sign_if_enabled "${destination}/$(basename "$1")" # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then local swift_runtime_libs swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) for lib in $swift_runtime_libs; do echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" code_sign_if_enabled "${destination}/${lib}" done fi } # Copies and strips a vendored dSYM install_dsym() { local source="$1" if [ -r "$source" ]; then # Copy the dSYM into a the targets temp dir. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" local basename basename="$(basename -s .framework.dSYM "$source")" binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then strip_invalid_archs "$binary" fi if [[ $STRIP_BINARY_RETVAL == 1 ]]; then # Move the stripped file into its final destination. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" else # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" fi fi } # Copies the bcsymbolmap files of a vendored framework install_bcsymbolmap() { local bcsymbolmap_path="$1" local destination="${BUILT_PRODUCTS_DIR}" echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" } # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identity echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then code_sign_cmd="$code_sign_cmd &" fi echo "$code_sign_cmd" eval "$code_sign_cmd" fi } # Strip invalid architectures strip_invalid_archs() { binary="$1" # Get architectures for current target binary binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" # Intersect them with the architectures we are building for intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" # If there are no archs supported by this binary then warn the user if [[ -z "$intersected_archs" ]]; then echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." STRIP_BINARY_RETVAL=0 return fi stripped="" for arch in $binary_archs; do if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" stripped="$stripped $arch" fi done if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi STRIP_BINARY_RETVAL=1 } if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then wait fi ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests-umbrella.h ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif FOUNDATION_EXPORT double Pods_EmptyDataSetTestsVersionNumber; FOUNDATION_EXPORT const unsigned char Pods_EmptyDataSetTestsVersionString[]; ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.debug.xcconfig ================================================ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" -iframework "$(PLATFORM_DIR)/Developer/Library/Frameworks" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.modulemap ================================================ framework module Pods_EmptyDataSetTests { umbrella header "Pods-EmptyDataSetTests-umbrella.h" export * module * { export * } } ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.release.xcconfig ================================================ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework/Headers" -iframework "$(PLATFORM_DIR)/Developer/Library/Frameworks" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase" OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 6.2.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 6.2.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-dummy.m ================================================ #import @interface PodsDummy_iOSSnapshotTestCase : NSObject @end @implementation PodsDummy_iOSSnapshotTestCase @end ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-prefix.pch ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase-umbrella.h ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif #import "FBSnapshotTestCase.h" #import "FBSnapshotTestCasePlatform.h" #import "FBSnapshotTestController.h" FOUNDATION_EXPORT double FBSnapshotTestCaseVersionNumber; FOUNDATION_EXPORT const unsigned char FBSnapshotTestCaseVersionString[]; ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase.modulemap ================================================ framework module FBSnapshotTestCase { umbrella header "iOSSnapshotTestCase-umbrella.h" export * module * { export * } } ================================================ FILE: DZNEmptyDataSet/Pods/Target Support Files/iOSSnapshotTestCase/iOSSnapshotTestCase.xcconfig ================================================ CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/iOSSnapshotTestCase ENABLE_BITCODE = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/iOSSnapshotTestCase PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.h ================================================ // // Created by Gabriel Handford on 3/1/09. // Copyright 2009-2013. All rights reserved. // Created by John Boiles on 10/20/11. // Copyright (c) 2011. All rights reserved // Modified by Felix Schulze on 2/11/13. // Copyright 2013. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // #import NS_ASSUME_NONNULL_BEGIN @interface UIImage (Compare) /** Compares the image against another given image. @param image The other image to compare against. @param perPixelTolerance How much (in percentage) any given pixel's colors are allowed to change from the pixel in the reference image. @param overallTolerance The overall percentage of pixels that are allowed to change from the pixels in the reference image. @return A BOOL which represents if the image is the same or not. */ - (BOOL)fb_compareWithImage:(UIImage *)image perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance; @end NS_ASSUME_NONNULL_END ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.m ================================================ // // Created by Gabriel Handford on 3/1/09. // Copyright 2009-2013. All rights reserved. // Created by John Boiles on 10/20/11. // Copyright (c) 2011. All rights reserved // Modified by Felix Schulze on 2/11/13. // Copyright 2013. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // #import // This makes debugging much more fun typedef union { uint32_t raw; unsigned char bytes[4]; struct { char red; char green; char blue; char alpha; } __attribute__((packed)) pixels; } FBComparePixel; @implementation UIImage (Compare) - (BOOL)fb_compareWithImage:(UIImage *)image perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance { CGSize referenceImageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); CGSize imageSize = CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); NSAssert(CGSizeEqualToSize(referenceImageSize, imageSize), @"Images must be same size."); // The images have the equal size, so we could use the smallest amount of bytes because of byte padding size_t minBytesPerRow = MIN(CGImageGetBytesPerRow(self.CGImage), CGImageGetBytesPerRow(image.CGImage)); size_t referenceImageSizeBytes = referenceImageSize.height * minBytesPerRow; void *referenceImagePixels = calloc(1, referenceImageSizeBytes); void *imagePixels = calloc(1, referenceImageSizeBytes); if (!referenceImagePixels || !imagePixels) { free(referenceImagePixels); free(imagePixels); return NO; } CGContextRef referenceImageContext = CGBitmapContextCreate(referenceImagePixels, referenceImageSize.width, referenceImageSize.height, CGImageGetBitsPerComponent(self.CGImage), minBytesPerRow, CGImageGetColorSpace(self.CGImage), (CGBitmapInfo)kCGImageAlphaPremultipliedLast); CGContextRef imageContext = CGBitmapContextCreate(imagePixels, imageSize.width, imageSize.height, CGImageGetBitsPerComponent(image.CGImage), minBytesPerRow, CGImageGetColorSpace(image.CGImage), (CGBitmapInfo)kCGImageAlphaPremultipliedLast); if (!referenceImageContext || !imageContext) { CGContextRelease(referenceImageContext); CGContextRelease(imageContext); free(referenceImagePixels); free(imagePixels); return NO; } CGContextDrawImage(referenceImageContext, CGRectMake(0, 0, referenceImageSize.width, referenceImageSize.height), self.CGImage); CGContextDrawImage(imageContext, CGRectMake(0, 0, imageSize.width, imageSize.height), image.CGImage); CGContextRelease(referenceImageContext); CGContextRelease(imageContext); BOOL imageEqual = YES; FBComparePixel *p1 = referenceImagePixels; FBComparePixel *p2 = imagePixels; // Do a fast compare if we can if (overallTolerance == 0 && perPixelTolerance == 0) { imageEqual = (memcmp(referenceImagePixels, imagePixels, referenceImageSizeBytes) == 0); } else { const NSUInteger pixelCount = referenceImageSize.width * referenceImageSize.height; // Go through each pixel in turn and see if it is different imageEqual = [self _compareAllPixelsWithPerPixelTolerance:perPixelTolerance overallTolerance:overallTolerance pixelCount:pixelCount referencePixels:p1 imagePixels:p2]; } free(referenceImagePixels); free(imagePixels); return imageEqual; } - (BOOL)_comparePixelWithPerPixelTolerance:(CGFloat)perPixelTolerance referencePixel:(FBComparePixel *)referencePixel imagePixel:(FBComparePixel *)imagePixel { if (referencePixel->raw == imagePixel->raw) { return YES; } else if (perPixelTolerance == 0) { return NO; } CGFloat redPercentDiff = [self _calculatePercentDifferenceForReferencePixelComponent:referencePixel->pixels.red imagePixelComponent:imagePixel->pixels.red]; CGFloat greenPercentDiff = [self _calculatePercentDifferenceForReferencePixelComponent:referencePixel->pixels.green imagePixelComponent:imagePixel->pixels.green]; CGFloat bluePercentDiff = [self _calculatePercentDifferenceForReferencePixelComponent:referencePixel->pixels.blue imagePixelComponent:imagePixel->pixels.blue]; CGFloat alphaPercentDiff = [self _calculatePercentDifferenceForReferencePixelComponent:referencePixel->pixels.alpha imagePixelComponent:imagePixel->pixels.alpha]; BOOL anyDifferencesFound = (redPercentDiff > perPixelTolerance || greenPercentDiff > perPixelTolerance || bluePercentDiff > perPixelTolerance || alphaPercentDiff > perPixelTolerance); return !anyDifferencesFound; } - (CGFloat)_calculatePercentDifferenceForReferencePixelComponent:(char)p1 imagePixelComponent:(char)p2 { NSInteger referencePixelComponent = (unsigned char)p1; NSInteger imagePixelComponent = (unsigned char)p2; NSUInteger componentDifference = ABS(referencePixelComponent - imagePixelComponent); return (CGFloat)componentDifference / 256; } - (BOOL)_compareAllPixelsWithPerPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance pixelCount:(NSUInteger)pixelCount referencePixels:(FBComparePixel *)referencePixel imagePixels:(FBComparePixel *)imagePixel { NSUInteger numDiffPixels = 0; for (NSUInteger n = 0; n < pixelCount; ++n) { // If this pixel is different, increment the pixel diff count and see // if we have hit our limit. BOOL isIdenticalPixel = [self _comparePixelWithPerPixelTolerance:perPixelTolerance referencePixel:referencePixel imagePixel:imagePixel]; if (!isIdenticalPixel) { numDiffPixels++; CGFloat percent = (CGFloat)numDiffPixels / (CGFloat)pixelCount; if (percent > overallTolerance) { return NO; } } referencePixel++; imagePixel++; } return YES; } @end ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.h ================================================ // // Created by Gabriel Handford on 3/1/09. // Copyright 2009-2013. All rights reserved. // Created by John Boiles on 10/20/11. // Copyright (c) 2011. All rights reserved // Modified by Felix Schulze on 2/11/13. // Copyright 2013. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // #import NS_ASSUME_NONNULL_BEGIN @interface UIImage (Diff) - (UIImage *)fb_diffWithImage:(UIImage *)image; @end NS_ASSUME_NONNULL_END ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.m ================================================ // // Created by Gabriel Handford on 3/1/09. // Copyright 2009-2013. All rights reserved. // Created by John Boiles on 10/20/11. // Copyright (c) 2011. All rights reserved // Modified by Felix Schulze on 2/11/13. // Copyright 2013. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // #import @implementation UIImage (Diff) - (UIImage *)fb_diffWithImage:(UIImage *)image { if (!image) { return nil; } CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height)); UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); CGContextRef context = UIGraphicsGetCurrentContext(); [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; CGContextSetAlpha(context, 0.5); CGContextBeginTransparencyLayer(context, NULL); [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; CGContextSetBlendMode(context, kCGBlendModeDifference); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height)); CGContextEndTransparencyLayer(context); UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return returnImage; } @end ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.h ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import NS_ASSUME_NONNULL_BEGIN @interface UIImage (Snapshot) /// Uses renderInContext: to get a snapshot of the layer. + (nullable UIImage *)fb_imageForLayer:(CALayer *)layer; /// Uses renderInContext: to get a snapshot of the view layer. + (nullable UIImage *)fb_imageForViewLayer:(UIView *)view; /// Uses drawViewHierarchyInRect: to get a snapshot of the view and adds the view into a window if needed. + (nullable UIImage *)fb_imageForView:(UIView *)view; @end NS_ASSUME_NONNULL_END ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.m ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import @implementation UIImage (Snapshot) + (UIImage *)fb_imageForLayer:(CALayer *)layer { CGRect bounds = layer.bounds; NSAssert1(CGRectGetWidth(bounds), @"Zero width for layer %@", layer); NSAssert1(CGRectGetHeight(bounds), @"Zero height for layer %@", layer); UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); NSAssert1(context, @"Could not generate context for layer %@", layer); CGContextSaveGState(context); [layer layoutIfNeeded]; [layer renderInContext:context]; CGContextRestoreGState(context); UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return snapshot; } + (UIImage *)fb_imageForViewLayer:(UIView *)view { [view layoutIfNeeded]; return [self fb_imageForLayer:view.layer]; } + (UIImage *)fb_imageForView:(UIView *)view { // If the input view is already a UIWindow, then just use that. Otherwise wrap in a window. UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *)view : view.window; BOOL removeFromSuperview = NO; if (!window) { window = [[UIApplication sharedApplication] keyWindow]; } if (!view.window && view != window) { [window addSubview:view]; removeFromSuperview = YES; } [view layoutIfNeeded]; CGRect bounds = view.bounds; NSAssert1(CGRectGetWidth(bounds), @"Zero width for view %@", view); NSAssert1(CGRectGetHeight(bounds), @"Zero height for view %@", view); UIGraphicsImageRenderer *graphicsImageRenderer = [[UIGraphicsImageRenderer alloc] initWithSize:bounds.size]; UIImage *snapshot = [graphicsImageRenderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { [view drawViewHierarchyInRect:bounds afterScreenUpdates:YES]; }]; if (removeFromSuperview) { [view removeFromSuperview]; } return snapshot; } @end ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import #import #import #import #import /* There are three ways of setting reference image directories. 1. Set the preprocessor macro FB_REFERENCE_IMAGE_DIR to a double quoted c-string with the path. This only works for Objective-C tests. 2. Set an environment variable named FB_REFERENCE_IMAGE_DIR with the path. This takes precedence over the preprocessor macro to allow for run-time override. 3. Keep everything unset, which will cause the reference images to be looked up inside the bundle holding the current test, in the Resources/ReferenceImages_* directories. */ #ifndef FB_REFERENCE_IMAGE_DIR #define FB_REFERENCE_IMAGE_DIR "" #endif /* There are three ways of setting failed image diff directories. 1. Set the preprocessor macro IMAGE_DIFF_DIR to a double quoted c-string with the path. 2. Set an environment variable named IMAGE_DIFF_DIR with the path. This takes precedence over the preprocessor macro to allow for run-time override. 3. Keep everything unset, which will cause the failed image diff images to be saved inside a temporary directory. */ #ifndef IMAGE_DIFF_DIR #define IMAGE_DIFF_DIR "" #endif /** Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. @param view The view to snapshot. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param suffixes An NSOrderedSet of strings for the different suffixes. @param tolerance The overall percentage of pixels that can differ and still count as an 'identical' view. */ #define FBSnapshotVerifyViewWithOptions(view__, identifier__, suffixes__, tolerance__) \ FBSnapshotVerifyViewOrLayerWithOptions(View, view__, identifier__, suffixes__, tolerance__) /** Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. @param view The view to snapshot. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param suffixes An NSOrderedSet of strings for the different suffixes. @param pixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. @param tolerance The overall percentage of pixels that can differ and still count as an 'identical' layer. */ #define FBSnapshotVerifyViewWithPixelOptions(view__, identifier__, suffixes__, pixelTolerance__, tolerance__) \ FBSnapshotVerifyViewOrLayerWithPixelOptions(View, view__, identifier__, suffixes__, pixelTolerance__, tolerance__) #define FBSnapshotVerifyView(view__, identifier__) \ FBSnapshotVerifyViewWithOptions(view__, identifier__, FBSnapshotTestCaseDefaultSuffixes(), 0) /** Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. @param layer The layer to snapshot. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param suffixes An NSOrderedSet of strings for the different suffixes. @param pixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. @param tolerance The overall percentage of pixels that can differ and still count as an 'identical' layer. */ #define FBSnapshotVerifyLayerWithPixelOptions(layer__, identifier__, suffixes__, pixelTolerance__, tolerance__) \ FBSnapshotVerifyViewOrLayerWithPixelOptions(Layer, layer__, identifier__, suffixes__, pixelTolerance__, tolerance__) /** Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. @param layer The layer to snapshot. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param suffixes An NSOrderedSet of strings for the different suffixes. @param tolerance The overall percentage of pixels that can differ and still count as an 'identical' layer. */ #define FBSnapshotVerifyLayerWithOptions(layer__, identifier__, suffixes__, tolerance__) \ FBSnapshotVerifyViewOrLayerWithOptions(Layer, layer__, identifier__, suffixes__, tolerance__) #define FBSnapshotVerifyLayer(layer__, identifier__) \ FBSnapshotVerifyLayerWithOptions(layer__, identifier__, FBSnapshotTestCaseDefaultSuffixes(), 0) #define FBSnapshotVerifyViewOrLayerWithOptions(what__, viewOrLayer__, identifier__, suffixes__, tolerance__) \ { \ NSString *errorDescription = [self snapshotVerifyViewOrLayer:viewOrLayer__ identifier:identifier__ suffixes:suffixes__ overallTolerance:tolerance__ defaultReferenceDirectory:(@FB_REFERENCE_IMAGE_DIR) defaultImageDiffDirectory:(@IMAGE_DIFF_DIR)]; \ BOOL noErrors = (errorDescription == nil); \ XCTAssertTrue(noErrors, @"%@", errorDescription); \ } #define FBSnapshotVerifyViewOrLayerWithPixelOptions(what__, viewOrLayer__, identifier__, suffixes__, pixelTolerance__, tolerance__) \ { \ NSString *errorDescription = [self snapshotVerifyViewOrLayer:viewOrLayer__ identifier:identifier__ suffixes:suffixes__ perPixelTolerance:pixelTolerance__ overallTolerance:tolerance__ defaultReferenceDirectory:(@FB_REFERENCE_IMAGE_DIR) defaultImageDiffDirectory:(@IMAGE_DIFF_DIR)]; \ BOOL noErrors = (errorDescription == nil); \ XCTAssertTrue(noErrors, @"%@", errorDescription); \ } NS_ASSUME_NONNULL_BEGIN /** The base class of view snapshotting tests. If you have small UI component, it's often easier to configure it in a test and compare an image of the view to a reference image that write lots of complex layout-code tests. In order to flip the tests in your subclass to record the reference images set @c recordMode to @c YES. @attention When recording, the reference image directory should be explicitly set, otherwise the images may be written to somewhere inside the simulator directory. For example: @code - (void)setUp { [super setUp]; self.recordMode = YES; } @endcode */ @interface FBSnapshotTestCase : XCTestCase /** When YES, the test macros will save reference images, rather than performing an actual test. */ @property (readwrite, nonatomic, assign) BOOL recordMode; /** When set, allows fine-grained control over what you want the file names to include. Allows you to combine which device or simulator specific details you want in your snapshot file names. The default value is FBSnapshotTestCaseFileNameIncludeOptionScreenScale. @discussion If you are migrating from the now deleted FBSnapshotTestCaseAgnosticOption to FBSnapshotTestCaseFileNameIncludeOption, we default to using FBSnapshotTestCaseFileNameIncludeOptionScreenScale for fileNameOptions to make the transition easy. If you don't want to have the screen scale included in your file name, you need to set fileNameOptions to a mask that doesn't include FBSnapshotTestCaseFileNameIncludeOptionScreenScale: self.fileNameOptions = (FBSnapshotTestCaseFileNameIncludeOptionDevice | FBSnapshotTestCaseFileNameIncludeOptionOS); */ @property (readwrite, nonatomic, assign) FBSnapshotTestCaseFileNameIncludeOption fileNameOptions; /** Overrides the folder name in which the snapshot is going to be saved. @attention This property *must* be called *AFTER* [super setUp]. */ @property (readwrite, nonatomic, copy, nullable) NSString *folderName; /** When YES, renders a snapshot of the complete view hierarchy as visible onscreen. There are several things that do not work if renderInContext: is used. - UIVisualEffect #70 - UIAppearance #91 - Size Classes #92 @attention If the view does't belong to a UIWindow, it will create one and add the view as a subview. */ @property (readwrite, nonatomic, assign) BOOL usesDrawViewHierarchyInRect; - (void)setUp NS_REQUIRES_SUPER; - (void)tearDown NS_REQUIRES_SUPER; /** Performs the comparison or records a snapshot of the layer if recordMode is YES. @param viewOrLayer The UIView or CALayer to snapshot. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param suffixes An NSOrderedSet of strings for the different suffixes. @param overallTolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care. @param defaultReferenceDirectory The directory to default to for reference images. @param defaultImageDiffDirectory The directory to default to for failed image diffs. @returns nil if the comparison (or saving of the reference image) succeeded. Otherwise it contains an error description. */ - (NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer identifier:(nullable NSString *)identifier suffixes:(NSOrderedSet *)suffixes overallTolerance:(CGFloat)overallTolerance defaultReferenceDirectory:(nullable NSString *)defaultReferenceDirectory defaultImageDiffDirectory:(nullable NSString *)defaultImageDiffDirectory; /** Performs the comparison or records a snapshot of the layer if recordMode is YES. @param viewOrLayer The UIView or CALayer to snapshot. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param suffixes An NSOrderedSet of strings for the different suffixes. @param perPixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. Each color shade difference represents a 0.390625% change. @param overallTolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care. @param defaultReferenceDirectory The directory to default to for reference images. @param defaultImageDiffDirectory The directory to default to for failed image diffs. @returns nil if the comparison (or saving of the reference image) succeeded. Otherwise it contains an error description. */ - (nullable NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer identifier:(nullable NSString *)identifier suffixes:(NSOrderedSet *)suffixes perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance defaultReferenceDirectory:(nullable NSString *)defaultReferenceDirectory defaultImageDiffDirectory:(nullable NSString *)defaultImageDiffDirectory; /** Performs the comparison or records a snapshot of the layer if recordMode is YES. @param layer The Layer to snapshot. @param referenceImagesDirectory The directory in which reference images are stored. @param imageDiffDirectory The directory in which failed image diffs are stored. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param overallTolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfLayer:(CALayer *)layer referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(nullable NSString *)identifier overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Performs the comparison or records a snapshot of the layer if recordMode is YES. @param layer The Layer to snapshot. @param referenceImagesDirectory The directory in which reference images are stored. @param imageDiffDirectory The directory in which failed image diffs are stored. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param perPixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. Each color shade difference represents a 0.390625% change. @param overallTolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfLayer:(CALayer *)layer referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(nullable NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Performs the comparison or records a snapshot of the view if recordMode is YES. @param view The view to snapshot. @param referenceImagesDirectory The directory in which reference images are stored. @param imageDiffDirectory The directory in which failed image diffs are stored. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param overallTolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfView:(UIView *)view referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(nullable NSString *)identifier overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Performs the comparison or records a snapshot of the view if recordMode is YES. @param view The view to snapshot. @param referenceImagesDirectory The directory in which reference images are stored. @param imageDiffDirectory The directory in which failed image diffs are stored. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param perPixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. Each color shade difference represents a 0.390625% change. @param overallTolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfView:(UIView *)view referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(nullable NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Checks if reference image with identifier based name exists in the reference images directory. @param referenceImagesDirectory The directory in which reference images are stored. @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if reference image exists. */ - (BOOL)referenceImageRecordedInDirectory:(NSString *)referenceImagesDirectory identifier:(nullable NSString *)identifier error:(NSError **)errorPtr; /** Returns the reference image directory. Helper function used to implement the assert macros. @param dir Directory to use if environment variable not specified. Ignored if null or empty. */ - (NSString *)getReferenceImageDirectoryWithDefault:(nullable NSString *)dir; /** Returns the failed image diff directory. Helper function used to implement the assert macros. @param dir Directory to use if environment variable not specified. Ignored if null or empty. */ - (NSString *)getImageDiffDirectoryWithDefault:(nullable NSString *)dir; @end NS_ASSUME_NONNULL_END ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import #import @implementation FBSnapshotTestCase { FBSnapshotTestController *_snapshotController; } #pragma mark - Overrides - (void)setUp { [super setUp]; _snapshotController = [[FBSnapshotTestController alloc] initWithTestClass:[self class]]; } - (void)tearDown { _snapshotController = nil; [super tearDown]; } - (BOOL)recordMode { return _snapshotController.recordMode; } - (void)setRecordMode:(BOOL)recordMode { NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); _snapshotController.recordMode = recordMode; } - (FBSnapshotTestCaseFileNameIncludeOption)fileNameOptions { return _snapshotController.fileNameOptions; } - (void)setFileNameOptions:(FBSnapshotTestCaseFileNameIncludeOption)fileNameOptions { NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); _snapshotController.fileNameOptions = fileNameOptions; } - (BOOL)usesDrawViewHierarchyInRect { return _snapshotController.usesDrawViewHierarchyInRect; } - (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect { NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); _snapshotController.usesDrawViewHierarchyInRect = usesDrawViewHierarchyInRect; } - (NSString *)folderName { return _snapshotController.folderName; } - (void)setFolderName:(NSString *)folderName { _snapshotController.folderName = folderName; } #pragma mark - Public API - (NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer identifier:(NSString *)identifier suffixes:(NSOrderedSet *)suffixes overallTolerance:(CGFloat)overallTolerance defaultReferenceDirectory:(NSString *)defaultReferenceDirectory defaultImageDiffDirectory:(NSString *)defaultImageDiffDirectory { return [self snapshotVerifyViewOrLayer:viewOrLayer identifier:identifier suffixes:suffixes perPixelTolerance:0 overallTolerance:overallTolerance defaultReferenceDirectory:defaultReferenceDirectory defaultImageDiffDirectory:defaultImageDiffDirectory]; } - (NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer identifier:(NSString *)identifier suffixes:(NSOrderedSet *)suffixes perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance defaultReferenceDirectory:(NSString *)defaultReferenceDirectory defaultImageDiffDirectory:(NSString *)defaultImageDiffDirectory { if (viewOrLayer == nil) { return @"Object to be snapshotted must not be nil"; } NSString *referenceImageDirectory = [self getReferenceImageDirectoryWithDefault:defaultReferenceDirectory]; if (referenceImageDirectory == nil) { return @"Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as an Environment variable in your scheme."; } NSString *imageDiffDirectory = [self getImageDiffDirectoryWithDefault:defaultImageDiffDirectory]; if (imageDiffDirectory == nil) { return @"Missing value for imageDiffDirectory - Set IMAGE_DIFF_DIR as an Environment variable in your scheme."; } if (suffixes.count == 0) { return [NSString stringWithFormat:@"Suffixes set cannot be empty %@", suffixes]; } NSError *error = nil; NSMutableArray *errors = [NSMutableArray array]; if (self.recordMode) { NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffixes.firstObject]; BOOL referenceImageSaved = [self _compareSnapshotOfViewOrLayer:viewOrLayer referenceImagesDirectory:referenceImagesDirectory imageDiffDirectory:imageDiffDirectory identifier:(identifier) perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:&error]; if (!referenceImageSaved) { [errors addObject:error]; } return @"Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!"; } else { BOOL testSuccess = NO; for (NSString *suffix in suffixes) { NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffix]; BOOL referenceImageAvailable = [self referenceImageRecordedInDirectory:referenceImagesDirectory identifier:(identifier) error:&error]; if (referenceImageAvailable) { BOOL comparisonSuccess = [self _compareSnapshotOfViewOrLayer:viewOrLayer referenceImagesDirectory:referenceImagesDirectory imageDiffDirectory:imageDiffDirectory identifier:identifier perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:&error]; [errors removeAllObjects]; if (comparisonSuccess) { testSuccess = YES; break; } else { [errors addObject:error]; } } else { [errors addObject:error]; } } if (!testSuccess) { return [NSString stringWithFormat:@"Snapshot comparison failed: %@", errors.firstObject]; } else { return nil; } } } - (BOOL)compareSnapshotOfLayer:(CALayer *)layer referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(NSString *)identifier overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { return [self _compareSnapshotOfViewOrLayer:layer referenceImagesDirectory:referenceImagesDirectory imageDiffDirectory:imageDiffDirectory identifier:identifier perPixelTolerance:0 overallTolerance:overallTolerance error:errorPtr]; } - (BOOL)compareSnapshotOfLayer:(CALayer *)layer referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { return [self _compareSnapshotOfViewOrLayer:layer referenceImagesDirectory:referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:identifier perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:errorPtr]; } - (BOOL)compareSnapshotOfView:(UIView *)view referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(NSString *)identifier overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { return [self _compareSnapshotOfViewOrLayer:view referenceImagesDirectory:referenceImagesDirectory imageDiffDirectory:imageDiffDirectory identifier:identifier perPixelTolerance:0 overallTolerance:overallTolerance error:errorPtr]; } - (BOOL)compareSnapshotOfView:(UIView *)view referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { return [self _compareSnapshotOfViewOrLayer:view referenceImagesDirectory:referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:identifier perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:errorPtr]; } - (BOOL)referenceImageRecordedInDirectory:(NSString *)referenceImagesDirectory identifier:(NSString *)identifier error:(NSError **)errorPtr { NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); _snapshotController.referenceImagesDirectory = referenceImagesDirectory; UIImage *referenceImage = [_snapshotController referenceImageForSelector:self.invocation.selector identifier:identifier error:errorPtr]; return (referenceImage != nil); } - (NSString *)getReferenceImageDirectoryWithDefault:(NSString *)dir { NSString *envReferenceImageDirectory = [NSProcessInfo processInfo].environment[@"FB_REFERENCE_IMAGE_DIR"]; if (envReferenceImageDirectory) { return envReferenceImageDirectory; } if (dir && dir.length > 0) { return dir; } return [[NSBundle bundleForClass:self.class].resourcePath stringByAppendingPathComponent:@"ReferenceImages"]; } - (NSString *)getImageDiffDirectoryWithDefault:(NSString *)dir { NSString *envImageDiffDirectory = [NSProcessInfo processInfo].environment[@"IMAGE_DIFF_DIR"]; if (envImageDiffDirectory) { return envImageDiffDirectory; } if (dir && dir.length > 0) { return dir; } return NSTemporaryDirectory(); } #pragma mark - Private API - (BOOL)_compareSnapshotOfViewOrLayer:(id)viewOrLayer referenceImagesDirectory:(NSString *)referenceImagesDirectory imageDiffDirectory:(NSString *)imageDiffDirectory identifier:(NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { _snapshotController.referenceImagesDirectory = referenceImagesDirectory; _snapshotController.imageDiffDirectory = imageDiffDirectory; return [_snapshotController compareSnapshotOfViewOrLayer:viewOrLayer selector:self.invocation.selector identifier:identifier perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:errorPtr]; } @end ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import #ifdef __cplusplus extern "C" { #endif NS_ASSUME_NONNULL_BEGIN /** An option mask that allows you to cherry pick which parts you want to include in the snapshot file name. - FBSnapshotTestCaseFileNameIncludeOptionNone: Don't include any of these options at all. - FBSnapshotTestCaseFileNameIncludeOptionDevice: The file name should include the device name, as returned by UIDevice.currentDevice.model. - FBSnapshotTestCaseFileNameIncludeOptionOS: The file name should include the OS version, as returned by UIDevice.currentDevice.systemVersion. - FBSnapshotTestCaseFileNameIncludeOptionScreenSize: The file name should include the screen size of the current device, as returned by UIScreen.mainScreen.bounds.size. - FBSnapshotTestCaseFileNameIncludeOptionScreenScale: The file name should include the scale of the current device, as returned by UIScreen.mainScreen.scale. */ typedef NS_OPTIONS(NSUInteger, FBSnapshotTestCaseFileNameIncludeOption) { FBSnapshotTestCaseFileNameIncludeOptionNone = 1 << 0, FBSnapshotTestCaseFileNameIncludeOptionDevice = 1 << 1, FBSnapshotTestCaseFileNameIncludeOptionOS = 1 << 2, FBSnapshotTestCaseFileNameIncludeOptionScreenSize = 1 << 3, FBSnapshotTestCaseFileNameIncludeOptionScreenScale = 1 << 4 }; /** Returns a Boolean value that indicates whether the snapshot test is running in 64Bit. This method is a convenience for creating the suffixes set based on the architecture that the test is running. @returns @c YES if the test is running in 64bit, otherwise @c NO. */ BOOL FBSnapshotTestCaseIs64Bit(void); /** Returns a default set of strings that is used to append a suffix based on the architectures. @warning Do not modify this function, you can create your own and use it with @c FBSnapshotVerifyViewWithOptions() @returns An @c NSOrderedSet object containing strings that are appended to the reference images directory. */ NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void); /** Returns a fully normalized file name as per the provided option mask. Strips punctuation and spaces and replaces them with @c _. @param fileName The file name to normalize. @param option File Name Include options to use before normalization. @return An @c NSString object containing the passed @c fileName and optionally, with the device model and/or OS and/or screen size and/or screen scale appended at the end. */ NSString *FBFileNameIncludeNormalizedFileNameFromOption(NSString *fileName, FBSnapshotTestCaseFileNameIncludeOption option); NS_ASSUME_NONNULL_END #ifdef __cplusplus } #endif ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import #import BOOL FBSnapshotTestCaseIs64Bit(void) { #if __LP64__ return YES; #else return NO; #endif } NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void) { if (FBSnapshotTestCaseIs64Bit()) { return [NSOrderedSet orderedSetWithObject:@"_64"]; } else { return [NSOrderedSet orderedSetWithObject:@"_32"]; } } NSString *FBFileNameIncludeNormalizedFileNameFromOption(NSString *fileName, FBSnapshotTestCaseFileNameIncludeOption option) { if ((option & FBSnapshotTestCaseFileNameIncludeOptionDevice) == FBSnapshotTestCaseFileNameIncludeOptionDevice) { UIDevice *device = [UIDevice currentDevice]; fileName = [fileName stringByAppendingFormat:@"_%@", device.model]; } if ((option & FBSnapshotTestCaseFileNameIncludeOptionOS) == FBSnapshotTestCaseFileNameIncludeOptionOS) { UIDevice *device = [UIDevice currentDevice]; NSString *os = device.systemVersion; fileName = [fileName stringByAppendingFormat:@"_%@", os]; } if ((option & FBSnapshotTestCaseFileNameIncludeOptionScreenSize) == FBSnapshotTestCaseFileNameIncludeOptionScreenSize) { CGSize screenSize = [UIScreen mainScreen].bounds.size; fileName = [fileName stringByAppendingFormat:@"_%.0fx%.0f", screenSize.width, screenSize.height]; } NSMutableCharacterSet *invalidCharacters = [NSMutableCharacterSet new]; [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]]; [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; NSArray *validComponents = [fileName componentsSeparatedByCharactersInSet:invalidCharacters]; fileName = [validComponents componentsJoinedByString:@"_"]; if ((option & FBSnapshotTestCaseFileNameIncludeOptionScreenScale) == FBSnapshotTestCaseFileNameIncludeOptionScreenScale) { CGFloat screenScale = [[UIScreen mainScreen] scale]; fileName = [fileName stringByAppendingFormat:@"@%.fx", screenScale]; } return fileName; } ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import #import #import NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSInteger, FBSnapshotTestControllerErrorCode) { FBSnapshotTestControllerErrorCodeUnknown, FBSnapshotTestControllerErrorCodeNeedsRecord, FBSnapshotTestControllerErrorCodePNGCreationFailed, FBSnapshotTestControllerErrorCodeImagesDifferentSizes, FBSnapshotTestControllerErrorCodeImagesDifferent, }; /** Errors returned by the methods of FBSnapshotTestController use this domain. */ extern NSString *const FBSnapshotTestControllerErrorDomain; /** Errors returned by the methods of FBSnapshotTestController sometimes contain this key in the `userInfo` dictionary. */ extern NSString *const FBReferenceImageFilePathKey; /** Errors returned by the methods of FBSnapshotTestController sometimes contain this key in the `userInfo` dictionary. */ extern NSString *const FBReferenceImageKey; /** Errors returned by the methods of FBSnapshotTestController sometimes contain this key in the `userInfo` dictionary. */ extern NSString *const FBCapturedImageKey; /** Errors returned by the methods of FBSnapshotTestController sometimes contain this key in the `userInfo` dictionary. */ extern NSString *const FBDiffedImageKey; /** Provides the heavy-lifting for FBSnapshotTestCase. It loads and saves images, along with performing the actual pixel- by-pixel comparison of images. Instances are initialized with the test class, and directories to read and write to. */ @interface FBSnapshotTestController : NSObject /** Record snapshots. */ @property (readwrite, nonatomic, assign) BOOL recordMode; /** When set, allows fine-grained control over what you want the file names to include. Allows you to combine which device or simulator specific details you want in your snapshot file names. The default value is FBSnapshotTestCaseFileNameIncludeOptionScreenScale. @discussion If you are migrating from the now deleted FBSnapshotTestCaseAgnosticOption to FBSnapshotTestCaseFileNameIncludeOption, we default to using FBSnapshotTestCaseFileNameIncludeOptionScreenScale for fileNameOptions to make the transition easier. If you don't want to have the screen scale included in your file name, you need to set fileNameOptions to a mask that doesn't include FBSnapshotTestCaseFileNameIncludeOptionScreenScale: self.fileNameOptions = (FBSnapshotTestCaseFileNameIncludeOptionDevice | FBSnapshotTestCaseFileNameIncludeOptionOS); */ @property (readwrite, nonatomic, assign) FBSnapshotTestCaseFileNameIncludeOption fileNameOptions; /** Uses drawViewHierarchyInRect:afterScreenUpdates: to draw the image instead of renderInContext: */ @property (readwrite, nonatomic, assign) BOOL usesDrawViewHierarchyInRect; /** The directory in which reference images are stored. */ @property (readwrite, nonatomic, copy, nullable) NSString *referenceImagesDirectory; /** The directory in which failed snapshot images are stored. */ @property (readwrite, nonatomic, copy) NSString *imageDiffDirectory; /** The name folder in which the snapshots will be saved for a given test case. */ @property (readwrite, nonatomic, copy) NSString *folderName; /** @param testClass The subclass of FBSnapshotTestCase that is using this controller. @returns An instance of FBSnapshotTestController. */ - (instancetype)initWithTestClass:(Class)testClass; /** Performs the comparison of the layer. @param layer The Layer to snapshot. @param selector The test method being run. @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfLayer:(CALayer *)layer selector:(SEL)selector identifier:(nullable NSString *)identifier error:(NSError **)errorPtr; /** Performs the comparison of the view. @param view The view to snapshot. @param selector The test method being run. @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfView:(UIView *)view selector:(SEL)selector identifier:(nullable NSString *)identifier error:(NSError **)errorPtr; /** Performs the comparison of a view or layer. @param viewOrLayer The view or layer to snapshot. @param selector The test method being run. @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. @param overallTolerance The percentage of pixels that can differ and still be considered 'identical'. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer selector:(SEL)selector identifier:(nullable NSString *)identifier overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Performs the comparison of a view or layer. @param viewOrLayer The view or layer to snapshot. @param selector The test method being run. @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. @param perPixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. @param overallTolerance The percentage of pixels that can differ and still be considered 'identical'. @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). @returns YES if the comparison (or saving of the reference image) succeeded. */ - (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer selector:(SEL)selector identifier:(nullable NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Loads a reference image. @param selector The test method being run. @param identifier The optional identifier, used when multiple images are tested in a single -test method. @param errorPtr An error, if this methods returns nil, the error will be something useful. @returns An image. */ - (nullable UIImage *)referenceImageForSelector:(SEL)selector identifier:(nullable NSString *)identifier error:(NSError **)errorPtr; /** Performs a pixel-by-pixel comparison of the two images with an allowable margin of error. @param referenceImage The reference (correct) image. @param image The image to test against the reference. @param overallTolerance The percentage of pixels that can differ and still be considered 'identical'. @param errorPtr An error that indicates why the comparison failed if it does. @returns YES if the comparison succeeded and the images are the same(ish). */ - (BOOL)compareReferenceImage:(UIImage *)referenceImage toImage:(UIImage *)image overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Performs a pixel-by-pixel comparison of the two images with an allowable margin of error. @param referenceImage The reference (correct) image. @param image The image to test against the reference. @param perPixelTolerance The percentage a given pixel's R,G,B and A components can differ and still be considered 'identical'. @param overallTolerance The percentage of pixels that can differ and still be considered 'identical'. @param errorPtr An error that indicates why the comparison failed if it does. @returns YES if the comparison succeeded and the images are the same(ish). */ - (BOOL)compareReferenceImage:(UIImage *)referenceImage toImage:(UIImage *)image perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr; /** Saves the reference image and the test image to `failedOutputDirectory`. @param referenceImage The reference (correct) image. @param testImage The image to test against the reference. @param selector The test method being run. @param identifier The optional identifier, used when multiple images are tested in a single -test method. @param errorPtr An error that indicates why the comparison failed if it does. @returns YES if the save succeeded. */ - (BOOL)saveFailedReferenceImage:(UIImage *)referenceImage testImage:(UIImage *)testImage selector:(SEL)selector identifier:(nullable NSString *)identifier error:(NSError **)errorPtr; @end NS_ASSUME_NONNULL_END ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ #import #import #import #import #import #import #import NSString *const FBSnapshotTestControllerErrorDomain = @"FBSnapshotTestControllerErrorDomain"; NSString *const FBReferenceImageFilePathKey = @"FBReferenceImageFilePathKey"; NSString *const FBReferenceImageKey = @"FBReferenceImageKey"; NSString *const FBCapturedImageKey = @"FBCapturedImageKey"; NSString *const FBDiffedImageKey = @"FBDiffedImageKey"; typedef NS_ENUM(NSUInteger, FBTestSnapshotFileNameType) { FBTestSnapshotFileNameTypeReference, FBTestSnapshotFileNameTypeFailedReference, FBTestSnapshotFileNameTypeFailedTest, FBTestSnapshotFileNameTypeFailedTestDiff, }; @implementation FBSnapshotTestController { NSFileManager *_fileManager; } #pragma mark - Initializers - (instancetype)initWithTestClass:(Class)testClass; { if (self = [super init]) { _folderName = NSStringFromClass(testClass); _fileNameOptions = FBSnapshotTestCaseFileNameIncludeOptionScreenScale; _fileManager = [[NSFileManager alloc] init]; } return self; } #pragma mark - Overrides - (NSString *)description { return [NSString stringWithFormat:@"%@ %@", [super description], _referenceImagesDirectory]; } #pragma mark - Public API - (BOOL)compareSnapshotOfLayer:(CALayer *)layer selector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr { return [self compareSnapshotOfViewOrLayer:layer selector:selector identifier:identifier perPixelTolerance:0 overallTolerance:0 error:errorPtr]; } - (BOOL)compareSnapshotOfView:(UIView *)view selector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr { return [self compareSnapshotOfViewOrLayer:view selector:selector identifier:identifier perPixelTolerance:0 overallTolerance:0 error:errorPtr]; } - (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer selector:(SEL)selector identifier:(NSString *)identifier overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { return [self compareSnapshotOfViewOrLayer:viewOrLayer selector:selector identifier:identifier perPixelTolerance:0 overallTolerance:overallTolerance error:errorPtr]; } - (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer selector:(SEL)selector identifier:(NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { if (self.recordMode) { return [self _recordSnapshotOfViewOrLayer:viewOrLayer selector:selector identifier:identifier error:errorPtr]; } else { return [self _performPixelComparisonWithViewOrLayer:viewOrLayer selector:selector identifier:identifier perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:errorPtr]; } } - (UIImage *)referenceImageForSelector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr { NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier]; UIImage *image = [UIImage imageWithContentsOfFile:filePath]; if (image == nil && errorPtr != NULL) { BOOL exists = [_fileManager fileExistsAtPath:filePath]; if (!exists) { *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain code:FBSnapshotTestControllerErrorCodeNeedsRecord userInfo:@{ FBReferenceImageFilePathKey : filePath, NSLocalizedDescriptionKey : @"Unable to load reference image.", NSLocalizedFailureReasonErrorKey : @"Reference image not found. You need to run the test in record mode", }]; } else { *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain code:FBSnapshotTestControllerErrorCodeUnknown userInfo:nil]; } } return image; } - (BOOL)compareReferenceImage:(UIImage *)referenceImage toImage:(UIImage *)image overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { return [self compareReferenceImage:referenceImage toImage:image perPixelTolerance:0 overallTolerance:overallTolerance error:errorPtr]; } - (BOOL)compareReferenceImage:(UIImage *)referenceImage toImage:(UIImage *)image perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { CGSize referenceImageSize = CGSizeMake(CGImageGetWidth(referenceImage.CGImage), CGImageGetHeight(referenceImage.CGImage)); CGSize imageSize = CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); BOOL sameImageDimensions = CGSizeEqualToSize(referenceImageSize, imageSize); if (sameImageDimensions && [referenceImage fb_compareWithImage:image perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance]) { return YES; } if (errorPtr != NULL) { NSString *errorDescription = sameImageDimensions ? @"Images different" : @"Images different sizes"; NSString *errorReason = sameImageDimensions ? [NSString stringWithFormat:@"image pixels differed by more than %.2f%% from the reference image", overallTolerance * 100] : [NSString stringWithFormat:@"referenceImage:%@, image:%@", NSStringFromCGSize(referenceImageSize), NSStringFromCGSize(imageSize)]; FBSnapshotTestControllerErrorCode errorCode = sameImageDimensions ? FBSnapshotTestControllerErrorCodeImagesDifferent : FBSnapshotTestControllerErrorCodeImagesDifferentSizes; *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain code:errorCode userInfo:@{ NSLocalizedDescriptionKey : errorDescription, NSLocalizedFailureReasonErrorKey : errorReason, FBReferenceImageKey : referenceImage, FBCapturedImageKey : image, FBDiffedImageKey : [referenceImage fb_diffWithImage:image], }]; } return NO; } - (BOOL)saveFailedReferenceImage:(UIImage *)referenceImage testImage:(UIImage *)testImage selector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr { UIImage *diffImage = [referenceImage fb_diffWithImage:testImage]; [XCTContext runActivityNamed:identifier ?: NSStringFromSelector(selector) block:^(id _Nonnull activity) { XCTAttachment *referenceAttachment = [XCTAttachment attachmentWithImage:referenceImage]; referenceAttachment.name = @"Reference Image"; XCTAttachment *failedAttachment = [XCTAttachment attachmentWithImage:testImage]; failedAttachment.name = @"Failed Image"; XCTAttachment *diffAttachment = [XCTAttachment attachmentWithImage:diffImage]; diffAttachment.name = @"Diffed Image"; [activity addAttachment:referenceAttachment]; [activity addAttachment:failedAttachment]; [activity addAttachment:diffAttachment]; }]; NSData *referencePNGData = UIImagePNGRepresentation(referenceImage); NSData *testPNGData = UIImagePNGRepresentation(testImage); NSString *referencePath = [self _failedFilePathForSelector:selector identifier:identifier fileNameType:FBTestSnapshotFileNameTypeFailedReference]; NSError *creationError = nil; BOOL didCreateDir = [_fileManager createDirectoryAtPath:[referencePath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&creationError]; if (!didCreateDir) { if (errorPtr != NULL) { *errorPtr = creationError; } return NO; } if (![referencePNGData writeToFile:referencePath options:NSDataWritingAtomic error:errorPtr]) { return NO; } NSString *testPath = [self _failedFilePathForSelector:selector identifier:identifier fileNameType:FBTestSnapshotFileNameTypeFailedTest]; if (![testPNGData writeToFile:testPath options:NSDataWritingAtomic error:errorPtr]) { return NO; } NSString *diffPath = [self _failedFilePathForSelector:selector identifier:identifier fileNameType:FBTestSnapshotFileNameTypeFailedTestDiff]; NSData *diffImageData = UIImagePNGRepresentation(diffImage); if (![diffImageData writeToFile:diffPath options:NSDataWritingAtomic error:errorPtr]) { return NO; } NSLog(@"If you have Kaleidoscope installed you can run this command to see an image diff:\n" @"ksdiff \"%@\" \"%@\"", referencePath, testPath); return YES; } #pragma mark - Private API - (NSString *)_fileNameForSelector:(SEL)selector identifier:(NSString *)identifier fileNameType:(FBTestSnapshotFileNameType)fileNameType { NSString *fileName = nil; switch (fileNameType) { case FBTestSnapshotFileNameTypeFailedReference: fileName = @"reference_"; break; case FBTestSnapshotFileNameTypeFailedTest: fileName = @"failed_"; break; case FBTestSnapshotFileNameTypeFailedTestDiff: fileName = @"diff_"; break; default: fileName = @""; break; } fileName = [fileName stringByAppendingString:NSStringFromSelector(selector)]; if (0 < identifier.length) { fileName = [fileName stringByAppendingFormat:@"_%@", identifier]; } BOOL noFileNameOption = (self.fileNameOptions & FBSnapshotTestCaseFileNameIncludeOptionNone) == FBSnapshotTestCaseFileNameIncludeOptionNone; if (!noFileNameOption) { fileName = FBFileNameIncludeNormalizedFileNameFromOption(fileName, self.fileNameOptions); } fileName = [fileName stringByAppendingPathExtension:@"png"]; return fileName; } - (NSString *)_referenceFilePathForSelector:(SEL)selector identifier:(NSString *)identifier { NSString *fileName = [self _fileNameForSelector:selector identifier:identifier fileNameType:FBTestSnapshotFileNameTypeReference]; NSString *filePath = [_referenceImagesDirectory stringByAppendingPathComponent:self.folderName]; filePath = [filePath stringByAppendingPathComponent:fileName]; return filePath; } - (NSString *)_failedFilePathForSelector:(SEL)selector identifier:(NSString *)identifier fileNameType:(FBTestSnapshotFileNameType)fileNameType { NSString *fileName = [self _fileNameForSelector:selector identifier:identifier fileNameType:fileNameType]; NSString *filePath = [_imageDiffDirectory stringByAppendingPathComponent:self.folderName]; filePath = [filePath stringByAppendingPathComponent:fileName]; return filePath; } - (BOOL)_performPixelComparisonWithViewOrLayer:(id)viewOrLayer selector:(SEL)selector identifier:(NSString *)identifier perPixelTolerance:(CGFloat)perPixelTolerance overallTolerance:(CGFloat)overallTolerance error:(NSError **)errorPtr { UIImage *referenceImage = [self referenceImageForSelector:selector identifier:identifier error:errorPtr]; if (referenceImage != nil) { UIImage *snapshot = [self _imageForViewOrLayer:viewOrLayer]; BOOL imagesSame = [self compareReferenceImage:referenceImage toImage:snapshot perPixelTolerance:perPixelTolerance overallTolerance:overallTolerance error:errorPtr]; if (!imagesSame) { NSError *saveError = nil; if ([self saveFailedReferenceImage:referenceImage testImage:snapshot selector:selector identifier:identifier error:&saveError] == NO) { NSLog(@"Error saving test images: %@", saveError); } } return imagesSame; } return NO; } - (BOOL)_recordSnapshotOfViewOrLayer:(id)viewOrLayer selector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr { UIImage *snapshot = [self _imageForViewOrLayer:viewOrLayer]; [XCTContext runActivityNamed:identifier ?: NSStringFromSelector(selector) block:^(id _Nonnull activity) { XCTAttachment *recordedAttachment = [XCTAttachment attachmentWithImage:snapshot]; recordedAttachment.name = @"Recorded Image"; [activity addAttachment:recordedAttachment]; }]; return [self _saveReferenceImage:snapshot selector:selector identifier:identifier error:errorPtr]; } - (BOOL)_saveReferenceImage:(UIImage *)image selector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr { BOOL didWrite = NO; if (image != nil) { NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier]; NSData *pngData = UIImagePNGRepresentation(image); if (pngData != nil) { NSError *creationError = nil; BOOL didCreateDir = [_fileManager createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&creationError]; if (!didCreateDir) { if (errorPtr != NULL) { *errorPtr = creationError; } return NO; } didWrite = [pngData writeToFile:filePath options:NSDataWritingAtomic error:errorPtr]; if (didWrite) { NSLog(@"Reference image save at: %@", filePath); } } else { if (errorPtr != nil) { *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain code:FBSnapshotTestControllerErrorCodePNGCreationFailed userInfo:@{ FBReferenceImageFilePathKey : filePath, }]; } } } return didWrite; } - (UIImage *)_imageForViewOrLayer:(id)viewOrLayer { if ([viewOrLayer isKindOfClass:[UIView class]]) { if (_usesDrawViewHierarchyInRect) { return [UIImage fb_imageForView:viewOrLayer]; } else { return [UIImage fb_imageForViewLayer:viewOrLayer]; } } else if ([viewOrLayer isKindOfClass:[CALayer class]]) { return [UIImage fb_imageForLayer:viewOrLayer]; } else { [NSException raise:@"Only UIView and CALayer classes can be snapshotted" format:@"%@", viewOrLayer]; } return nil; } @end ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift ================================================ /* * Copyright (c) 2017-2018, Uber Technologies, Inc. * Copyright (c) 2015-2018, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ public extension FBSnapshotTestCase { func FBSnapshotVerifyView(_ view: UIView, identifier: String? = nil, suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), perPixelTolerance: CGFloat = 0, overallTolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) { FBSnapshotVerifyViewOrLayer(view, identifier: identifier, suffixes: suffixes, perPixelTolerance: perPixelTolerance, overallTolerance: overallTolerance, file: file, line: line) } func FBSnapshotVerifyViewController(_ viewController: UIViewController, identifier: String? = nil, suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), perPixelTolerance: CGFloat = 0, overallTolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) { viewController.view.bounds = UIScreen.main.bounds viewController.viewWillAppear(false) viewController.viewDidAppear(false) FBSnapshotVerifyView(viewController.view, identifier: identifier, suffixes: suffixes, perPixelTolerance: perPixelTolerance, overallTolerance: overallTolerance, file: file, line: line) } func FBSnapshotVerifyLayer(_ layer: CALayer, identifier: String? = nil, suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), perPixelTolerance: CGFloat = 0, overallTolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) { FBSnapshotVerifyViewOrLayer(layer, identifier: identifier, suffixes: suffixes, perPixelTolerance: perPixelTolerance, overallTolerance: overallTolerance, file: file, line: line) } private func FBSnapshotVerifyViewOrLayer(_ viewOrLayer: AnyObject, identifier: String? = nil, suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), perPixelTolerance: CGFloat = 0, overallTolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) { let envReferenceImageDirectory = self.getReferenceImageDirectory(withDefault: nil) let envImageDiffDirectory = self.getImageDiffDirectory(withDefault: nil) var error: NSError? var comparisonSuccess = false for suffix in suffixes { let referenceImagesDirectory = "\(envReferenceImageDirectory)\(suffix)" let imageDiffDirectory = envImageDiffDirectory if viewOrLayer.isKind(of: UIView.self) { do { try compareSnapshot(of: viewOrLayer as! UIView, referenceImagesDirectory: referenceImagesDirectory, imageDiffDirectory: imageDiffDirectory, identifier: identifier, perPixelTolerance: perPixelTolerance, overallTolerance: overallTolerance) comparisonSuccess = true } catch let error1 as NSError { error = error1 comparisonSuccess = false } } else if viewOrLayer.isKind(of: CALayer.self) { do { try compareSnapshot(of: viewOrLayer as! CALayer, referenceImagesDirectory: referenceImagesDirectory, imageDiffDirectory: imageDiffDirectory, identifier: identifier, perPixelTolerance: perPixelTolerance, overallTolerance: overallTolerance) comparisonSuccess = true } catch let error1 as NSError { error = error1 comparisonSuccess = false } } else { assertionFailure("Only UIView and CALayer classes can be snapshotted") } assert(recordMode == false, message: "Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!", file: file, line: line) if comparisonSuccess || recordMode { break } assert(comparisonSuccess, message: "Snapshot comparison failed: \(String(describing: error))", file: file, line: line) } } func assert(_ assertion: Bool, message: String, file: StaticString, line: UInt) { if !assertion { XCTFail(message, file: file, line: line) } } } ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/LICENSE ================================================ MIT License Copyright (c) 2017-2018, Uber Technologies, Inc. Copyright (c) 2013-2018, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: DZNEmptyDataSet/Pods/iOSSnapshotTestCase/README.md ================================================ # iOSSnapshotTestCase (previously [FBSnapshotTestCase](https://github.com/facebookarchive/ios-snapshot-test-case)) [![Build Status](https://travis-ci.org/uber/ios-snapshot-test-case.svg)](https://travis-ci.org/uber/ios-snapshot-test-case) [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/iOSSnapshotTestCase.svg)](https://img.shields.io/cocoapods/v/iOSSnapshotTestCase.svg) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) ## What it does A "snapshot test case" takes a configured `UIView` or `CALayer` and uses the necessary UIKit or Core Animation methods to generate an image snapshot of its contents. It compares this snapshot to a "reference image" stored in your source code repository and fails the test if the two images don't match. ## Why? We write a lot of UI code. There are a lot of edge cases that we want to handle correctly when you are creating `UIView` instances: - What if there is more text than can fit in the space available? - What if an image doesn't match the size of an image view? - What should the highlighted state look like? It's straightforward to test logic code, but less obvious how you should test views. You can do a lot of rectangle asserts, but these are hard to understand or visualize. Looking at an image diff shows you exactly what changed and how it will look to users. `iOSSnapshotTestCase` was developed to make snapshot tests easy. ## Installation ### Step 1: Add iOSSnapshotTestCase to your project #### CocoaPods Add the following lines to your Podfile: ```ruby target "Tests" do use_frameworks! pod 'iOSSnapshotTestCase' end ``` If your test target is Objective-C only use `iOSSnapshotTestCase/Core` instead, which doesn't contain Swift support. #### Carthage Add the following line to your Cartfile: ```carthage github "uber/ios-snapshot-test-case" ~> 6.1.0 ``` ### Step 2: Setup Test Scheme Replace "Tests" with the name of your test project. 1. There are [three ways](https://github.com/uber/ios-snapshot-test-case/blob/master/FBSnapshotTestCase/FBSnapshotTestCase.h#L19-L29) of setting reference image directories, the recommended one is to define `FB_REFERENCE_IMAGE_DIR` in your scheme. This should point to the directory where you want reference images to be stored. We normally use this: |Name|Value| |:---|:----| |`FB_REFERENCE_IMAGE_DIR`|`$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages`| |`IMAGE_DIFF_DIR`|`$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/FailureDiffs`| Define the `IMAGE_DIFF_DIR` to the directory where you want to store diffs of failed snapshots. There are also [three ways](https://github.com/uber/ios-snapshot-test-case/blob/master/FBSnapshotTestCase/FBSnapshotTestCase.h#L34-L43) to set failed image diff directories. ![](FBSnapshotTestCaseDemo/Scheme_FB_REFERENCE_IMAGE_DIR.png) ## Creating a snapshot test 1. Subclass `FBSnapshotTestCase` instead of `XCTestCase`. 2. From within your test, use `FBSnapshotVerifyView`. 3. Run the test once with `self.recordMode = YES;` in the test's `-setUp` method. (This creates the reference images on disk.) 4. Remove the line enabling record mode and run the test. ## Features - Automatically names reference images on disk according to test class and selector. - Prints a descriptive error message to the console on failure. (Bonus: failure message includes a one-line command to see an image diff if you have [Kaleidoscope](http://www.kaleidoscopeapp.com) installed.) - Supply an optional "identifier" if you want to perform multiple snapshots in a single test method. - Support for `CALayer` via `FBSnapshotVerifyLayer`. - `usesDrawViewHierarchyInRect` to handle cases like `UIVisualEffect`, `UIAppearance` and Size Classes. - `fileNameOptions` to control appending the device model (`iPhone`, `iPad`, `iPod Touch`, etc), OS version, screen size and screen scale to the images (allowing to have multiple tests for the same «snapshot» for different `OS`s and devices). ## Notes Your unit tests _should_ be inside an "application" bundle, not a "logic/library" test bundle. (That is, it should be run within the Simulator so that it has access to UIKit.) *However*, if you are writing snapshot tests inside a library/framework, you might want to keep your test bundle as a library test bundle without a Test Host. Read more on this [here](docs/LibraryVsApplicationTestBundles.md). ## Authors `iOSSnapshotTestCase` was written at Facebook by Jonathan Dann with significant contributions by Todd Krabach. Today it is maintained by [Uber](https://github.com/uber). ## License `iOSSnapshotTestCase` is MIT–licensed. See [`LICENSE`](https://github.com/uber/ios-snapshot-test-case/blob/master/LICENSE). ================================================ FILE: DZNEmptyDataSet.podspec ================================================ @version = "1.8.1" Pod::Spec.new do |s| s.name = "DZNEmptyDataSet" s.version = @version s.summary = "A drop-in UITableView/UICollectionView superclass category for showing empty datasets whenever the view has no content to display." s.description = "It will work automatically, by just conforming to DZNEmptyDataSetSource, and returning the data you want to show. The -reloadData call will be observed so the empty dataset will be configured whenever needed." s.homepage = "https://github.com/dzenbot/DZNEmptyDataSet" s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { "dzenbot" => "iromero@dzen.cl" } s.ios.deployment_target = '6.0' s.tvos.deployment_target = '9.0' s.source = { :git => "https://github.com/dzenbot/DZNEmptyDataSet.git", :tag => "v#{s.version}" } s.source_files = 'Classes', 'Source/**/*.{h,m}' s.requires_arc = true s.framework = "UIKit" end ================================================ FILE: Dangerfile ================================================ # The Dangerfile contains a collection of home-grown rules specific to your project. # http://danger.systems/ # Warn about incomplete PR title. warn("Please add a more descriptive title.") if github.pr_title.length < 10 # Warn about incomplete PR description. warn("Please add a detailed summary in the description.") if github.pr_body.length < 10 # Warn about large PR! warn("This PR is too big! Consider breaking it down into smaller PRs.") if git.lines_of_code > 2000 ================================================ FILE: Gemfile ================================================ source "https://rubygems.org" gem 'xcpretty' gem 'cocoapods' gem 'danger', '~> 4.0' ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Package.swift ================================================ // swift-tools-version:5.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "DZNEmptyDataSet", platforms: [ .iOS(.v9), .tvOS(.v9) ], products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. .library( name: "DZNEmptyDataSet", targets: ["DZNEmptyDataSet"]) ], dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target( name: "DZNEmptyDataSet", dependencies: [], path: ".", sources: ["Source"], publicHeadersPath: "Source" ) ] ) ================================================ FILE: README.md ================================================ DZNEmptyDataSet ================= [![Travis](https://travis-ci.org/dzenbot/DZNEmptyDataSet.svg?branch=master)](https://travis-ci.org/dzenbot/DZNEmptyDataSet.svg?branch=master) [![codecov](https://codecov.io/gh/dzenbot/DZNEmptyDataSet/badge.svg)](https://codecov.io/gh/dzenbot/DZNEmptyDataSet) [![Pod Version](http://img.shields.io/cocoapods/v/DZNEmptyDataSet.svg)](http://cocoadocs.org/docsets/DZNEmptyDataSet/) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![License](http://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT) ### Projects using this library [Add your project to the list here](https://github.com/dzenbot/DZNEmptyDataSet/wiki/Projects-using-DZNEmptyDataSet) and provide a (320px wide) render of the result. ### The Empty Data Set Pattern Also known as *[Empty State](http://emptystat.es/)* or *[Blank Slate](http://patternry.com/p=blank-slate/)*. Most applications show lists of content (data sets), which many turn out to be empty at one point, specially for new users with blank accounts. Empty screens create confusion by not being clear about what's going on, if there is an error/bug or if the user is supposed to do something within your app to be able to consume the content. Please read this very interesting article about [*Designing For The Empty States*](http://tympanus.net/codrops/2013/01/09/designing-for-the-empty-states/). ![Screenshots_Row1](https://raw.githubusercontent.com/dzenbot/DZNEmptyDataSet/v2-swift/Examples/Applications/Screenshots/Screenshots_row1.png) ![Screenshots_Row2](https://raw.githubusercontent.com/dzenbot/DZNEmptyDataSet/v2-swift/Examples/Applications/Screenshots/Screenshots_row2.png) (*These are real life examples, available in the 'Applications' sample project in the v2-Swift branch*) **[Empty Data Sets](http://pttrns.com/?did=1&scid=30)** are helpful for: * Avoiding white-screens and communicating to your users why the screen is empty. * Calling to action (particularly as an onboarding process). * Avoiding other interruptive mechanisms like showing error alerts. * Being consistent and improving the user experience. * Delivering a brand presence. ### Features * Compatible with UITableView and UICollectionView. Also compatible with UISearchDisplayController and UIScrollView. * Gives multiple possibilities of layout and appearance, by showing an image and/or title label and/or description label and/or button. * Uses NSAttributedString for easier appearance customisation. * Uses auto-layout to automagically center the content to the tableview, with auto-rotation support. Also accepts custom vertical and horizontal alignment. * Background color customisation. * Allows tap gesture on the whole tableview rectangle (useful for resigning first responder or similar actions). * For more advanced customisation, it allows a custom view. * Compatible with Storyboard. * Compatible with iOS 6, tvOS 9, or later. * Compatible with iPhone, iPad, and Apple TV. * **App Store ready** This library has been designed in a way where you won't need to extend UITableView or UICollectionView class. It will still work when using UITableViewController or UICollectionViewController. By just conforming to DZNEmptyDataSetSource & DZNEmptyDataSetDelegate, you will be able to fully customize the content and appearance of the empty states for your application. ## Installation Available in [CocoaPods](http://cocoapods.org/?q=DZNEmptyDataSet) ```ruby pod 'DZNEmptyDataSet' ``` To integrate DZNEmptyDataSet into your Xcode project using Carthage, specify it in your `Cartfile`: ```ruby github "dzenbot/DZNEmptyDataSet" ``` To integrate DZNEmptyDataSet into your Xcode project using SPM, specify it in your `Package.swift`: ```ruby .package( url: "https://github.com/dzenbot/DZNEmptyDataSet", .branch("master") ) ``` For existing, go to "File Navigator" -> "Select Project" -> "Project Name" -> "Swift Packages" -> "+" -> Paste "https://github.com/dzenbot/DZNEmptyDataSet" and proceed to select your target. ## How to use For complete documentation, [visit CocoaPods' auto-generated doc](http://cocoadocs.org/docsets/DZNEmptyDataSet/) ### Import ```objc #import "UIScrollView+EmptyDataSet.h" ``` Unless you are importing as a framework, then do: ```objc #import ``` ### Protocol Conformance Conform to datasource and/or delegate. ```objc @interface MainViewController : UITableViewController - (void)viewDidLoad { [super viewDidLoad]; self.tableView.emptyDataSetSource = self; self.tableView.emptyDataSetDelegate = self; // A little trick for removing the cell separators self.tableView.tableFooterView = [UIView new]; } ``` ### Data Source Implementation Return the content you want to show on the empty state, and take advantage of NSAttributedString features to customise the text appearance. The image for the empty state: ```objc - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView { return [UIImage imageNamed:@"empty_placeholder"]; } ``` The attributed string for the title of the empty state: ```objc - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"Please Allow Photo Access"; NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:18.0f], NSForegroundColorAttributeName: [UIColor darkGrayColor]}; return [[NSAttributedString alloc] initWithString:text attributes:attributes]; } ``` The attributed string for the description of the empty state: ```objc - (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { NSString *text = @"This allows you to share photos from your library and save photos to your camera roll."; NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new]; paragraph.lineBreakMode = NSLineBreakByWordWrapping; paragraph.alignment = NSTextAlignmentCenter; NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName: [UIColor lightGrayColor], NSParagraphStyleAttributeName: paragraph}; return [[NSAttributedString alloc] initWithString:text attributes:attributes]; } ``` The attributed string to be used for the specified button state: ```objc - (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0f]}; return [[NSAttributedString alloc] initWithString:@"Continue" attributes:attributes]; } ``` or the image to be used for the specified button state: ```objc - (UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { return [UIImage imageNamed:@"button_image"]; } ``` The background color for the empty state: ```objc - (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView { return [UIColor whiteColor]; } ``` If you need a more complex layout, you can return a custom view instead: ```objc - (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView { UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; [activityView startAnimating]; return activityView; } ``` The image view animation ```objc - (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"transform"]; animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0)]; animation.duration = 0.25; animation.cumulative = YES; animation.repeatCount = MAXFLOAT; return animation; } ``` Additionally, you can also adjust the vertical alignment of the content view (ie: useful when there is tableHeaderView visible): ```objc - (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView { return -self.tableView.tableHeaderView.frame.size.height/2.0f; } ``` Finally, you can separate components from each other (default separation is 11 pts): ```objc - (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView { return 20.0f; } ``` ### Delegate Implementation Return the behaviours you would expect from the empty states, and receive the user events. Asks to know if the empty state should be rendered and displayed (Default is YES) : ```objc - (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView { return YES; } ``` Asks for interaction permission (Default is YES) : ```objc - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } ``` Asks for scrolling permission (Default is NO) : ```objc - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return YES; } ``` Asks for image view animation permission (Default is NO) : ```objc - (BOOL) emptyDataSetShouldAllowImageViewAnimate:(UIScrollView *)scrollView { return YES; } ``` Notifies when the dataset view was tapped: ```objc - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { // Do something } ``` Notifies when the data set call to action button was tapped: ```objc - (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button { // Do something } ``` ### Refresh layout If you need to refresh the empty state layout, simply call: ```objc [self.tableView reloadData]; ``` or ```objc [self.collectionView reloadData]; ``` depending of which you are using. ### Force layout update You can also call `[self.tableView reloadEmptyDataSet]` to invalidate the current empty state layout and trigger a layout update, bypassing `-reloadData`. This might be useful if you have a lot of logic on your data source that you want to avoid calling, when not needed. `[self.scrollView reloadEmptyDataSet]` is the only way to refresh content when using with UIScrollView. ## Sample projects #### Applications This project replicates several popular application's empty states (~20) with their exact content and appearance, such as Airbnb, Dropbox, Facebook, Foursquare, and many others. See how easy and flexible it is to customize the appearance of your empty states. You can also use this project as a playground to test things. #### Countries This project shows a list of the world countries loaded from CoreData. It uses NSFecthedResultController for filtering search. When searching and no content is matched, a simple empty state is shown. See how to interact between the UITableViewDataSource and the DZNEmptyDataSetSource protocols, while using a typical CoreData stack. #### Colors This project is a simple example of how this library also works with UICollectionView and UISearchDisplayController, while using Storyboards. ## Collaboration Feel free to collaborate with ideas, issues and/or pull requests. ## License (The MIT License) Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Source/UIScrollView+EmptyDataSet.h ================================================ // // UIScrollView+EmptyDataSet.h // DZNEmptyDataSet // https://github.com/dzenbot/DZNEmptyDataSet // // Created by Ignacio Romero Zurbuchen on 6/20/14. // Copyright (c) 2016 DZN Labs. All rights reserved. // Licence: MIT-Licence // #import NS_ASSUME_NONNULL_BEGIN @protocol DZNEmptyDataSetSource; @protocol DZNEmptyDataSetDelegate; #define DZNEmptyDataSetDeprecated(instead) DEPRECATED_MSG_ATTRIBUTE(" Use " # instead " instead") /** A drop-in UITableView/UICollectionView superclass category for showing empty datasets whenever the view has no content to display. @discussion It will work automatically, by just conforming to DZNEmptyDataSetSource, and returning the data you want to show. */ @interface UIScrollView (EmptyDataSet) /** The empty datasets data source. */ @property (nonatomic, weak, nullable) IBOutlet id emptyDataSetSource; /** The empty datasets delegate. */ @property (nonatomic, weak, nullable) IBOutlet id emptyDataSetDelegate; /** YES if any empty dataset is visible. */ @property (nonatomic, readonly, getter = isEmptyDataSetVisible) BOOL emptyDataSetVisible; /** Reloads the empty dataset content receiver. @discussion Call this method to force all the data to refresh. Calling -reloadData is similar, but this forces only the empty dataset to reload, not the entire table view or collection view. */ - (void)reloadEmptyDataSet; @end /** The object that acts as the data source of the empty datasets. @discussion The data source must adopt the DZNEmptyDataSetSource protocol. The data source is not retained. All data source methods are optional. */ @protocol DZNEmptyDataSetSource @optional /** Asks the data source for the title of the dataset. The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. @param scrollView A scrollView subclass informing the data source. @return An attributed string for the dataset title, combining font, text color, text pararaph style, etc. */ - (nullable NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for the description of the dataset. The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. @param scrollView A scrollView subclass informing the data source. @return An attributed string for the dataset description text, combining font, text color, text pararaph style, etc. */ - (nullable NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for the image of the dataset. @param scrollView A scrollView subclass informing the data source. @return An image for the dataset. */ - (nullable UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for a tint color of the image dataset. Default is nil. @param scrollView A scrollView subclass object informing the data source. @return A color to tint the image of the dataset. */ - (nullable UIColor *)imageTintColorForEmptyDataSet:(UIScrollView *)scrollView; /** * Asks the data source for the image animation of the dataset. * * @param scrollView A scrollView subclass object informing the delegate. * * @return image animation */ - (nullable CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for the title to be used for the specified button state. The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. @param scrollView A scrollView subclass object informing the data source. @param state The state that uses the specified title. The possible values are described in UIControlState. @return An attributed string for the dataset button title, combining font, text color, text pararaph style, etc. */ - (nullable NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state; /** Asks the data source for the image to be used for the specified button state. This method will override buttonTitleForEmptyDataSet:forState: and present the image only without any text. @param scrollView A scrollView subclass object informing the data source. @param state The state that uses the specified title. The possible values are described in UIControlState. @return An image for the dataset button imageview. */ - (nullable UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state; /** Asks the data source for a background image to be used for the specified button state. There is no default style for this call. @param scrollView A scrollView subclass informing the data source. @param state The state that uses the specified image. The values are described in UIControlState. @return An attributed string for the dataset button title, combining font, text color, text pararaph style, etc. */ - (nullable UIImage *)buttonBackgroundImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state; /** Asks the data source for the background color of the dataset. Default is clear color. @param scrollView A scrollView subclass object informing the data source. @return A color to be applied to the dataset background view. */ - (nullable UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for a custom view to be displayed instead of the default views such as labels, imageview and button. Default is nil. Use this method to show an activity view indicator for loading feedback, or for complete custom empty data set. Returning a custom view will ignore -offsetForEmptyDataSet and -spaceHeightForEmptyDataSet configurations. @param scrollView A scrollView subclass object informing the delegate. @return The custom view. */ - (nullable UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for a offset for vertical and horizontal alignment of the content. Default is CGPointZero. @param scrollView A scrollView subclass object informing the delegate. @return The offset for vertical and horizontal alignment. */ - (CGPoint)offsetForEmptyDataSet:(UIScrollView *)scrollView DZNEmptyDataSetDeprecated(-verticalOffsetForEmptyDataSet:); - (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView; /** Asks the data source for a vertical space between elements. Default is 11 pts. @param scrollView A scrollView subclass object informing the delegate. @return The space height between elements. */ - (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView; @end /** The object that acts as the delegate of the empty datasets. @discussion The delegate can adopt the DZNEmptyDataSetDelegate protocol. The delegate is not retained. All delegate methods are optional. @discussion All delegate methods are optional. Use this delegate for receiving action callbacks. */ @protocol DZNEmptyDataSetDelegate @optional /** Asks the delegate to know if the empty dataset should fade in when displayed. Default is YES. @param scrollView A scrollView subclass object informing the delegate. @return YES if the empty dataset should fade in. */ - (BOOL)emptyDataSetShouldFadeIn:(UIScrollView *)scrollView; /** Asks the delegate to know if the empty dataset should still be displayed when the amount of items is more than 0. Default is NO @param scrollView A scrollView subclass object informing the delegate. @return YES if empty dataset should be forced to display */ - (BOOL)emptyDataSetShouldBeForcedToDisplay:(UIScrollView *)scrollView; /** Asks the delegate to know if the empty dataset should be rendered and displayed. Default is YES. @param scrollView A scrollView subclass object informing the delegate. @return YES if the empty dataset should show. */ - (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView; /** Asks the delegate for touch permission. Default is YES. @param scrollView A scrollView subclass object informing the delegate. @return YES if the empty dataset receives touch gestures. */ - (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView; /** Asks the delegate for scroll permission. Default is NO. @param scrollView A scrollView subclass object informing the delegate. @return YES if the empty dataset is allowed to be scrollable. */ - (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView; /** Asks the delegate for image view animation permission. Default is NO. Make sure to return a valid CAAnimation object from imageAnimationForEmptyDataSet: @param scrollView A scrollView subclass object informing the delegate. @return YES if the empty dataset is allowed to animate */ - (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView; /** Tells the delegate that the empty dataset view was tapped. Use this method either to resignFirstResponder of a textfield or searchBar. @param scrollView A scrollView subclass informing the delegate. */ - (void)emptyDataSetDidTapView:(UIScrollView *)scrollView DZNEmptyDataSetDeprecated(-emptyDataSet:didTapView:); /** Tells the delegate that the action button was tapped. @param scrollView A scrollView subclass informing the delegate. */ - (void)emptyDataSetDidTapButton:(UIScrollView *)scrollView DZNEmptyDataSetDeprecated(-emptyDataSet:didTapButton:); /** Tells the delegate that the empty dataset view was tapped. Use this method either to resignFirstResponder of a textfield or searchBar. @param scrollView A scrollView subclass informing the delegate. @param view the view tapped by the user */ - (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view; /** Tells the delegate that the action button was tapped. @param scrollView A scrollView subclass informing the delegate. @param button the button tapped by the user */ - (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button; /** Tells the delegate that the empty data set will appear. @param scrollView A scrollView subclass informing the delegate. */ - (void)emptyDataSetWillAppear:(UIScrollView *)scrollView; /** Tells the delegate that the empty data set did appear. @param scrollView A scrollView subclass informing the delegate. */ - (void)emptyDataSetDidAppear:(UIScrollView *)scrollView; /** Tells the delegate that the empty data set will disappear. @param scrollView A scrollView subclass informing the delegate. */ - (void)emptyDataSetWillDisappear:(UIScrollView *)scrollView; /** Tells the delegate that the empty data set did disappear. @param scrollView A scrollView subclass informing the delegate. */ - (void)emptyDataSetDidDisappear:(UIScrollView *)scrollView; @end #undef DZNEmptyDataSetDeprecated NS_ASSUME_NONNULL_END ================================================ FILE: Source/UIScrollView+EmptyDataSet.m ================================================ // // UIScrollView+EmptyDataSet.m // DZNEmptyDataSet // https://github.com/dzenbot/DZNEmptyDataSet // // Created by Ignacio Romero Zurbuchen on 6/20/14. // Copyright (c) 2016 DZN Labs. All rights reserved. // Licence: MIT-Licence // #import "UIScrollView+EmptyDataSet.h" #import @interface UIView (DZNConstraintBasedLayoutExtensions) - (NSLayoutConstraint *)equallyRelatedConstraintWithView:(UIView *)view attribute:(NSLayoutAttribute)attribute; @end @interface DZNWeakObjectContainer : NSObject @property (nonatomic, readonly, weak) id weakObject; - (instancetype)initWithWeakObject:(id)object; @end @interface DZNEmptyDataSetView : UIView @property (nonatomic, readonly) UIView *contentView; @property (nonatomic, readonly) UILabel *titleLabel; @property (nonatomic, readonly) UILabel *detailLabel; @property (nonatomic, readonly) UIImageView *imageView; @property (nonatomic, readonly) UIButton *button; @property (nonatomic, strong) UIView *customView; @property (nonatomic, strong) UITapGestureRecognizer *tapGesture; @property (nonatomic, assign) CGFloat verticalOffset; @property (nonatomic, assign) CGFloat verticalSpace; @property (nonatomic, assign) BOOL fadeInOnDisplay; - (void)setupConstraints; - (void)prepareForReuse; @end #pragma mark - UIScrollView+EmptyDataSet static char const * const kEmptyDataSetSource = "emptyDataSetSource"; static char const * const kEmptyDataSetDelegate = "emptyDataSetDelegate"; static char const * const kEmptyDataSetView = "emptyDataSetView"; #define kEmptyImageViewAnimationKey @"com.dzn.emptyDataSet.imageViewAnimation" @interface UIScrollView () @property (nonatomic, readonly) DZNEmptyDataSetView *emptyDataSetView; @end @implementation UIScrollView (DZNEmptyDataSet) #pragma mark - Getters (Public) - (id)emptyDataSetSource { DZNWeakObjectContainer *container = objc_getAssociatedObject(self, kEmptyDataSetSource); return container.weakObject; } - (id)emptyDataSetDelegate { DZNWeakObjectContainer *container = objc_getAssociatedObject(self, kEmptyDataSetDelegate); return container.weakObject; } - (BOOL)isEmptyDataSetVisible { UIView *view = objc_getAssociatedObject(self, kEmptyDataSetView); return view ? !view.hidden : NO; } #pragma mark - Getters (Private) - (DZNEmptyDataSetView *)emptyDataSetView { DZNEmptyDataSetView *view = objc_getAssociatedObject(self, kEmptyDataSetView); if (!view) { view = [DZNEmptyDataSetView new]; view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; view.hidden = YES; view.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dzn_didTapContentView:)]; view.tapGesture.delegate = self; [view addGestureRecognizer:view.tapGesture]; [self setEmptyDataSetView:view]; } return view; } - (BOOL)dzn_canDisplay { if (self.emptyDataSetSource && [self.emptyDataSetSource conformsToProtocol:@protocol(DZNEmptyDataSetSource)]) { if ([self isKindOfClass:[UITableView class]] || [self isKindOfClass:[UICollectionView class]] || [self isKindOfClass:[UIScrollView class]]) { return YES; } } return NO; } - (NSInteger)dzn_itemsCount { NSInteger items = 0; // UIScollView doesn't respond to 'dataSource' so let's exit if (![self respondsToSelector:@selector(dataSource)]) { return items; } // UITableView support if ([self isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)self; id dataSource = tableView.dataSource; NSInteger sections = 1; if (dataSource && [dataSource respondsToSelector:@selector(numberOfSectionsInTableView:)]) { sections = [dataSource numberOfSectionsInTableView:tableView]; } if (dataSource && [dataSource respondsToSelector:@selector(tableView:numberOfRowsInSection:)]) { for (NSInteger section = 0; section < sections; section++) { items += [dataSource tableView:tableView numberOfRowsInSection:section]; } } } // UICollectionView support else if ([self isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)self; id dataSource = collectionView.dataSource; NSInteger sections = 1; if (dataSource && [dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)]) { sections = [dataSource numberOfSectionsInCollectionView:collectionView]; } if (dataSource && [dataSource respondsToSelector:@selector(collectionView:numberOfItemsInSection:)]) { for (NSInteger section = 0; section < sections; section++) { items += [dataSource collectionView:collectionView numberOfItemsInSection:section]; } } } return items; } #pragma mark - Data Source Getters - (NSAttributedString *)dzn_titleLabelString { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(titleForEmptyDataSet:)]) { NSAttributedString *string = [self.emptyDataSetSource titleForEmptyDataSet:self]; if (string) NSAssert([string isKindOfClass:[NSAttributedString class]], @"You must return a valid NSAttributedString object for -titleForEmptyDataSet:"); return string; } return nil; } - (NSAttributedString *)dzn_detailLabelString { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(descriptionForEmptyDataSet:)]) { NSAttributedString *string = [self.emptyDataSetSource descriptionForEmptyDataSet:self]; if (string) NSAssert([string isKindOfClass:[NSAttributedString class]], @"You must return a valid NSAttributedString object for -descriptionForEmptyDataSet:"); return string; } return nil; } - (UIImage *)dzn_image { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(imageForEmptyDataSet:)]) { UIImage *image = [self.emptyDataSetSource imageForEmptyDataSet:self]; if (image) NSAssert([image isKindOfClass:[UIImage class]], @"You must return a valid UIImage object for -imageForEmptyDataSet:"); return image; } return nil; } - (CAAnimation *)dzn_imageAnimation { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(imageAnimationForEmptyDataSet:)]) { CAAnimation *imageAnimation = [self.emptyDataSetSource imageAnimationForEmptyDataSet:self]; if (imageAnimation) NSAssert([imageAnimation isKindOfClass:[CAAnimation class]], @"You must return a valid CAAnimation object for -imageAnimationForEmptyDataSet:"); return imageAnimation; } return nil; } - (UIColor *)dzn_imageTintColor { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(imageTintColorForEmptyDataSet:)]) { UIColor *color = [self.emptyDataSetSource imageTintColorForEmptyDataSet:self]; if (color) NSAssert([color isKindOfClass:[UIColor class]], @"You must return a valid UIColor object for -imageTintColorForEmptyDataSet:"); return color; } return nil; } - (NSAttributedString *)dzn_buttonTitleForState:(UIControlState)state { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(buttonTitleForEmptyDataSet:forState:)]) { NSAttributedString *string = [self.emptyDataSetSource buttonTitleForEmptyDataSet:self forState:state]; if (string) NSAssert([string isKindOfClass:[NSAttributedString class]], @"You must return a valid NSAttributedString object for -buttonTitleForEmptyDataSet:forState:"); return string; } return nil; } - (UIImage *)dzn_buttonImageForState:(UIControlState)state { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(buttonImageForEmptyDataSet:forState:)]) { UIImage *image = [self.emptyDataSetSource buttonImageForEmptyDataSet:self forState:state]; if (image) NSAssert([image isKindOfClass:[UIImage class]], @"You must return a valid UIImage object for -buttonImageForEmptyDataSet:forState:"); return image; } return nil; } - (UIImage *)dzn_buttonBackgroundImageForState:(UIControlState)state { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(buttonBackgroundImageForEmptyDataSet:forState:)]) { UIImage *image = [self.emptyDataSetSource buttonBackgroundImageForEmptyDataSet:self forState:state]; if (image) NSAssert([image isKindOfClass:[UIImage class]], @"You must return a valid UIImage object for -buttonBackgroundImageForEmptyDataSet:forState:"); return image; } return nil; } - (UIColor *)dzn_dataSetBackgroundColor { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(backgroundColorForEmptyDataSet:)]) { UIColor *color = [self.emptyDataSetSource backgroundColorForEmptyDataSet:self]; if (color) NSAssert([color isKindOfClass:[UIColor class]], @"You must return a valid UIColor object for -backgroundColorForEmptyDataSet:"); return color; } return [UIColor clearColor]; } - (UIView *)dzn_customView { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(customViewForEmptyDataSet:)]) { UIView *view = [self.emptyDataSetSource customViewForEmptyDataSet:self]; if (view) NSAssert([view isKindOfClass:[UIView class]], @"You must return a valid UIView object for -customViewForEmptyDataSet:"); return view; } return nil; } - (CGFloat)dzn_verticalOffset { CGFloat offset = 0.0; if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(verticalOffsetForEmptyDataSet:)]) { offset = [self.emptyDataSetSource verticalOffsetForEmptyDataSet:self]; } return offset; } - (CGFloat)dzn_verticalSpace { if (self.emptyDataSetSource && [self.emptyDataSetSource respondsToSelector:@selector(spaceHeightForEmptyDataSet:)]) { return [self.emptyDataSetSource spaceHeightForEmptyDataSet:self]; } return 0.0; } #pragma mark - Delegate Getters & Events (Private) - (BOOL)dzn_shouldFadeIn { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetShouldFadeIn:)]) { return [self.emptyDataSetDelegate emptyDataSetShouldFadeIn:self]; } return YES; } - (BOOL)dzn_shouldDisplay { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetShouldDisplay:)]) { return [self.emptyDataSetDelegate emptyDataSetShouldDisplay:self]; } return YES; } - (BOOL)dzn_shouldBeForcedToDisplay { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetShouldBeForcedToDisplay:)]) { return [self.emptyDataSetDelegate emptyDataSetShouldBeForcedToDisplay:self]; } return NO; } - (BOOL)dzn_isTouchAllowed { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetShouldAllowTouch:)]) { return [self.emptyDataSetDelegate emptyDataSetShouldAllowTouch:self]; } return YES; } - (BOOL)dzn_isScrollAllowed { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetShouldAllowScroll:)]) { return [self.emptyDataSetDelegate emptyDataSetShouldAllowScroll:self]; } return NO; } - (BOOL)dzn_isImageViewAnimateAllowed { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetShouldAnimateImageView:)]) { return [self.emptyDataSetDelegate emptyDataSetShouldAnimateImageView:self]; } return NO; } - (void)dzn_willAppear { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetWillAppear:)]) { [self.emptyDataSetDelegate emptyDataSetWillAppear:self]; } } - (void)dzn_didAppear { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetDidAppear:)]) { [self.emptyDataSetDelegate emptyDataSetDidAppear:self]; } } - (void)dzn_willDisappear { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetWillDisappear:)]) { [self.emptyDataSetDelegate emptyDataSetWillDisappear:self]; } } - (void)dzn_didDisappear { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetDidDisappear:)]) { [self.emptyDataSetDelegate emptyDataSetDidDisappear:self]; } } - (void)dzn_didTapContentView:(id)sender { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSet:didTapView:)]) { [self.emptyDataSetDelegate emptyDataSet:self didTapView:sender]; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" else if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetDidTapView:)]) { [self.emptyDataSetDelegate emptyDataSetDidTapView:self]; } #pragma clang diagnostic pop } - (void)dzn_didTapDataButton:(id)sender { if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSet:didTapButton:)]) { [self.emptyDataSetDelegate emptyDataSet:self didTapButton:sender]; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" else if (self.emptyDataSetDelegate && [self.emptyDataSetDelegate respondsToSelector:@selector(emptyDataSetDidTapButton:)]) { [self.emptyDataSetDelegate emptyDataSetDidTapButton:self]; } #pragma clang diagnostic pop } #pragma mark - Setters (Public) - (void)setEmptyDataSetSource:(id)datasource { if (!datasource || ![self dzn_canDisplay]) { [self dzn_invalidate]; } objc_setAssociatedObject(self, kEmptyDataSetSource, [[DZNWeakObjectContainer alloc] initWithWeakObject:datasource], OBJC_ASSOCIATION_RETAIN_NONATOMIC); // We add method sizzling for injecting -dzn_reloadData implementation to the native -reloadData implementation [self swizzleIfPossible:@selector(reloadData)]; // Exclusively for UITableView, we also inject -dzn_reloadData to -endUpdates if ([self isKindOfClass:[UITableView class]]) { [self swizzleIfPossible:@selector(endUpdates)]; } } - (void)setEmptyDataSetDelegate:(id)delegate { if (!delegate) { [self dzn_invalidate]; } objc_setAssociatedObject(self, kEmptyDataSetDelegate, [[DZNWeakObjectContainer alloc] initWithWeakObject:delegate], OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - Setters (Private) - (void)setEmptyDataSetView:(DZNEmptyDataSetView *)view { objc_setAssociatedObject(self, kEmptyDataSetView, view, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - Reload APIs (Public) - (void)reloadEmptyDataSet { [self dzn_reloadEmptyDataSet]; } #pragma mark - Reload APIs (Private) - (void)dzn_reloadEmptyDataSet { if (![self dzn_canDisplay]) { return; } if (([self dzn_shouldDisplay] && [self dzn_itemsCount] == 0) || [self dzn_shouldBeForcedToDisplay]) { // Notifies that the empty dataset view will appear [self dzn_willAppear]; DZNEmptyDataSetView *view = self.emptyDataSetView; // Configure empty dataset fade in display view.fadeInOnDisplay = [self dzn_shouldFadeIn]; if (!view.superview) { // Send the view all the way to the back, in case a header and/or footer is present, as well as for sectionHeaders or any other content if (([self isKindOfClass:[UITableView class]] || [self isKindOfClass:[UICollectionView class]]) && self.subviews.count > 1) { [self insertSubview:view atIndex:0]; } else { [self addSubview:view]; } } // Removing view resetting the view and its constraints it very important to guarantee a good state [view prepareForReuse]; UIView *customView = [self dzn_customView]; // If a non-nil custom view is available, let's configure it instead if (customView) { view.customView = customView; } else { // Get the data from the data source NSAttributedString *titleLabelString = [self dzn_titleLabelString]; NSAttributedString *detailLabelString = [self dzn_detailLabelString]; UIImage *buttonImage = [self dzn_buttonImageForState:UIControlStateNormal]; NSAttributedString *buttonTitle = [self dzn_buttonTitleForState:UIControlStateNormal]; UIImage *image = [self dzn_image]; UIColor *imageTintColor = [self dzn_imageTintColor]; UIImageRenderingMode renderingMode = imageTintColor ? UIImageRenderingModeAlwaysTemplate : UIImageRenderingModeAlwaysOriginal; view.verticalSpace = [self dzn_verticalSpace]; // Configure Image if (image) { if ([image respondsToSelector:@selector(imageWithRenderingMode:)]) { view.imageView.image = [image imageWithRenderingMode:renderingMode]; view.imageView.tintColor = imageTintColor; } else { // iOS 6 fallback: insert code to convert imaged if needed view.imageView.image = image; } } // Configure title label if (titleLabelString) { view.titleLabel.attributedText = titleLabelString; } // Configure detail label if (detailLabelString) { view.detailLabel.attributedText = detailLabelString; } // Configure button if (buttonImage) { [view.button setImage:buttonImage forState:UIControlStateNormal]; [view.button setImage:[self dzn_buttonImageForState:UIControlStateHighlighted] forState:UIControlStateHighlighted]; } else if (buttonTitle) { [view.button setAttributedTitle:buttonTitle forState:UIControlStateNormal]; [view.button setAttributedTitle:[self dzn_buttonTitleForState:UIControlStateHighlighted] forState:UIControlStateHighlighted]; [view.button setBackgroundImage:[self dzn_buttonBackgroundImageForState:UIControlStateNormal] forState:UIControlStateNormal]; [view.button setBackgroundImage:[self dzn_buttonBackgroundImageForState:UIControlStateHighlighted] forState:UIControlStateHighlighted]; } } // Configure offset view.verticalOffset = [self dzn_verticalOffset]; // Configure the empty dataset view view.backgroundColor = [self dzn_dataSetBackgroundColor]; view.hidden = NO; view.clipsToBounds = YES; // Configure empty dataset userInteraction permission view.userInteractionEnabled = [self dzn_isTouchAllowed]; [view setupConstraints]; [UIView performWithoutAnimation:^{ [view layoutIfNeeded]; }]; // Configure scroll permission self.scrollEnabled = [self dzn_isScrollAllowed]; // Configure image view animation if ([self dzn_isImageViewAnimateAllowed]) { CAAnimation *animation = [self dzn_imageAnimation]; if (animation) { [self.emptyDataSetView.imageView.layer addAnimation:animation forKey:kEmptyImageViewAnimationKey]; } } else if ([self.emptyDataSetView.imageView.layer animationForKey:kEmptyImageViewAnimationKey]) { [self.emptyDataSetView.imageView.layer removeAnimationForKey:kEmptyImageViewAnimationKey]; } // Notifies that the empty dataset view did appear [self dzn_didAppear]; } else if (self.isEmptyDataSetVisible) { [self dzn_invalidate]; } } - (void)dzn_invalidate { // Notifies that the empty dataset view will disappear [self dzn_willDisappear]; if (self.emptyDataSetView) { [self.emptyDataSetView prepareForReuse]; [self.emptyDataSetView removeFromSuperview]; [self setEmptyDataSetView:nil]; } self.scrollEnabled = YES; // Notifies that the empty dataset view did disappear [self dzn_didDisappear]; } #pragma mark - Method Swizzling static NSMutableDictionary *_impLookupTable; static NSString *const DZNSwizzleInfoPointerKey = @"pointer"; static NSString *const DZNSwizzleInfoOwnerKey = @"owner"; static NSString *const DZNSwizzleInfoSelectorKey = @"selector"; // Based on Bryce Buchanan's swizzling technique http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/ // And Juzzin's ideas https://github.com/juzzin/JUSEmptyViewController void dzn_original_implementation(id self, SEL _cmd) { // Fetch original implementation from lookup table Class baseClass = dzn_baseClassToSwizzleForTarget(self); NSString *key = dzn_implementationKey(baseClass, _cmd); NSDictionary *swizzleInfo = [_impLookupTable objectForKey:key]; NSValue *impValue = [swizzleInfo valueForKey:DZNSwizzleInfoPointerKey]; IMP impPointer = [impValue pointerValue]; // We then inject the additional implementation for reloading the empty dataset // Doing it before calling the original implementation does update the 'isEmptyDataSetVisible' flag on time. [self dzn_reloadEmptyDataSet]; // If found, call original implementation if (impPointer) { ((void(*)(id,SEL))impPointer)(self,_cmd); } } NSString *dzn_implementationKey(Class class, SEL selector) { if (!class || !selector) { return nil; } NSString *className = NSStringFromClass([class class]); NSString *selectorName = NSStringFromSelector(selector); return [NSString stringWithFormat:@"%@_%@",className,selectorName]; } Class dzn_baseClassToSwizzleForTarget(id target) { if ([target isKindOfClass:[UITableView class]]) { return [UITableView class]; } else if ([target isKindOfClass:[UICollectionView class]]) { return [UICollectionView class]; } else if ([target isKindOfClass:[UIScrollView class]]) { return [UIScrollView class]; } return nil; } - (void)swizzleIfPossible:(SEL)selector { // Check if the target responds to selector if (![self respondsToSelector:selector]) { return; } // Create the lookup table if (!_impLookupTable) { _impLookupTable = [[NSMutableDictionary alloc] initWithCapacity:3]; // 3 represent the supported base classes } // We make sure that setImplementation is called once per class kind, UITableView or UICollectionView. for (NSDictionary *info in [_impLookupTable allValues]) { Class class = [info objectForKey:DZNSwizzleInfoOwnerKey]; NSString *selectorName = [info objectForKey:DZNSwizzleInfoSelectorKey]; if ([selectorName isEqualToString:NSStringFromSelector(selector)]) { if ([self isKindOfClass:class]) { return; } } } Class baseClass = dzn_baseClassToSwizzleForTarget(self); NSString *key = dzn_implementationKey(baseClass, selector); NSValue *impValue = [[_impLookupTable objectForKey:key] valueForKey:DZNSwizzleInfoPointerKey]; // If the implementation for this class already exist, skip!! if (impValue || !key || !baseClass) { return; } // Swizzle by injecting additional implementation Method method = class_getInstanceMethod(baseClass, selector); IMP dzn_newImplementation = method_setImplementation(method, (IMP)dzn_original_implementation); // Store the new implementation in the lookup table NSDictionary *swizzledInfo = @{DZNSwizzleInfoOwnerKey: baseClass, DZNSwizzleInfoSelectorKey: NSStringFromSelector(selector), DZNSwizzleInfoPointerKey: [NSValue valueWithPointer:dzn_newImplementation]}; [_impLookupTable setObject:swizzledInfo forKey:key]; } #pragma mark - UIGestureRecognizerDelegate Methods - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { if ([gestureRecognizer.view isEqual:self.emptyDataSetView]) { return [self dzn_isTouchAllowed]; } return [super gestureRecognizerShouldBegin:gestureRecognizer]; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { UIGestureRecognizer *tapGesture = self.emptyDataSetView.tapGesture; if ([gestureRecognizer isEqual:tapGesture] || [otherGestureRecognizer isEqual:tapGesture]) { return YES; } // defer to emptyDataSetDelegate's implementation if available if ( (self.emptyDataSetDelegate != (id)self) && [self.emptyDataSetDelegate respondsToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]) { return [(id)self.emptyDataSetDelegate gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer]; } return NO; } @end #pragma mark - DZNEmptyDataSetView @interface DZNEmptyDataSetView () @end @implementation DZNEmptyDataSetView @synthesize contentView = _contentView; @synthesize titleLabel = _titleLabel, detailLabel = _detailLabel, imageView = _imageView, button = _button; #pragma mark - Initialization Methods - (instancetype)init { self = [super init]; if (self) { [self addSubview:self.contentView]; } return self; } - (void)didMoveToSuperview { CGRect superviewBounds = self.superview.bounds; self.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(superviewBounds), CGRectGetHeight(superviewBounds)); void(^fadeInBlock)(void) = ^{_contentView.alpha = 1.0;}; if (self.fadeInOnDisplay) { [UIView animateWithDuration:0.25 animations:fadeInBlock completion:NULL]; } else { fadeInBlock(); } } #pragma mark - Getters - (UIView *)contentView { if (!_contentView) { _contentView = [UIView new]; _contentView.translatesAutoresizingMaskIntoConstraints = NO; _contentView.backgroundColor = [UIColor clearColor]; _contentView.userInteractionEnabled = YES; _contentView.alpha = 0; } return _contentView; } - (UIImageView *)imageView { if (!_imageView) { _imageView = [UIImageView new]; _imageView.translatesAutoresizingMaskIntoConstraints = NO; _imageView.backgroundColor = [UIColor clearColor]; _imageView.contentMode = UIViewContentModeScaleAspectFit; _imageView.userInteractionEnabled = NO; _imageView.accessibilityIdentifier = @"empty set background image"; [_contentView addSubview:_imageView]; } return _imageView; } - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _titleLabel.backgroundColor = [UIColor clearColor]; _titleLabel.font = [UIFont systemFontOfSize:27.0]; _titleLabel.textColor = [UIColor colorWithWhite:0.6 alpha:1.0]; _titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; _titleLabel.numberOfLines = 0; _titleLabel.accessibilityIdentifier = @"empty set title"; [_contentView addSubview:_titleLabel]; } return _titleLabel; } - (UILabel *)detailLabel { if (!_detailLabel) { _detailLabel = [UILabel new]; _detailLabel.translatesAutoresizingMaskIntoConstraints = NO; _detailLabel.backgroundColor = [UIColor clearColor]; _detailLabel.font = [UIFont systemFontOfSize:17.0]; _detailLabel.textColor = [UIColor colorWithWhite:0.6 alpha:1.0]; _detailLabel.textAlignment = NSTextAlignmentCenter; _detailLabel.lineBreakMode = NSLineBreakByWordWrapping; _detailLabel.numberOfLines = 0; _detailLabel.accessibilityIdentifier = @"empty set detail label"; [_contentView addSubview:_detailLabel]; } return _detailLabel; } - (UIButton *)button { if (!_button) { _button = [UIButton buttonWithType:UIButtonTypeCustom]; _button.translatesAutoresizingMaskIntoConstraints = NO; _button.backgroundColor = [UIColor clearColor]; _button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; _button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; _button.accessibilityIdentifier = @"empty set button"; [_button addTarget:self action:@selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside]; [_contentView addSubview:_button]; } return _button; } - (BOOL)canShowImage { return (_imageView.image && _imageView.superview); } - (BOOL)canShowTitle { return (_titleLabel.attributedText.string.length > 0 && _titleLabel.superview); } - (BOOL)canShowDetail { return (_detailLabel.attributedText.string.length > 0 && _detailLabel.superview); } - (BOOL)canShowButton { if ([_button attributedTitleForState:UIControlStateNormal].string.length > 0 || [_button imageForState:UIControlStateNormal]) { return (_button.superview != nil); } return NO; } #pragma mark - Setters - (void)setCustomView:(UIView *)view { if (!view) { return; } if (_customView) { [_customView removeFromSuperview]; _customView = nil; } _customView = view; _customView.translatesAutoresizingMaskIntoConstraints = NO; [self.contentView addSubview:_customView]; } #pragma mark - Action Methods - (void)didTapButton:(id)sender { SEL selector = NSSelectorFromString(@"dzn_didTapDataButton:"); if ([self.superview respondsToSelector:selector]) { [self.superview performSelector:selector withObject:sender afterDelay:0.0f]; } } - (void)removeAllConstraints { [self removeConstraints:self.constraints]; [_contentView removeConstraints:_contentView.constraints]; } - (void)prepareForReuse { [self.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; _titleLabel = nil; _detailLabel = nil; _imageView = nil; _button = nil; _customView = nil; [self removeAllConstraints]; } #pragma mark - Auto-Layout Configuration - (void)setupConstraints { // First, configure the content view constaints // The content view must alway be centered to its superview NSLayoutConstraint *centerXConstraint = [self equallyRelatedConstraintWithView:self.contentView attribute:NSLayoutAttributeCenterX]; NSLayoutConstraint *centerYConstraint = [self equallyRelatedConstraintWithView:self.contentView attribute:NSLayoutAttributeCenterY]; [self addConstraint:centerXConstraint]; [self addConstraint:centerYConstraint]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:nil views:@{@"contentView": self.contentView}]]; // When a custom offset is available, we adjust the vertical constraints' constants if (self.verticalOffset != 0 && self.constraints.count > 0) { centerYConstraint.constant = self.verticalOffset; } // If applicable, set the custom view's constraints if (_customView) { [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[customView]|" options:0 metrics:nil views:@{@"customView":_customView}]]; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[customView]|" options:0 metrics:nil views:@{@"customView":_customView}]]; } else { CGFloat width = CGRectGetWidth(self.frame) ? : CGRectGetWidth([UIScreen mainScreen].bounds); CGFloat padding = roundf(width/16.0); CGFloat verticalSpace = self.verticalSpace ? : 11.0; // Default is 11 pts NSMutableArray *subviewStrings = [NSMutableArray array]; NSMutableDictionary *views = [NSMutableDictionary dictionary]; NSDictionary *metrics = @{@"padding": @(padding)}; // Assign the image view's horizontal constraints if (_imageView.superview) { [subviewStrings addObject:@"imageView"]; views[[subviewStrings lastObject]] = _imageView; [self.contentView addConstraint:[self.contentView equallyRelatedConstraintWithView:_imageView attribute:NSLayoutAttributeCenterX]]; } // Assign the title label's horizontal constraints if ([self canShowTitle]) { [subviewStrings addObject:@"titleLabel"]; views[[subviewStrings lastObject]] = _titleLabel; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(padding@750)-[titleLabel(>=0)]-(padding@750)-|" options:0 metrics:metrics views:views]]; } // or removes from its superview else { [_titleLabel removeFromSuperview]; _titleLabel = nil; } // Assign the detail label's horizontal constraints if ([self canShowDetail]) { [subviewStrings addObject:@"detailLabel"]; views[[subviewStrings lastObject]] = _detailLabel; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(padding@750)-[detailLabel(>=0)]-(padding@750)-|" options:0 metrics:metrics views:views]]; } // or removes from its superview else { [_detailLabel removeFromSuperview]; _detailLabel = nil; } // Assign the button's horizontal constraints if ([self canShowButton]) { [subviewStrings addObject:@"button"]; views[[subviewStrings lastObject]] = _button; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(padding@750)-[button(>=0)]-(padding@750)-|" options:0 metrics:metrics views:views]]; } // or removes from its superview else { [_button removeFromSuperview]; _button = nil; } NSMutableString *verticalFormat = [NSMutableString new]; // Build a dynamic string format for the vertical constraints, adding a margin between each element. Default is 11 pts. for (int i = 0; i < subviewStrings.count; i++) { NSString *string = subviewStrings[i]; [verticalFormat appendFormat:@"[%@]", string]; if (i < subviewStrings.count-1) { [verticalFormat appendFormat:@"-(%.f@750)-", verticalSpace]; } } // Assign the vertical constraints to the content view if (verticalFormat.length > 0) { [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|%@|", verticalFormat] options:0 metrics:metrics views:views]]; } } } - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; // Return any UIControl instance such as buttons, segmented controls, switches, etc. if ([hitView isKindOfClass:[UIControl class]]) { return hitView; } // Return either the contentView or customView if ([hitView isEqual:_contentView] || [hitView isEqual:_customView]) { return hitView; } return nil; } @end #pragma mark - UIView+DZNConstraintBasedLayoutExtensions @implementation UIView (DZNConstraintBasedLayoutExtensions) - (NSLayoutConstraint *)equallyRelatedConstraintWithView:(UIView *)view attribute:(NSLayoutAttribute)attribute { return [NSLayoutConstraint constraintWithItem:view attribute:attribute relatedBy:NSLayoutRelationEqual toItem:self attribute:attribute multiplier:1.0 constant:0.0]; } @end #pragma mark - DZNWeakObjectContainer @implementation DZNWeakObjectContainer - (instancetype)initWithWeakObject:(id)object { self = [super init]; if (self) { _weakObject = object; } return self; } @end