From fefa98441490737a3a7e1aa3beeaab94457f2da8 Mon Sep 17 00:00:00 2001 From: Michele Gruppioni Date: Sat, 17 Feb 2018 16:14:53 +0100 Subject: [PATCH] Add tvOS Target --- Gifu.podspec | 3 + Gifu.xcodeproj/project.pbxproj | 310 +++++++++++++++++++++++++++- Gifu_tvOS-Info.plist | 26 +++ Gifu_tvOS/Gifu_tvOS.h | 19 ++ Gifu_tvOS/Info.plist | 24 +++ Gifu_tvOSTests/Gifu_tvOSTests.swift | 107 ++++++++++ Gifu_tvOSTests/Info.plist | 22 ++ Source/Classes/AnimatedFrame.swift | 1 + Source/Classes/Animator.swift | 2 + Source/Classes/FrameStore.swift | 1 + Source/Classes/GIFAnimatable.swift | 1 + Source/Classes/GIFImageView.swift | 1 + Source/Extensions/CGSize.swift | 2 + Source/Extensions/UIImage.swift | 1 + Source/Extensions/UIImageView.swift | 1 + Supporting Files/Info.plist | 2 +- 16 files changed, 521 insertions(+), 2 deletions(-) create mode 100644 Gifu_tvOS-Info.plist create mode 100644 Gifu_tvOS/Gifu_tvOS.h create mode 100644 Gifu_tvOS/Info.plist create mode 100644 Gifu_tvOSTests/Gifu_tvOSTests.swift create mode 100644 Gifu_tvOSTests/Info.plist diff --git a/Gifu.podspec b/Gifu.podspec index 5572c5e..8f20e7b 100644 --- a/Gifu.podspec +++ b/Gifu.podspec @@ -8,7 +8,10 @@ Pod::Spec.new do |s| s.author = { "Reda Lemeden" => "git@kaishin.haz.email" } s.source = { :git => "https://github.com/kaishin/Gifu.git", :tag => "v#{s.version}", :submodules => true } s.platform = :ios, "9.0" + s.platform = :tvos, "9.0" s.ios.source_files = "Source/**/*.{h,swift}" + s.tvos.source_files = "Source/**/*.{h,swift}" s.requires_arc = true s.ios.deployment_target = "9.0" + s.tvos.deployment_target = "9.0" end diff --git a/Gifu.xcodeproj/project.pbxproj b/Gifu.xcodeproj/project.pbxproj index 2a03f41..71526bc 100644 --- a/Gifu.xcodeproj/project.pbxproj +++ b/Gifu.xcodeproj/project.pbxproj @@ -20,6 +20,21 @@ 00B8C7961A3650EE00C188E7 /* Gifu.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B8C7951A3650EE00C188E7 /* Gifu.h */; settings = {ATTRIBUTES = (Public, ); }; }; 00BF42CC1D99A1DC00C6F28D /* GIFAnimatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */; }; 00DD26EE1DA9643800A0F683 /* UIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00DD26ED1DA9643800A0F683 /* UIImageView.swift */; }; + 71E8B2E620387D830037BA62 /* Gifu_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71E8B2DD20387D830037BA62 /* Gifu_tvOS.framework */; }; + 71E8B2ED20387D830037BA62 /* Gifu_tvOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 71E8B2DF20387D830037BA62 /* Gifu_tvOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 71E8B2F420387D8E0037BA62 /* AnimatedFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */; }; + 71E8B2F520387D8E0037BA62 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00978B6B1D9C6D2A00A6575F /* Animator.swift */; }; + 71E8B2F620387D8E0037BA62 /* FrameStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */; }; + 71E8B2F720387D8E0037BA62 /* GIFAnimatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */; }; + 71E8B2F820387D8E0037BA62 /* GIFImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */; }; + 71E8B2F920387D910037BA62 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007E08431BD95E6200883D0C /* Array.swift */; }; + 71E8B2FA20387D910037BA62 /* CGSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009BD1431BBC93C800FC982B /* CGSize.swift */; }; + 71E8B2FB20387D910037BA62 /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49C7E1A3A4DE000B395DF /* UIImage.swift */; }; + 71E8B2FC20387D910037BA62 /* UIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00DD26ED1DA9643800A0F683 /* UIImageView.swift */; }; + 71E8B2FD20387D950037BA62 /* ImageSourceHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */; }; + 71E8B30220387E1E0037BA62 /* nailed.gif in Resources */ = {isa = PBXBuildFile; fileRef = 71E8B30020387E1E0037BA62 /* nailed.gif */; }; + 71E8B30320387E1E0037BA62 /* mugen.gif in Resources */ = {isa = PBXBuildFile; fileRef = 71E8B30120387E1E0037BA62 /* mugen.gif */; }; + 71E8B30420387ED70037BA62 /* Gifu_tvOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71E8B2CE20387CE60037BA62 /* Gifu_tvOSTests.swift */; }; EAF49C7F1A3A4DE000B395DF /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49C7E1A3A4DE000B395DF /* UIImage.swift */; }; EAF49CB11A3B6EEB00B395DF /* AnimatedFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */; }; /* End PBXBuildFile section */ @@ -32,6 +47,13 @@ remoteGlobalIDString = 00B8C73D1A364DA400C188E7; remoteInfo = Gifu; }; + 71E8B2E720387D830037BA62 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 00B8C7351A364DA400C188E7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71E8B2DC20387D830037BA62; + remoteInfo = Gifu_tvOS; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -51,6 +73,15 @@ 00B8C7951A3650EE00C188E7 /* Gifu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gifu.h; sourceTree = ""; }; 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GIFAnimatable.swift; sourceTree = ""; }; 00DD26ED1DA9643800A0F683 /* UIImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageView.swift; sourceTree = ""; }; + 71E8B2B82038784C0037BA62 /* Gifu_tvOS-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Gifu_tvOS-Info.plist"; path = "/Users/gruppionim/Documents/Developer/Github/Gifu/Gifu_tvOS-Info.plist"; sourceTree = ""; }; + 71E8B2CE20387CE60037BA62 /* Gifu_tvOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Gifu_tvOSTests.swift; sourceTree = ""; }; + 71E8B2D020387CE60037BA62 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 71E8B2DD20387D830037BA62 /* Gifu_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Gifu_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 71E8B2DF20387D830037BA62 /* Gifu_tvOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Gifu_tvOS.h; sourceTree = ""; }; + 71E8B2E020387D830037BA62 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 71E8B2E520387D830037BA62 /* Gifu_tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Gifu_tvOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 71E8B30020387E1E0037BA62 /* nailed.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = nailed.gif; sourceTree = ""; }; + 71E8B30120387E1E0037BA62 /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = mugen.gif; sourceTree = ""; }; EAF49C7E1A3A4DE000B395DF /* UIImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImage.swift; sourceTree = ""; }; EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatedFrame.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -71,6 +102,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 71E8B2D920387D830037BA62 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 71E8B2E220387D830037BA62 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 71E8B2E620387D830037BA62 /* Gifu_tvOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -128,9 +174,12 @@ isa = PBXGroup; children = ( 009BD1371BBC7F6500FC982B /* GifuTests */, + 71E8B2CD20387CE60037BA62 /* Gifu_tvOSTests */, + 71E8B2DE20387D830037BA62 /* Gifu_tvOS */, 00B8C73F1A364DA400C188E7 /* Products */, 00B8C75A1A364DBE00C188E7 /* Source */, 00B8C7411A364DA400C188E7 /* Supporting Files */, + 71E8B2B82038784C0037BA62 /* Gifu_tvOS-Info.plist */, ); sourceTree = ""; }; @@ -139,6 +188,8 @@ children = ( 00B8C73E1A364DA400C188E7 /* Gifu.framework */, 009BD1361BBC7F6500FC982B /* GifuTests.xctest */, + 71E8B2DD20387D830037BA62 /* Gifu_tvOS.framework */, + 71E8B2E520387D830037BA62 /* Gifu_tvOSTests.xctest */, ); name = Products; sourceTree = ""; @@ -162,6 +213,35 @@ path = Source; sourceTree = ""; }; + 71E8B2CD20387CE60037BA62 /* Gifu_tvOSTests */ = { + isa = PBXGroup; + children = ( + 71E8B2FF20387E1E0037BA62 /* Images */, + 71E8B2CE20387CE60037BA62 /* Gifu_tvOSTests.swift */, + 71E8B2D020387CE60037BA62 /* Info.plist */, + ); + path = Gifu_tvOSTests; + sourceTree = ""; + }; + 71E8B2DE20387D830037BA62 /* Gifu_tvOS */ = { + isa = PBXGroup; + children = ( + 71E8B2DF20387D830037BA62 /* Gifu_tvOS.h */, + 71E8B2E020387D830037BA62 /* Info.plist */, + ); + path = Gifu_tvOS; + sourceTree = ""; + }; + 71E8B2FF20387E1E0037BA62 /* Images */ = { + isa = PBXGroup; + children = ( + 71E8B30020387E1E0037BA62 /* nailed.gif */, + 71E8B30120387E1E0037BA62 /* mugen.gif */, + ); + name = Images; + path = GifuTests/Images; + sourceTree = SOURCE_ROOT; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -173,6 +253,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 71E8B2DA20387D830037BA62 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 71E8B2ED20387D830037BA62 /* Gifu_tvOS.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -213,13 +301,49 @@ productReference = 00B8C73E1A364DA400C188E7 /* Gifu.framework */; productType = "com.apple.product-type.framework"; }; + 71E8B2DC20387D830037BA62 /* Gifu_tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 71E8B2EE20387D830037BA62 /* Build configuration list for PBXNativeTarget "Gifu_tvOS" */; + buildPhases = ( + 71E8B2D820387D830037BA62 /* Sources */, + 71E8B2D920387D830037BA62 /* Frameworks */, + 71E8B2DA20387D830037BA62 /* Headers */, + 71E8B2DB20387D830037BA62 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Gifu_tvOS; + productName = Gifu_tvOS; + productReference = 71E8B2DD20387D830037BA62 /* Gifu_tvOS.framework */; + productType = "com.apple.product-type.framework"; + }; + 71E8B2E420387D830037BA62 /* Gifu_tvOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 71E8B2F120387D830037BA62 /* Build configuration list for PBXNativeTarget "Gifu_tvOSTests" */; + buildPhases = ( + 71E8B2E120387D830037BA62 /* Sources */, + 71E8B2E220387D830037BA62 /* Frameworks */, + 71E8B2E320387D830037BA62 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 71E8B2E820387D830037BA62 /* PBXTargetDependency */, + ); + name = Gifu_tvOSTests; + productName = Gifu_tvOSTests; + productReference = 71E8B2E520387D830037BA62 /* Gifu_tvOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 00B8C7351A364DA400C188E7 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0700; + LastSwiftUpdateCheck = 0920; LastUpgradeCheck = 0900; ORGANIZATIONNAME = "Kaishin & Co"; TargetAttributes = { @@ -232,6 +356,14 @@ LastSwiftMigration = 0900; ProvisioningStyle = Manual; }; + 71E8B2DC20387D830037BA62 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; + 71E8B2E420387D830037BA62 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = 00B8C7381A364DA400C188E7 /* Build configuration list for PBXProject "Gifu" */; @@ -248,6 +380,8 @@ targets = ( 00B8C73D1A364DA400C188E7 /* Gifu */, 009BD1351BBC7F6500FC982B /* GifuTests */, + 71E8B2DC20387D830037BA62 /* Gifu_tvOS */, + 71E8B2E420387D830037BA62 /* Gifu_tvOSTests */, ); }; /* End PBXProject section */ @@ -269,6 +403,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 71E8B2DB20387D830037BA62 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 71E8B2E320387D830037BA62 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 71E8B30220387E1E0037BA62 /* nailed.gif in Resources */, + 71E8B30320387E1E0037BA62 /* mugen.gif in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -314,6 +464,31 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 71E8B2D820387D830037BA62 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 71E8B2FD20387D950037BA62 /* ImageSourceHelpers.swift in Sources */, + 71E8B2F820387D8E0037BA62 /* GIFImageView.swift in Sources */, + 71E8B2FC20387D910037BA62 /* UIImageView.swift in Sources */, + 71E8B2FB20387D910037BA62 /* UIImage.swift in Sources */, + 71E8B2F520387D8E0037BA62 /* Animator.swift in Sources */, + 71E8B2F620387D8E0037BA62 /* FrameStore.swift in Sources */, + 71E8B2FA20387D910037BA62 /* CGSize.swift in Sources */, + 71E8B2F920387D910037BA62 /* Array.swift in Sources */, + 71E8B2F720387D8E0037BA62 /* GIFAnimatable.swift in Sources */, + 71E8B2F420387D8E0037BA62 /* AnimatedFrame.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 71E8B2E120387D830037BA62 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 71E8B30420387ED70037BA62 /* Gifu_tvOSTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -322,6 +497,11 @@ target = 00B8C73D1A364DA400C188E7 /* Gifu */; targetProxy = 009BD13C1BBC7F6500FC982B /* PBXContainerItemProxy */; }; + 71E8B2E820387D830037BA62 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 71E8B2DC20387D830037BA62 /* Gifu_tvOS */; + targetProxy = 71E8B2E720387D830037BA62 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -509,6 +689,116 @@ }; name = Release; }; + 71E8B2EF20387D830037BA62 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = Gifu_tvOS/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "co.kaishin.gifu.Gifu-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 11.2; + }; + name = Debug; + }; + 71E8B2F020387D830037BA62 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = Gifu_tvOS/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "co.kaishin.gifu.Gifu-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 11.2; + }; + name = Release; + }; + 71E8B2F220387D830037BA62 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = Gifu_tvOSTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "co.kaishin.gifu.Gifu-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 11.2; + }; + name = Debug; + }; + 71E8B2F320387D830037BA62 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = Gifu_tvOSTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "co.kaishin.gifu.Gifu-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 11.2; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -539,6 +829,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 71E8B2EE20387D830037BA62 /* Build configuration list for PBXNativeTarget "Gifu_tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 71E8B2EF20387D830037BA62 /* Debug */, + 71E8B2F020387D830037BA62 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 71E8B2F120387D830037BA62 /* Build configuration list for PBXNativeTarget "Gifu_tvOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 71E8B2F220387D830037BA62 /* Debug */, + 71E8B2F320387D830037BA62 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 00B8C7351A364DA400C188E7 /* Project object */; diff --git a/Gifu_tvOS-Info.plist b/Gifu_tvOS-Info.plist new file mode 100644 index 0000000..c44a34b --- /dev/null +++ b/Gifu_tvOS-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.0.0 + CFBundleSignature + ???? + CFBundleVersion + 142 + NSPrincipalClass + + + diff --git a/Gifu_tvOS/Gifu_tvOS.h b/Gifu_tvOS/Gifu_tvOS.h new file mode 100644 index 0000000..b4a21a5 --- /dev/null +++ b/Gifu_tvOS/Gifu_tvOS.h @@ -0,0 +1,19 @@ +// +// Gifu_tvOS.h +// Gifu_tvOS +// +// Created by Gruppioni Michele on 17/02/18. +// Copyright © 2018 Kaishin & Co. All rights reserved. +// + +#import + +//! Project version number for Gifu_tvOS. +FOUNDATION_EXPORT double Gifu_tvOSVersionNumber; + +//! Project version string for Gifu_tvOS. +FOUNDATION_EXPORT const unsigned char Gifu_tvOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Gifu_tvOS/Info.plist b/Gifu_tvOS/Info.plist new file mode 100644 index 0000000..1007fd9 --- /dev/null +++ b/Gifu_tvOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Gifu_tvOSTests/Gifu_tvOSTests.swift b/Gifu_tvOSTests/Gifu_tvOSTests.swift new file mode 100644 index 0000000..eedd0dc --- /dev/null +++ b/Gifu_tvOSTests/Gifu_tvOSTests.swift @@ -0,0 +1,107 @@ +// +// Gifu_tvOSTests.swift +// Gifu_tvOSTests +// +// Created by Gruppioni Michele on 17/02/18. +// Copyright © 2018 Kaishin & Co. All rights reserved. +// + +import XCTest +import ImageIO +@testable import Gifu_tvOS + +private let imageData = testImageDataNamed("mugen.gif") +private let staticImage = UIImage(data: imageData)! +private let preloadFrameCount = 20 + +class DummyAnimatable: GIFAnimatable { + init() {} + var animator: Animator? = nil + var image: UIImage? = nil + var layer = CALayer() + var frame: CGRect = .zero + var contentMode: UIViewContentMode = .scaleToFill + func animatorHasNewFrame() {} +} + +class GifuTests: XCTestCase { + var animator: Animator! + var originalFrameCount: Int! + let delegate = DummyAnimatable() + + override func setUp() { + super.setUp() + animator = Animator(withDelegate: delegate) + animator.prepareForAnimation(withGIFData: imageData, size: staticImage.size, contentMode: .scaleToFill) + originalFrameCount = 44 + } + + func testIsAnimatable() { + XCTAssertNotNil(animator.frameStore) + guard let store = animator.frameStore else { return } + XCTAssertTrue(store.isAnimatable) + } + + func testCurrentFrame() { + XCTAssertNotNil(animator.frameStore) + guard let store = animator.frameStore else { return } + XCTAssertEqual(store.currentFrameIndex, 0) + } + + func testFramePreload() { + XCTAssertNotNil(animator.frameStore) + guard let store = animator.frameStore else { return } + + let expectation = self.expectation(description: "frameDuration") + + store.prepareFrames { + let animatedFrameCount = store.animatedFrames.count + XCTAssertEqual(animatedFrameCount, self.originalFrameCount) + XCTAssertNotNil(store.frame(at: preloadFrameCount - 1)) + XCTAssertNil(store.frame(at: preloadFrameCount + 1)?.images) + XCTAssertEqual(store.currentFrameIndex, 0) + + store.shouldChangeFrame(with: 1.0) { hasNewFrame in + XCTAssertTrue(hasNewFrame) + XCTAssertEqual(store.currentFrameIndex, 1) + expectation.fulfill() + } + } + + waitForExpectations(timeout: 1.0) { error in + if let error = error { + print("Error: \(error.localizedDescription)") + } + } + } + + func testFrameInfo() { + XCTAssertNotNil(animator.frameStore) + guard let store = animator.frameStore else { return } + + let expectation = self.expectation(description: "testFrameInfoIsAccurate") + + store.prepareFrames { + let frameDuration = store.frame(at: 5)?.duration ?? 0 + XCTAssertTrue((frameDuration - 0.05) < 0.00001) + + let imageSize = store.frame(at: 5)?.size ?? CGSize.zero + XCTAssertEqual(imageSize, staticImage.size) + + expectation.fulfill() + } + + waitForExpectations(timeout: 1.0) { error in + if let error = error { + print("Error: \(error.localizedDescription)") + } + } + } +} + +private func testImageDataNamed(_ name: String) -> Data { + let testBundle = Bundle(for: GifuTests.self) + let imagePath = testBundle.bundleURL.appendingPathComponent(name) + return (try! Data(contentsOf: imagePath)) +} + diff --git a/Gifu_tvOSTests/Info.plist b/Gifu_tvOSTests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/Gifu_tvOSTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Source/Classes/AnimatedFrame.swift b/Source/Classes/AnimatedFrame.swift index c1c31e3..84cca80 100644 --- a/Source/Classes/AnimatedFrame.swift +++ b/Source/Classes/AnimatedFrame.swift @@ -1,3 +1,4 @@ +import UIKit /// Represents a single frame in a GIF. struct AnimatedFrame { diff --git a/Source/Classes/Animator.swift b/Source/Classes/Animator.swift index 54f6d67..e59e006 100644 --- a/Source/Classes/Animator.swift +++ b/Source/Classes/Animator.swift @@ -1,3 +1,5 @@ +import UIKit + /// Responsible for parsing GIF data and decoding the individual frames. public class Animator { diff --git a/Source/Classes/FrameStore.swift b/Source/Classes/FrameStore.swift index 6dff253..3941602 100644 --- a/Source/Classes/FrameStore.swift +++ b/Source/Classes/FrameStore.swift @@ -1,4 +1,5 @@ import ImageIO +import UIKit /// Responsible for storing and updating the frames of a single GIF. class FrameStore { diff --git a/Source/Classes/GIFAnimatable.swift b/Source/Classes/GIFAnimatable.swift index e5baced..507ef80 100644 --- a/Source/Classes/GIFAnimatable.swift +++ b/Source/Classes/GIFAnimatable.swift @@ -1,4 +1,5 @@ import Foundation +import UIKit /// The protocol that view classes need to conform to to enable animated GIF support. public protocol GIFAnimatable: class { diff --git a/Source/Classes/GIFImageView.swift b/Source/Classes/GIFImageView.swift index 5ca00a3..650d7f3 100644 --- a/Source/Classes/GIFImageView.swift +++ b/Source/Classes/GIFImageView.swift @@ -1,3 +1,4 @@ +import UIKit /// Example class that conforms to `GIFAnimatable`. Uses default values for the animator frame buffer count and resize behavior. You can either use it directly in your code or use it as a blueprint for your own subclass. public class GIFImageView: UIImageView, GIFAnimatable { diff --git a/Source/Extensions/CGSize.swift b/Source/Extensions/CGSize.swift index b936b71..5b0a55d 100644 --- a/Source/Extensions/CGSize.swift +++ b/Source/Extensions/CGSize.swift @@ -1,3 +1,5 @@ +import Foundation +import UIKit extension CGSize { /// Calculates the aspect ratio of the size. /// diff --git a/Source/Extensions/UIImage.swift b/Source/Extensions/UIImage.swift index 8a0d0d5..2fe8d3d 100644 --- a/Source/Extensions/UIImage.swift +++ b/Source/Extensions/UIImage.swift @@ -1,3 +1,4 @@ +import UIKit /// A `UIImage` extension that makes it easier to resize the image and inspect its size. extension UIImage { /// Resizes an image instance. diff --git a/Source/Extensions/UIImageView.swift b/Source/Extensions/UIImageView.swift index 1f5dd87..b2a8be7 100644 --- a/Source/Extensions/UIImageView.swift +++ b/Source/Extensions/UIImageView.swift @@ -1,2 +1,3 @@ /// Makes `UIImageView` conform to `ImageContainer` +import UIKit extension UIImageView: ImageContainer {} diff --git a/Supporting Files/Info.plist b/Supporting Files/Info.plist index a28f657..c44a34b 100644 --- a/Supporting Files/Info.plist +++ b/Supporting Files/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 141 + 142 NSPrincipalClass