├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SwiftGif.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── SwiftGif.xccheckout └── xcshareddata │ └── xcschemes │ ├── SwiftGif.xcscheme │ ├── SwiftGifDemo.xcscheme │ └── SwiftGifTests.xcscheme ├── SwiftGif ├── Info.plist └── SwiftGif.h ├── SwiftGifCommon └── UIImage+Gif.swift ├── SwiftGifDemo ├── AppDelegate.swift ├── DemoVC.swift ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Info.plist ├── Main.storyboard ├── adventure-time.gif ├── jeremy.gif └── non_standard_gif.gif ├── SwiftGifOrigin.podspec ├── SwiftGifTests ├── GifTests.swift ├── Info.plist └── test.gif └── demo.gif /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | *.xcuserdatad 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode9.2 3 | 4 | before_install: 5 | - gem install xcpretty 6 | before_script: 7 | - set -o pipefail 8 | script: 9 | - xcodebuild 10 | -project SwiftGif.xcodeproj 11 | -scheme SwiftGif 12 | -sdk iphonesimulator 13 | -destination "platform=iOS Simulator,name=iPhone 8" build test 14 | CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | You want to contribute? Thank you :smila: 3 | 4 | 1. Clone the repositoy: `git clone git@github.com:bahlo/SwiftGif.git` 5 | 2. Create a new branch with the schema `my-feature`. 6 | 3. Implement your feature 7 | 4. Open a pull request 8 | 9 | :heart: 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Arne Bahlo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### :warning: UNMAINTAINED :warning: 2 | 3 | This library is no longer maintained. I recommend using [Gifu](https://github.com/kaishin/gifu) instead. 4 | 5 | --- 6 | 7 | # SwiftGif [![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg?style=flat)](https://developer.apple.com/swift/) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![CocoaPods](https://img.shields.io/cocoapods/v/SwiftGifOrigin.svg)](http://cocoadocs.org/docsets/SwiftGifOrigin) [![License MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat)](https://github.com/Carthage/Carthage) [![Build Status](https://travis-ci.org/bahlo/SwiftGif.svg?branch=master)](https://travis-ci.org/bahlo/SwiftGif) 8 | 9 | A small `UIImage` extension with gif support. 10 | 11 | ![Demo gif](demo.gif) 12 | 13 | ## Usage 14 | 15 | ```swift 16 | import SwiftGifOrigin 17 | 18 | // An animated UIImage 19 | let jeremyGif = UIImage.gif(name: "jeremy") 20 | 21 | // A UIImageView with async loading 22 | let imageView = UIImageView() 23 | imageView.loadGif(name: "jeremy") 24 | 25 | // A UIImageView with async loading from asset catalog(from iOS9) 26 | let imageView = UIImageView() 27 | imageView.loadGif(asset: "jeremy") 28 | ``` 29 | 30 | ## Installation 31 | ### CocoaPods 32 | Install [CocoaPods](http://cocoapods.org) with the following command: 33 | 34 | ```bash 35 | gem install cocoapods 36 | ``` 37 | 38 | Integrate SwiftGif into your Xcode project by creating a `Podfile`: 39 | 40 | ```ruby 41 | platform :ios, '9.0' 42 | use_frameworks! 43 | 44 | target '' do 45 | pod 'SwiftGifOrigin', '~> 1.7.0' 46 | end 47 | ``` 48 | 49 | Run `pod install` to build your dependencies. 50 | 51 | ### Carthage 52 | 53 | Install [Carthage](https://github.com/Carthage/Carthage) with 54 | [Homebrew](http://brew.sh/) using the following command: 55 | 56 | ```bash 57 | brew update 58 | brew install carthage 59 | ``` 60 | 61 | Add the following line to your `Cartfile` to add SwiftGif: 62 | 63 | ```ogdl 64 | github "bahlo/SwiftGif" ~> 1.7.0 65 | ``` 66 | 67 | Run `carthage update` to build the framework and drag the built 68 | `SwiftGif.framework` into your Xcode project. 69 | 70 | 71 | ## How does it work? 72 | Easy, it does the following: 73 | 74 | 1. Find out the duration of every frame 75 | 2. Find the greatest common divisor 76 | 3. Add frames accordingly to the greatest common divisor to an array 77 | 4. Create an animated UIImage with the frames 78 | 79 | ## Testing 80 | 81 | ``` 82 | $ xcodebuild \ 83 | -project SwiftGif.xcodeproj \ 84 | -scheme SwiftGif \ 85 | -sdk iphonesimulator \ 86 | -destination "platform=iOS Simulator,name=iPhone 8" \ 87 | build test \ 88 | CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" 89 | ``` 90 | 91 | # Inspiration 92 | This project is heavily inspired by [uiimage-from-animated-gif](https://github.com/mayoff/uiimage-from-animated-gif). 93 | Kudos to [@mayoff](https://github.com/mayoff). :thumbsup: 94 | 95 | ## License 96 | This repository is licensed under the MIT license, more under 97 | [LICENSE](LICENSE). 98 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 12166BDC1C73A31800FC3CB5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12166BDB1C73A31800FC3CB5 /* Main.storyboard */; }; 11 | 12166BDE1C73A52A00FC3CB5 /* DemoVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12166BDD1C73A52A00FC3CB5 /* DemoVC.swift */; }; 12 | 1419B388194EFBFD005DF6D0 /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1419B37D194EFBFD005DF6D0 /* UIImage+Gif.swift */; }; 13 | 1419B389194EFBFD005DF6D0 /* adventure-time.gif in Resources */ = {isa = PBXBuildFile; fileRef = 1419B37F194EFBFD005DF6D0 /* adventure-time.gif */; }; 14 | 1419B38A194EFBFD005DF6D0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1419B380194EFBFD005DF6D0 /* AppDelegate.swift */; }; 15 | 1419B38B194EFBFD005DF6D0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1419B381194EFBFD005DF6D0 /* Images.xcassets */; }; 16 | 1419B38D194EFBFD005DF6D0 /* jeremy.gif in Resources */ = {isa = PBXBuildFile; fileRef = 1419B383194EFBFD005DF6D0 /* jeremy.gif */; }; 17 | 1419B38F194EFC11005DF6D0 /* GifTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1419B378194EFBE7005DF6D0 /* GifTests.swift */; }; 18 | 1419B390194EFC15005DF6D0 /* test.gif in Resources */ = {isa = PBXBuildFile; fileRef = 1419B379194EFBE7005DF6D0 /* test.gif */; }; 19 | 1482D73B194EFCF10038192B /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1419B37D194EFBFD005DF6D0 /* UIImage+Gif.swift */; }; 20 | 14FF87E31D6B7BAA00FB208A /* SwiftGif.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FF87D31D6B7BAA00FB208A /* SwiftGif.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 14FF87E61D6B7BAA00FB208A /* SwiftGif.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14FF87D11D6B7BAA00FB208A /* SwiftGif.framework */; }; 22 | 14FF87E71D6B7BAA00FB208A /* SwiftGif.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 14FF87D11D6B7BAA00FB208A /* SwiftGif.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 23 | 9266326F1EC292AD007A31C2 /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1419B37D194EFBFD005DF6D0 /* UIImage+Gif.swift */; }; 24 | FB57A0641CA41C2400065109 /* non_standard_gif.gif in Resources */ = {isa = PBXBuildFile; fileRef = FB57A0631CA41C2400065109 /* non_standard_gif.gif */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | 14A76446194EFBB800A74B1F /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 14A76430194EFBB800A74B1F /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 14A76437194EFBB800A74B1F; 33 | remoteInfo = SwiftGif; 34 | }; 35 | 14FF87E41D6B7BAA00FB208A /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = 14A76430194EFBB800A74B1F /* Project object */; 38 | proxyType = 1; 39 | remoteGlobalIDString = 14FF87D01D6B7BAA00FB208A; 40 | remoteInfo = SwiftGif; 41 | }; 42 | /* End PBXContainerItemProxy section */ 43 | 44 | /* Begin PBXCopyFilesBuildPhase section */ 45 | 14FF87EB1D6B7BAA00FB208A /* Embed Frameworks */ = { 46 | isa = PBXCopyFilesBuildPhase; 47 | buildActionMask = 2147483647; 48 | dstPath = ""; 49 | dstSubfolderSpec = 10; 50 | files = ( 51 | 14FF87E71D6B7BAA00FB208A /* SwiftGif.framework in Embed Frameworks */, 52 | ); 53 | name = "Embed Frameworks"; 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXCopyFilesBuildPhase section */ 57 | 58 | /* Begin PBXFileReference section */ 59 | 12166BDB1C73A31800FC3CB5 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 60 | 12166BDD1C73A52A00FC3CB5 /* DemoVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoVC.swift; sourceTree = ""; }; 61 | 1419B378194EFBE7005DF6D0 /* GifTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GifTests.swift; sourceTree = ""; }; 62 | 1419B379194EFBE7005DF6D0 /* test.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = test.gif; sourceTree = ""; }; 63 | 1419B37D194EFBFD005DF6D0 /* UIImage+Gif.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIImage+Gif.swift"; path = "SwiftGifCommon/UIImage+Gif.swift"; sourceTree = SOURCE_ROOT; }; 64 | 1419B37F194EFBFD005DF6D0 /* adventure-time.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "adventure-time.gif"; sourceTree = ""; }; 65 | 1419B380194EFBFD005DF6D0 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 66 | 1419B381194EFBFD005DF6D0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 67 | 1419B382194EFBFD005DF6D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | 1419B383194EFBFD005DF6D0 /* jeremy.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = jeremy.gif; sourceTree = ""; }; 69 | 1482D739194EFCE00038192B /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | 14A76438194EFBB800A74B1F /* SwiftGifDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftGifDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 71 | 14A76445194EFBB800A74B1F /* SwiftGifTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftGifTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | 14FF87D11D6B7BAA00FB208A /* SwiftGif.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftGif.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | 14FF87D31D6B7BAA00FB208A /* SwiftGif.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftGif.h; sourceTree = ""; }; 74 | 14FF87D41D6B7BAA00FB208A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | FB57A0631CA41C2400065109 /* non_standard_gif.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = non_standard_gif.gif; sourceTree = ""; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | 14A76435194EFBB800A74B1F /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 14FF87E61D6B7BAA00FB208A /* SwiftGif.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | 14A76442194EFBB800A74B1F /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | 14FF87CD1D6B7BAA00FB208A /* Frameworks */ = { 95 | isa = PBXFrameworksBuildPhase; 96 | buildActionMask = 2147483647; 97 | files = ( 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | /* End PBXFrameworksBuildPhase section */ 102 | 103 | /* Begin PBXGroup section */ 104 | 1419B377194EFBE7005DF6D0 /* SwiftGifTests */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 1419B378194EFBE7005DF6D0 /* GifTests.swift */, 108 | 1419B379194EFBE7005DF6D0 /* test.gif */, 109 | 1482D739194EFCE00038192B /* Info.plist */, 110 | ); 111 | path = SwiftGifTests; 112 | sourceTree = ""; 113 | }; 114 | 1419B37E194EFBFD005DF6D0 /* SwiftGifDemo */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 1419B380194EFBFD005DF6D0 /* AppDelegate.swift */, 118 | 12166BDD1C73A52A00FC3CB5 /* DemoVC.swift */, 119 | 1419B381194EFBFD005DF6D0 /* Images.xcassets */, 120 | 1419B37F194EFBFD005DF6D0 /* adventure-time.gif */, 121 | 1419B383194EFBFD005DF6D0 /* jeremy.gif */, 122 | FB57A0631CA41C2400065109 /* non_standard_gif.gif */, 123 | 1419B382194EFBFD005DF6D0 /* Info.plist */, 124 | 12166BDB1C73A31800FC3CB5 /* Main.storyboard */, 125 | ); 126 | path = SwiftGifDemo; 127 | sourceTree = ""; 128 | }; 129 | 14A7642F194EFBB800A74B1F = { 130 | isa = PBXGroup; 131 | children = ( 132 | 1419B37E194EFBFD005DF6D0 /* SwiftGifDemo */, 133 | 14FF87D21D6B7BAA00FB208A /* SwiftGif */, 134 | 1419B377194EFBE7005DF6D0 /* SwiftGifTests */, 135 | 14A76439194EFBB800A74B1F /* Products */, 136 | ); 137 | sourceTree = ""; 138 | }; 139 | 14A76439194EFBB800A74B1F /* Products */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 14A76438194EFBB800A74B1F /* SwiftGifDemo.app */, 143 | 14A76445194EFBB800A74B1F /* SwiftGifTests.xctest */, 144 | 14FF87D11D6B7BAA00FB208A /* SwiftGif.framework */, 145 | ); 146 | name = Products; 147 | sourceTree = ""; 148 | }; 149 | 14FF87D21D6B7BAA00FB208A /* SwiftGif */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 14FF87D31D6B7BAA00FB208A /* SwiftGif.h */, 153 | 1419B37D194EFBFD005DF6D0 /* UIImage+Gif.swift */, 154 | 14FF87D41D6B7BAA00FB208A /* Info.plist */, 155 | ); 156 | path = SwiftGif; 157 | sourceTree = ""; 158 | }; 159 | /* End PBXGroup section */ 160 | 161 | /* Begin PBXHeadersBuildPhase section */ 162 | 14FF87CE1D6B7BAA00FB208A /* Headers */ = { 163 | isa = PBXHeadersBuildPhase; 164 | buildActionMask = 2147483647; 165 | files = ( 166 | 14FF87E31D6B7BAA00FB208A /* SwiftGif.h in Headers */, 167 | ); 168 | runOnlyForDeploymentPostprocessing = 0; 169 | }; 170 | /* End PBXHeadersBuildPhase section */ 171 | 172 | /* Begin PBXNativeTarget section */ 173 | 14A76437194EFBB800A74B1F /* SwiftGifDemo */ = { 174 | isa = PBXNativeTarget; 175 | buildConfigurationList = 14A7644F194EFBB800A74B1F /* Build configuration list for PBXNativeTarget "SwiftGifDemo" */; 176 | buildPhases = ( 177 | 14A76434194EFBB800A74B1F /* Sources */, 178 | 14A76435194EFBB800A74B1F /* Frameworks */, 179 | 14A76436194EFBB800A74B1F /* Resources */, 180 | 14FF87EB1D6B7BAA00FB208A /* Embed Frameworks */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | 14FF87E51D6B7BAA00FB208A /* PBXTargetDependency */, 186 | ); 187 | name = SwiftGifDemo; 188 | productName = SwiftGif; 189 | productReference = 14A76438194EFBB800A74B1F /* SwiftGifDemo.app */; 190 | productType = "com.apple.product-type.application"; 191 | }; 192 | 14A76444194EFBB800A74B1F /* SwiftGifTests */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 14A76452194EFBB800A74B1F /* Build configuration list for PBXNativeTarget "SwiftGifTests" */; 195 | buildPhases = ( 196 | 14A76441194EFBB800A74B1F /* Sources */, 197 | 14A76442194EFBB800A74B1F /* Frameworks */, 198 | 14A76443194EFBB800A74B1F /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | 14A76447194EFBB800A74B1F /* PBXTargetDependency */, 204 | ); 205 | name = SwiftGifTests; 206 | productName = SwiftGifTests; 207 | productReference = 14A76445194EFBB800A74B1F /* SwiftGifTests.xctest */; 208 | productType = "com.apple.product-type.bundle.unit-test"; 209 | }; 210 | 14FF87D01D6B7BAA00FB208A /* SwiftGif */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 14FF87E81D6B7BAA00FB208A /* Build configuration list for PBXNativeTarget "SwiftGif" */; 213 | buildPhases = ( 214 | 14FF87CC1D6B7BAA00FB208A /* Sources */, 215 | 14FF87CD1D6B7BAA00FB208A /* Frameworks */, 216 | 14FF87CE1D6B7BAA00FB208A /* Headers */, 217 | 14FF87CF1D6B7BAA00FB208A /* Resources */, 218 | ); 219 | buildRules = ( 220 | ); 221 | dependencies = ( 222 | ); 223 | name = SwiftGif; 224 | productName = SwiftGif; 225 | productReference = 14FF87D11D6B7BAA00FB208A /* SwiftGif.framework */; 226 | productType = "com.apple.product-type.framework"; 227 | }; 228 | /* End PBXNativeTarget section */ 229 | 230 | /* Begin PBXProject section */ 231 | 14A76430194EFBB800A74B1F /* Project object */ = { 232 | isa = PBXProject; 233 | attributes = { 234 | LastSwiftUpdateCheck = 0800; 235 | LastUpgradeCheck = 1000; 236 | ORGANIZATIONNAME = "Arne Bahlo"; 237 | TargetAttributes = { 238 | 14A76437194EFBB800A74B1F = { 239 | CreatedOnToolsVersion = 6.0; 240 | LastSwiftMigration = 1030; 241 | }; 242 | 14A76444194EFBB800A74B1F = { 243 | CreatedOnToolsVersion = 6.0; 244 | LastSwiftMigration = 1030; 245 | TestTargetID = 14A76437194EFBB800A74B1F; 246 | }; 247 | 14FF87D01D6B7BAA00FB208A = { 248 | CreatedOnToolsVersion = 8.0; 249 | LastSwiftMigration = 1030; 250 | ProvisioningStyle = Automatic; 251 | }; 252 | }; 253 | }; 254 | buildConfigurationList = 14A76433194EFBB800A74B1F /* Build configuration list for PBXProject "SwiftGif" */; 255 | compatibilityVersion = "Xcode 8.0"; 256 | developmentRegion = English; 257 | hasScannedForEncodings = 0; 258 | knownRegions = ( 259 | English, 260 | en, 261 | ); 262 | mainGroup = 14A7642F194EFBB800A74B1F; 263 | productRefGroup = 14A76439194EFBB800A74B1F /* Products */; 264 | projectDirPath = ""; 265 | projectRoot = ""; 266 | targets = ( 267 | 14A76437194EFBB800A74B1F /* SwiftGifDemo */, 268 | 14A76444194EFBB800A74B1F /* SwiftGifTests */, 269 | 14FF87D01D6B7BAA00FB208A /* SwiftGif */, 270 | ); 271 | }; 272 | /* End PBXProject section */ 273 | 274 | /* Begin PBXResourcesBuildPhase section */ 275 | 14A76436194EFBB800A74B1F /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | FB57A0641CA41C2400065109 /* non_standard_gif.gif in Resources */, 280 | 1419B38D194EFBFD005DF6D0 /* jeremy.gif in Resources */, 281 | 1419B38B194EFBFD005DF6D0 /* Images.xcassets in Resources */, 282 | 1419B389194EFBFD005DF6D0 /* adventure-time.gif in Resources */, 283 | 12166BDC1C73A31800FC3CB5 /* Main.storyboard in Resources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | 14A76443194EFBB800A74B1F /* Resources */ = { 288 | isa = PBXResourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | 1419B390194EFC15005DF6D0 /* test.gif in Resources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | 14FF87CF1D6B7BAA00FB208A /* Resources */ = { 296 | isa = PBXResourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | /* End PBXResourcesBuildPhase section */ 303 | 304 | /* Begin PBXSourcesBuildPhase section */ 305 | 14A76434194EFBB800A74B1F /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | 1419B38A194EFBFD005DF6D0 /* AppDelegate.swift in Sources */, 310 | 12166BDE1C73A52A00FC3CB5 /* DemoVC.swift in Sources */, 311 | 1419B388194EFBFD005DF6D0 /* UIImage+Gif.swift in Sources */, 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | }; 315 | 14A76441194EFBB800A74B1F /* Sources */ = { 316 | isa = PBXSourcesBuildPhase; 317 | buildActionMask = 2147483647; 318 | files = ( 319 | 1482D73B194EFCF10038192B /* UIImage+Gif.swift in Sources */, 320 | 1419B38F194EFC11005DF6D0 /* GifTests.swift in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | 14FF87CC1D6B7BAA00FB208A /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | 9266326F1EC292AD007A31C2 /* UIImage+Gif.swift in Sources */, 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | }; 332 | /* End PBXSourcesBuildPhase section */ 333 | 334 | /* Begin PBXTargetDependency section */ 335 | 14A76447194EFBB800A74B1F /* PBXTargetDependency */ = { 336 | isa = PBXTargetDependency; 337 | target = 14A76437194EFBB800A74B1F /* SwiftGifDemo */; 338 | targetProxy = 14A76446194EFBB800A74B1F /* PBXContainerItemProxy */; 339 | }; 340 | 14FF87E51D6B7BAA00FB208A /* PBXTargetDependency */ = { 341 | isa = PBXTargetDependency; 342 | target = 14FF87D01D6B7BAA00FB208A /* SwiftGif */; 343 | targetProxy = 14FF87E41D6B7BAA00FB208A /* PBXContainerItemProxy */; 344 | }; 345 | /* End PBXTargetDependency section */ 346 | 347 | /* Begin XCBuildConfiguration section */ 348 | 14A7644D194EFBB800A74B1F /* Debug */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ALWAYS_SEARCH_USER_PATHS = NO; 352 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 353 | CLANG_CXX_LIBRARY = "libc++"; 354 | CLANG_ENABLE_MODULES = YES; 355 | CLANG_ENABLE_OBJC_ARC = YES; 356 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 357 | CLANG_WARN_BOOL_CONVERSION = YES; 358 | CLANG_WARN_COMMA = YES; 359 | CLANG_WARN_CONSTANT_CONVERSION = YES; 360 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 361 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 362 | CLANG_WARN_EMPTY_BODY = YES; 363 | CLANG_WARN_ENUM_CONVERSION = YES; 364 | CLANG_WARN_INFINITE_RECURSION = YES; 365 | CLANG_WARN_INT_CONVERSION = YES; 366 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 367 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 368 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 369 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 370 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 371 | CLANG_WARN_STRICT_PROTOTYPES = YES; 372 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 373 | CLANG_WARN_UNREACHABLE_CODE = YES; 374 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 375 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 376 | COPY_PHASE_STRIP = NO; 377 | ENABLE_STRICT_OBJC_MSGSEND = YES; 378 | ENABLE_TESTABILITY = YES; 379 | GCC_C_LANGUAGE_STANDARD = gnu99; 380 | GCC_DYNAMIC_NO_PIC = NO; 381 | GCC_NO_COMMON_BLOCKS = YES; 382 | GCC_OPTIMIZATION_LEVEL = 0; 383 | GCC_PREPROCESSOR_DEFINITIONS = ( 384 | "DEBUG=1", 385 | "$(inherited)", 386 | ); 387 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 390 | GCC_WARN_UNDECLARED_SELECTOR = YES; 391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 392 | GCC_WARN_UNUSED_FUNCTION = YES; 393 | GCC_WARN_UNUSED_VARIABLE = YES; 394 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 395 | METAL_ENABLE_DEBUG_INFO = YES; 396 | ONLY_ACTIVE_ARCH = YES; 397 | SDKROOT = iphoneos; 398 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 399 | }; 400 | name = Debug; 401 | }; 402 | 14A7644E194EFBB800A74B1F /* Release */ = { 403 | isa = XCBuildConfiguration; 404 | buildSettings = { 405 | ALWAYS_SEARCH_USER_PATHS = NO; 406 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 407 | CLANG_CXX_LIBRARY = "libc++"; 408 | CLANG_ENABLE_MODULES = YES; 409 | CLANG_ENABLE_OBJC_ARC = YES; 410 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 411 | CLANG_WARN_BOOL_CONVERSION = YES; 412 | CLANG_WARN_COMMA = YES; 413 | CLANG_WARN_CONSTANT_CONVERSION = YES; 414 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 415 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 416 | CLANG_WARN_EMPTY_BODY = YES; 417 | CLANG_WARN_ENUM_CONVERSION = YES; 418 | CLANG_WARN_INFINITE_RECURSION = YES; 419 | CLANG_WARN_INT_CONVERSION = YES; 420 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 421 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 422 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 423 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 424 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 425 | CLANG_WARN_STRICT_PROTOTYPES = YES; 426 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 427 | CLANG_WARN_UNREACHABLE_CODE = YES; 428 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 429 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 430 | COPY_PHASE_STRIP = YES; 431 | ENABLE_NS_ASSERTIONS = NO; 432 | ENABLE_STRICT_OBJC_MSGSEND = YES; 433 | GCC_C_LANGUAGE_STANDARD = gnu99; 434 | GCC_NO_COMMON_BLOCKS = YES; 435 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 436 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 437 | GCC_WARN_UNDECLARED_SELECTOR = YES; 438 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 439 | GCC_WARN_UNUSED_FUNCTION = YES; 440 | GCC_WARN_UNUSED_VARIABLE = YES; 441 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 442 | METAL_ENABLE_DEBUG_INFO = NO; 443 | SDKROOT = iphoneos; 444 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 445 | VALIDATE_PRODUCT = YES; 446 | }; 447 | name = Release; 448 | }; 449 | 14A76450194EFBB800A74B1F /* Debug */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 453 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 454 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 455 | DEVELOPMENT_TEAM = AK9NEP7BV6; 456 | INFOPLIST_FILE = "$(SRCROOT)/SwiftGifDemo/Info.plist"; 457 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 458 | PRODUCT_BUNDLE_IDENTIFIER = me.arne.SwiftGifDemo; 459 | PRODUCT_NAME = "$(TARGET_NAME)"; 460 | SWIFT_VERSION = 5.0; 461 | }; 462 | name = Debug; 463 | }; 464 | 14A76451194EFBB800A74B1F /* Release */ = { 465 | isa = XCBuildConfiguration; 466 | buildSettings = { 467 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 470 | DEVELOPMENT_TEAM = AK9NEP7BV6; 471 | INFOPLIST_FILE = "$(SRCROOT)/SwiftGifDemo/Info.plist"; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 473 | PRODUCT_BUNDLE_IDENTIFIER = me.arne.SwiftGifDemo; 474 | PRODUCT_NAME = "$(TARGET_NAME)"; 475 | SWIFT_VERSION = 5.0; 476 | }; 477 | name = Release; 478 | }; 479 | 14A76453194EFBB800A74B1F /* Debug */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | BUNDLE_LOADER = "$(TEST_HOST)"; 483 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 484 | GCC_PREPROCESSOR_DEFINITIONS = ( 485 | "DEBUG=1", 486 | "$(inherited)", 487 | ); 488 | INFOPLIST_FILE = SwiftGifTests/Info.plist; 489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 490 | METAL_ENABLE_DEBUG_INFO = YES; 491 | PRODUCT_BUNDLE_IDENTIFIER = "me.arne.${PRODUCT_NAME:rfc1034identifier}"; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | SWIFT_VERSION = 5.0; 494 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftGifDemo.app/SwiftGifDemo"; 495 | }; 496 | name = Debug; 497 | }; 498 | 14A76454194EFBB800A74B1F /* Release */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | BUNDLE_LOADER = "$(TEST_HOST)"; 502 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 503 | INFOPLIST_FILE = SwiftGifTests/Info.plist; 504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 505 | METAL_ENABLE_DEBUG_INFO = NO; 506 | PRODUCT_BUNDLE_IDENTIFIER = "me.arne.${PRODUCT_NAME:rfc1034identifier}"; 507 | PRODUCT_NAME = "$(TARGET_NAME)"; 508 | SWIFT_VERSION = 5.0; 509 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftGifDemo.app/SwiftGifDemo"; 510 | }; 511 | name = Release; 512 | }; 513 | 14FF87E91D6B7BAA00FB208A /* Debug */ = { 514 | isa = XCBuildConfiguration; 515 | buildSettings = { 516 | CLANG_ANALYZER_NONNULL = YES; 517 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 518 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 519 | CODE_SIGN_IDENTITY = ""; 520 | CURRENT_PROJECT_VERSION = 1; 521 | DEBUG_INFORMATION_FORMAT = dwarf; 522 | DEFINES_MODULE = YES; 523 | DEVELOPMENT_TEAM = AK9NEP7BV6; 524 | DYLIB_COMPATIBILITY_VERSION = 1; 525 | DYLIB_CURRENT_VERSION = 1; 526 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 527 | INFOPLIST_FILE = SwiftGif/Info.plist; 528 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 529 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 531 | MTL_ENABLE_DEBUG_INFO = YES; 532 | PRODUCT_BUNDLE_IDENTIFIER = me.arne.SwiftGif; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | SKIP_INSTALL = YES; 535 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 536 | SWIFT_VERSION = 5.0; 537 | TARGETED_DEVICE_FAMILY = "1,2"; 538 | VERSIONING_SYSTEM = "apple-generic"; 539 | VERSION_INFO_PREFIX = ""; 540 | }; 541 | name = Debug; 542 | }; 543 | 14FF87EA1D6B7BAA00FB208A /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | CLANG_ANALYZER_NONNULL = YES; 547 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 548 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 549 | CODE_SIGN_IDENTITY = ""; 550 | COPY_PHASE_STRIP = NO; 551 | CURRENT_PROJECT_VERSION = 1; 552 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 553 | DEFINES_MODULE = YES; 554 | DEVELOPMENT_TEAM = AK9NEP7BV6; 555 | DYLIB_COMPATIBILITY_VERSION = 1; 556 | DYLIB_CURRENT_VERSION = 1; 557 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 558 | INFOPLIST_FILE = SwiftGif/Info.plist; 559 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 560 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 561 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 562 | MTL_ENABLE_DEBUG_INFO = NO; 563 | PRODUCT_BUNDLE_IDENTIFIER = me.arne.SwiftGif; 564 | PRODUCT_NAME = "$(TARGET_NAME)"; 565 | SKIP_INSTALL = YES; 566 | SWIFT_VERSION = 5.0; 567 | TARGETED_DEVICE_FAMILY = "1,2"; 568 | VERSIONING_SYSTEM = "apple-generic"; 569 | VERSION_INFO_PREFIX = ""; 570 | }; 571 | name = Release; 572 | }; 573 | /* End XCBuildConfiguration section */ 574 | 575 | /* Begin XCConfigurationList section */ 576 | 14A76433194EFBB800A74B1F /* Build configuration list for PBXProject "SwiftGif" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | 14A7644D194EFBB800A74B1F /* Debug */, 580 | 14A7644E194EFBB800A74B1F /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | defaultConfigurationName = Release; 584 | }; 585 | 14A7644F194EFBB800A74B1F /* Build configuration list for PBXNativeTarget "SwiftGifDemo" */ = { 586 | isa = XCConfigurationList; 587 | buildConfigurations = ( 588 | 14A76450194EFBB800A74B1F /* Debug */, 589 | 14A76451194EFBB800A74B1F /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | 14A76452194EFBB800A74B1F /* Build configuration list for PBXNativeTarget "SwiftGifTests" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | 14A76453194EFBB800A74B1F /* Debug */, 598 | 14A76454194EFBB800A74B1F /* Release */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | 14FF87E81D6B7BAA00FB208A /* Build configuration list for PBXNativeTarget "SwiftGif" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | 14FF87E91D6B7BAA00FB208A /* Debug */, 607 | 14FF87EA1D6B7BAA00FB208A /* Release */, 608 | ); 609 | defaultConfigurationIsVisible = 0; 610 | defaultConfigurationName = Release; 611 | }; 612 | /* End XCConfigurationList section */ 613 | }; 614 | rootObject = 14A76430194EFBB800A74B1F /* Project object */; 615 | } 616 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/project.xcworkspace/xcshareddata/SwiftGif.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 296869D0-C15D-4327-A221-B75F7F6D6F5B 9 | IDESourceControlProjectName 10 | SwiftGif 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | CC1CB80635DAA6EE75D19EA4BDDA420AB94DBCEA 14 | github.com:bahlo/SwiftGif.git 15 | 16 | IDESourceControlProjectPath 17 | SwiftGif.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | CC1CB80635DAA6EE75D19EA4BDDA420AB94DBCEA 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:bahlo/SwiftGif.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | CC1CB80635DAA6EE75D19EA4BDDA420AB94DBCEA 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | CC1CB80635DAA6EE75D19EA4BDDA420AB94DBCEA 36 | IDESourceControlWCCName 37 | SwiftGif 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/xcshareddata/xcschemes/SwiftGif.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/xcshareddata/xcschemes/SwiftGifDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /SwiftGif.xcodeproj/xcshareddata/xcschemes/SwiftGifTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /SwiftGif/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SwiftGif/SwiftGif.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftGif.h 3 | // SwiftGif 4 | // 5 | // Created by Arne Bahlo on 22.08.16. 6 | // Copyright © 2016 Arne Bahlo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SwiftGif. 12 | FOUNDATION_EXPORT double SwiftGifVersionNumber; 13 | 14 | //! Project version string for SwiftGif. 15 | FOUNDATION_EXPORT const unsigned char SwiftGifVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SwiftGifCommon/UIImage+Gif.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Gif.swift 3 | // SwiftGif 4 | // 5 | // Created by Arne Bahlo on 07.06.14. 6 | // Copyright (c) 2014 Arne Bahlo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ImageIO 11 | 12 | extension UIImageView { 13 | 14 | public func loadGif(name: String) { 15 | DispatchQueue.global().async { 16 | let image = UIImage.gif(name: name) 17 | DispatchQueue.main.async { 18 | self.image = image 19 | } 20 | } 21 | } 22 | 23 | @available(iOS 9.0, *) 24 | public func loadGif(asset: String) { 25 | DispatchQueue.global().async { 26 | let image = UIImage.gif(asset: asset) 27 | DispatchQueue.main.async { 28 | self.image = image 29 | } 30 | } 31 | } 32 | 33 | } 34 | 35 | extension UIImage { 36 | 37 | public class func gif(data: Data) -> UIImage? { 38 | // Create source from data 39 | guard let source = CGImageSourceCreateWithData(data as CFData, nil) else { 40 | print("SwiftGif: Source for the image does not exist") 41 | return nil 42 | } 43 | 44 | return UIImage.animatedImageWithSource(source) 45 | } 46 | 47 | public class func gif(url: String) -> UIImage? { 48 | // Validate URL 49 | guard let bundleURL = URL(string: url) else { 50 | print("SwiftGif: This image named \"\(url)\" does not exist") 51 | return nil 52 | } 53 | 54 | // Validate data 55 | guard let imageData = try? Data(contentsOf: bundleURL) else { 56 | print("SwiftGif: Cannot turn image named \"\(url)\" into NSData") 57 | return nil 58 | } 59 | 60 | return gif(data: imageData) 61 | } 62 | 63 | public class func gif(name: String) -> UIImage? { 64 | // Check for existance of gif 65 | guard let bundleURL = Bundle.main 66 | .url(forResource: name, withExtension: "gif") else { 67 | print("SwiftGif: This image named \"\(name)\" does not exist") 68 | return nil 69 | } 70 | 71 | // Validate data 72 | guard let imageData = try? Data(contentsOf: bundleURL) else { 73 | print("SwiftGif: Cannot turn image named \"\(name)\" into NSData") 74 | return nil 75 | } 76 | 77 | return gif(data: imageData) 78 | } 79 | 80 | @available(iOS 9.0, *) 81 | public class func gif(asset: String) -> UIImage? { 82 | // Create source from assets catalog 83 | guard let dataAsset = NSDataAsset(name: asset) else { 84 | print("SwiftGif: Cannot turn image named \"\(asset)\" into NSDataAsset") 85 | return nil 86 | } 87 | 88 | return gif(data: dataAsset.data) 89 | } 90 | 91 | internal class func delayForImageAtIndex(_ index: Int, source: CGImageSource!) -> Double { 92 | var delay = 0.1 93 | 94 | // Get dictionaries 95 | let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil) 96 | let gifPropertiesPointer = UnsafeMutablePointer.allocate(capacity: 0) 97 | defer { 98 | gifPropertiesPointer.deallocate() 99 | } 100 | let unsafePointer = Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque() 101 | if CFDictionaryGetValueIfPresent(cfProperties, unsafePointer, gifPropertiesPointer) == false { 102 | return delay 103 | } 104 | 105 | let gifProperties: CFDictionary = unsafeBitCast(gifPropertiesPointer.pointee, to: CFDictionary.self) 106 | 107 | // Get delay time 108 | var delayObject: AnyObject = unsafeBitCast( 109 | CFDictionaryGetValue(gifProperties, 110 | Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()), 111 | to: AnyObject.self) 112 | if delayObject.doubleValue == 0 { 113 | delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties, 114 | Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self) 115 | } 116 | 117 | if let delayObject = delayObject as? Double, delayObject > 0 { 118 | delay = delayObject 119 | } else { 120 | delay = 0.1 // Make sure they're not too fast 121 | } 122 | 123 | return delay 124 | } 125 | 126 | internal class func gcdForPair(_ lhs: Int?, _ rhs: Int?) -> Int { 127 | var lhs = lhs 128 | var rhs = rhs 129 | // Check if one of them is nil 130 | if rhs == nil || lhs == nil { 131 | if rhs != nil { 132 | return rhs! 133 | } else if lhs != nil { 134 | return lhs! 135 | } else { 136 | return 0 137 | } 138 | } 139 | 140 | // Swap for modulo 141 | if lhs! < rhs! { 142 | let ctp = lhs 143 | lhs = rhs 144 | rhs = ctp 145 | } 146 | 147 | // Get greatest common divisor 148 | var rest: Int 149 | while true { 150 | rest = lhs! % rhs! 151 | 152 | if rest == 0 { 153 | return rhs! // Found it 154 | } else { 155 | lhs = rhs 156 | rhs = rest 157 | } 158 | } 159 | } 160 | 161 | internal class func gcdForArray(_ array: [Int]) -> Int { 162 | if array.isEmpty { 163 | return 1 164 | } 165 | 166 | var gcd = array[0] 167 | 168 | for val in array { 169 | gcd = UIImage.gcdForPair(val, gcd) 170 | } 171 | 172 | return gcd 173 | } 174 | 175 | internal class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? { 176 | let count = CGImageSourceGetCount(source) 177 | var images = [CGImage]() 178 | var delays = [Int]() 179 | 180 | // Fill arrays 181 | for index in 0.. 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.6 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwiftGifDemo/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /SwiftGifDemo/adventure-time.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swiftgif/SwiftGif/7234d124592190eada4af939647d16055ba6134b/SwiftGifDemo/adventure-time.gif -------------------------------------------------------------------------------- /SwiftGifDemo/jeremy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swiftgif/SwiftGif/7234d124592190eada4af939647d16055ba6134b/SwiftGifDemo/jeremy.gif -------------------------------------------------------------------------------- /SwiftGifDemo/non_standard_gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swiftgif/SwiftGif/7234d124592190eada4af939647d16055ba6134b/SwiftGifDemo/non_standard_gif.gif -------------------------------------------------------------------------------- /SwiftGifOrigin.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'SwiftGifOrigin' 3 | spec.version = '1.7.0' 4 | spec.license = { 'type' => 'MIT' } 5 | spec.homepage = 'https://github.com/bahlo/SwiftGif' 6 | spec.authors = { 'Arne Bahlo' => 'hallo@arne.me' } 7 | spec.summary = 'A small UIImage extension with gif support' 8 | spec.source = { git: 'https://github.com/bahlo/SwiftGif.git', tag: 'v1.7.0' } 9 | 10 | spec.ios.deployment_target = '8.0' 11 | spec.tvos.deployment_target = '9.0' 12 | 13 | spec.source_files = 'SwiftGifCommon/*.swift' 14 | end 15 | -------------------------------------------------------------------------------- /SwiftGifTests/GifTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GifTests.swift 3 | // SwiftGif 4 | // 5 | // Created by Arne Bahlo on 12.06.14. 6 | // Copyright (c) 2014 Arne Bahlo. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import UIKit 11 | import ImageIO 12 | 13 | class GifTests: XCTestCase { 14 | 15 | var imageData: Data? 16 | var source: CGImageSource? 17 | 18 | override func setUp() { 19 | super.setUp() 20 | 21 | imageData = try? Data(contentsOf: Bundle(for: GifTests.self) 22 | .url(forResource: "test", withExtension: "gif")!) 23 | 24 | let cfImageData = imageData! as CFData 25 | source = CGImageSourceCreateWithData(cfImageData, nil) 26 | } 27 | 28 | override func tearDown() { 29 | imageData = nil 30 | source = nil 31 | 32 | super.tearDown() 33 | } 34 | 35 | func testGCDForPair() { 36 | let values = (9, 4011) 37 | let result = UIImage.gcdForPair(values.1, values.0) 38 | let expected = 3 39 | 40 | XCTAssert(result == expected, 41 | "UIImage.gcdForPair(\(values.0), \(values.1)) = \(result), but should be \(expected)") 42 | } 43 | 44 | func testGCDForArray() { 45 | let values = [13, 17_381, 169] 46 | let result = UIImage.gcdForArray(values) 47 | let expected = 13 48 | 49 | XCTAssert(result == expected, 50 | "UIImage.gcdForArray(\(values)) = \(result), but should be \(expected)") 51 | } 52 | 53 | func testDelayForImageAtIndex() { 54 | let result = UIImage.delayForImageAtIndex(0, source: source!) 55 | let expected = 0.5 56 | 57 | XCTAssert(result == expected, 58 | "UIImage.delayForImageAtIndex(0, source) = \(result), but should be \(expected)") 59 | } 60 | 61 | func testAnimatedImageWithSource() { 62 | let image = UIImage.animatedImageWithSource(source!) 63 | 64 | XCTAssertNotNil(image, 65 | "UIImage.animatedImageWithSource(source) is nil, but shouldn't") 66 | 67 | // Note: There should be 12, because they delay is the same for all 68 | let frames = image!.images as Array? 69 | XCTAssert(frames!.count == 12, "image.images.count = \(frames!.count), but should be 12") 70 | 71 | XCTAssert(image!.duration == 6.0, "image.duration = \(image!.duration), but should be 6.0") 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /SwiftGifTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftGifTests/test.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swiftgif/SwiftGif/7234d124592190eada4af939647d16055ba6134b/SwiftGifTests/test.gif -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swiftgif/SwiftGif/7234d124592190eada4af939647d16055ba6134b/demo.gif --------------------------------------------------------------------------------