├── .gitignore ├── Screenshot └── Fonty-Demo.gif ├── Fonty-Demo.xcodeproj ├── project.xcworkspace │ ├── xcuserdata │ │ ├── QQQ.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ └── yanweichen.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── contents.xcworkspacedata ├── xcuserdata │ ├── QQQ.xcuserdatad │ │ ├── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── Fonty-Demo.xcscheme │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ └── yanweichen.xcuserdatad │ │ ├── xcschemes │ │ ├── xcschememanagement.plist │ │ └── Fonty-Demo.xcscheme │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist ├── xcshareddata │ └── xcschemes │ │ └── Fonty-DemoTests.xcscheme └── project.pbxproj ├── Fonty-Demo ├── ViewController.h ├── FYSelectFontViewController.h ├── AppDelegate.h ├── main.m ├── FYSelectFontTableViewCell.h ├── AppDelegate.m ├── ViewController.m ├── Info.plist ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── FYSelectFontTableViewCell.m └── FYSelectFontViewController.m ├── .travis.yml ├── Fonty ├── Fonty.h ├── UIFont+FY_Fonty.h ├── FYFontRegister.h ├── UIFont+FY_Fonty.m ├── FYFontDownloader.h ├── FYDownloadDelegate.h ├── FYFontCache.h ├── FYFontManager.h ├── FYFontFile.h ├── FYFontRegister.m ├── FYDownloadDelegate.m ├── FYFontCache.m ├── FYFontDownloader.m ├── FYFontFile.m └── FYFontManager.m ├── Fonty-DemoTests ├── Info.plist └── Fonty_DemoTests.m ├── LICENSE ├── README.md └── Fonty.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /Screenshot/Fonty-Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s2mh/Fonty/HEAD/Screenshot/Fonty-Demo.gif -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/project.xcworkspace/xcuserdata/QQQ.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s2mh/Fonty/HEAD/Fonty-Demo.xcodeproj/project.xcworkspace/xcuserdata/QQQ.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/project.xcworkspace/xcuserdata/yanweichen.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s2mh/Fonty/HEAD/Fonty-Demo.xcodeproj/project.xcworkspace/xcuserdata/yanweichen.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Fonty-Demo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Fonty-Demo 4 | // 5 | // Created by 颜为晨 on 9/12/16. 6 | // Copyright © 2016 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: 3 | - xcodebuild test -project Fonty-Demo.xcodeproj -scheme 'Fonty-DemoTests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' -configuration Debug | xcpretty -c 4 | after_success: 5 | - bash <(curl -s https://codecov.io/bash) 6 | -------------------------------------------------------------------------------- /Fonty-Demo/FYSelectFontViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYSelectFontViewController.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FYSelectFontViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Fonty/Fonty.h: -------------------------------------------------------------------------------- 1 | // 2 | // Fonty.h 3 | // Fonty-Demo 4 | // 5 | // Created by QQQ on 17/4/10. 6 | // Copyright © 2017年 s2mh. All rights reserved. 7 | // 8 | 9 | #ifndef Fonty_h 10 | #define Fonty_h 11 | 12 | #import "FYFontManager.h" 13 | #import "FYFontFile.h" 14 | #import "UIFont+FY_Fonty.h" 15 | 16 | #endif /* Fonty_h */ 17 | -------------------------------------------------------------------------------- /Fonty-Demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Fonty-Demo 4 | // 5 | // Created by 颜为晨 on 9/12/16. 6 | // Copyright © 2016 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Fonty-Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Fonty-Demo 4 | // 5 | // Created by 颜为晨 on 9/12/16. 6 | // Copyright © 2016 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Fonty/UIFont+FY_Fonty.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+FY_Fonty.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 16/7/2. 6 | // Copyright © 2016年 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Fonty.h" 11 | 12 | @interface UIFont (FY_Fonty) 13 | 14 | + (UIFont *)fy_mainFontWithSize:(CGFloat)size; 15 | + (UIFont *)fy_fontOfModel:(FYFontModel *)model withSize:(CGFloat)size; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Fonty-Demo/FYSelectFontTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYSelectFontTableViewCell.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FYSelectFontTableViewCell : UITableViewCell 12 | 13 | @property (nonatomic, assign) BOOL striped; 14 | @property (nonatomic, assign) BOOL pauseStripes; 15 | @property (nonatomic, assign) double downloadProgress; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Fonty/FYFontRegister.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontRegister.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FYFontFile; 12 | 13 | extern NSString * const FYFontRegisterErrorPostScriptName; 14 | 15 | @interface FYFontRegister : NSObject 16 | 17 | + (BOOL)registerFontInFile:(FYFontFile *)file; 18 | + (BOOL)unregisterFontInFile:(FYFontFile *)file; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Fonty/UIFont+FY_Fonty.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+FY_Fonty.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 16/7/2. 6 | // Copyright © 2016年 颜为晨. All rights reserved. 7 | // 8 | 9 | #import "UIFont+FY_Fonty.h" 10 | 11 | @implementation UIFont (FY_Fonty) 12 | 13 | + (UIFont *)fy_mainFontWithSize:(CGFloat)size { 14 | return [[FYFontManager mainFont] fontWithSize:size]; 15 | } 16 | 17 | + (UIFont *)fy_fontOfModel:(FYFontModel *)model withSize:(CGFloat)size { 18 | return [model.font fontWithSize:size]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Fonty/FYFontDownloader.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontDownloader.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FYFontFile; 12 | 13 | @interface FYFontDownloader : NSObject 14 | 15 | - (void)downloadFontFile:(FYFontFile *)file progress:(void(^)(FYFontFile *file))progress completionHandler:(void(^)(NSError *error))completionHandler; 16 | - (void)cancelDownloadingFile:(FYFontFile *)file; 17 | - (void)suspendDownloadFile:(FYFontFile *)file; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Fonty/FYDownloadDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYDownloadDelegate.h 3 | // Fonty-Demo 4 | // 5 | // Created by QQQ on 17/4/12. 6 | // Copyright © 2017年 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FYFontFile; 12 | 13 | @interface FYDownloadDelegate : NSObject 14 | 15 | - (instancetype)initWithTask:(NSURLSessionDownloadTask *)task; 16 | 17 | @property (nonatomic, weak) FYFontFile *file; 18 | @property (nonatomic, copy) void(^progress)(FYFontFile *file); 19 | @property (nonatomic, copy) void(^completionHandler)(NSError *error); 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Fonty/FYFontCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontCache.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 16/7/2. 6 | // Copyright © 2016年 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FYFontFile; 12 | 13 | @interface FYFontCache : NSObject 14 | 15 | + (BOOL)cacheObject:(id)object fileName:(NSString *)fileName; 16 | + (id)objectFromCacheWithFileName:(NSString *)fileName; 17 | 18 | + (void)cacheFile:(FYFontFile *)file atLocation:(NSURL *)location completionHandler:(void(^)(NSError *error))completionHandler ; 19 | + (void)cleanCachedFile:(FYFontFile *)file completionHandler:(void(^)(NSError *error))completionHandler; 20 | 21 | + (NSString *)diskCacheDirectoryPath; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Fonty-DemoTests/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 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcuserdata/QQQ.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Fonty-Demo.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | Fonty-DemoTests.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 6A6F37841DE3001700E0B360 21 | 22 | primary 23 | 24 | 25 | 6A73D6AB1D86BB2600D38630 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcuserdata/yanweichen.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Fonty-Demo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | Fonty-DemoTests.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 6A6F37841DE3001700E0B360 21 | 22 | primary 23 | 24 | 25 | 6A73D6AB1D86BB2600D38630 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Fonty-Demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Fonty-Demo 4 | // 5 | // Created by 颜为晨 on 9/12/16. 6 | // Copyright © 2016 s2mh. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "FYFontManager.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | [FYFontManager setFileURLStrings:@[@"https://github.com/s2mh/FontFile/raw/master/Chinese/Simplified%20Chinese/ttc/Xingkai.ttc", 20 | @"https://github.com/s2mh/FontFile/raw/master/Common/Regular/YuppySC-Regular.otf", 21 | @"https://github.com/s2mh/FontFile/raw/master/English/Bold/Luminari.ttf", 22 | @"https://github.com/s2mh/FontFile/raw/master/Common/Bold/LiHeiPro.ttf"]]; 23 | 24 | return YES; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Fonty-Demo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Fonty-Demo 4 | // 5 | // Created by 颜为晨 on 9/12/16. 6 | // Copyright © 2016 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ViewController.h" 12 | #import "FYSelectFontViewController.h" 13 | 14 | #import "Fonty.h" 15 | 16 | @interface ViewController () 17 | 18 | @property (weak, nonatomic) IBOutlet UITextView *textView; 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (void)viewWillAppear:(BOOL)animated { 25 | [super viewWillAppear:animated]; 26 | 27 | self.textView.font = [UIFont fy_mainFontWithSize:39.0f]; 28 | } 29 | 30 | #pragma mark - Action 31 | 32 | - (IBAction)barButtonItemAction:(UIBarButtonItem *)sender { 33 | FYSelectFontViewController *vc = [[FYSelectFontViewController alloc] initWithStyle:UITableViewStyleGrouped]; 34 | UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc]; 35 | [self presentViewController:nc animated:YES completion:nil]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Fonty-DemoTests/Fonty_DemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Fonty_DemoTests.m 3 | // Fonty-DemoTests 4 | // 5 | // Created by 颜为晨 on 21/11/2016. 6 | // Copyright © 2016 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Fonty_DemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Fonty_DemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2016 Alamofire Software Foundation (http://alamofire.org/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcuserdata/QQQ.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 18 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcuserdata/yanweichen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 13 | 14 | 15 | 17 | 23 | 24 | 25 | 27 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Fonty/FYFontManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontManager.h 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 16/7/2. 6 | // Copyright © 2016年 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class FYFontFile, FYFontModel; 13 | 14 | extern NSString *const FYFontFileDownloadingNotification; 15 | extern NSString *const FYFontFileDownloadStateDidChangeNotification; 16 | extern NSString *const FYFontFileDownloadingDidCompleteNotification; 17 | extern NSString *const FYFontFileRegisteringDidCompleteNotification; 18 | extern NSString *const FYFontFileDeletingDidCompleteNotification; 19 | extern NSString *const FYFontFileNotificationUserInfoKey; 20 | 21 | @interface FYFontManager : NSObject 22 | 23 | + (void)archive; 24 | 25 | + (void)downloadFontFile:(FYFontFile *)file; 26 | + (void)downloadFontFile:(FYFontFile *)file 27 | progress:(void(^)(FYFontFile *file))progress 28 | completionHandler:(void(^)(NSError *error))completionHandler; 29 | + (void)cancelDownloadingFontFile:(FYFontFile *)file; 30 | + (void)pauseDownloadingFile:(FYFontFile *)file; 31 | + (void)deleteFontFile:(FYFontFile *)file; 32 | + (void)deleteFontFile:(FYFontFile *)file 33 | completionHandler:(void(^)(NSError *error))completionHandler; 34 | + (BOOL)registerFontFile:(FYFontFile *)file; 35 | 36 | @property (class, nonatomic, copy) NSArray *fileURLStrings; 37 | @property (class, nonatomic, copy, readonly) NSArray *fontFiles; 38 | @property (class, nonatomic, strong) UIFont *mainFont; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Fonty-Demo/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIMainStoryboardFile 33 | Main 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Fonty/FYFontFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontFile.h 3 | // Fonty-Demo 4 | // 5 | // Created by QQQ on 17/3/27. 6 | // Copyright © 2017年 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FYFontModel, UIFont; 12 | 13 | typedef NS_ENUM(NSUInteger, FYFontFileDownloadState) { 14 | FYFontFileDownloadStateToBeDownloaded, 15 | FYFontFileDownloadStateDownloading, 16 | FYFontFileDownloadStateSuspended, 17 | FYFontFileDownloadStateDownloaded, 18 | }; 19 | 20 | @interface FYFontFile : NSObject 21 | 22 | - (instancetype)initWithSourceURLString:(NSString *)sourceURLString; 23 | 24 | @property (nonatomic, copy, readonly) NSString *sourceURLString; 25 | @property (nonatomic, assign, readonly) FYFontFileDownloadState downloadStatus; 26 | @property (nonatomic, assign, readonly) int64_t fileSize; 27 | @property (nonatomic, assign, readonly) int64_t fileDownloadedSize; 28 | @property (nonatomic, assign, readonly) double downloadProgress; 29 | @property (nonatomic, assign, readonly) BOOL fileSizeUnknown; 30 | @property (nonatomic, copy, readonly) NSError *downloadError; 31 | @property (nonatomic, weak, readonly) NSURLSessionDownloadTask *downloadTask; 32 | 33 | @property (nonatomic, copy) NSString *localPath; 34 | @property (nonatomic, copy) NSString *fileName; 35 | @property (nonatomic, assign) BOOL registered; 36 | @property (nonatomic, copy) NSArray *fontModels; 37 | 38 | - (void)clear; 39 | - (void)resetWithDownloadTask:(NSURLSessionDownloadTask *)downloadTask; 40 | 41 | @end 42 | 43 | @interface FYFontModel : NSObject 44 | 45 | @property (nonatomic, strong) UIFont *font; 46 | @property (nonatomic, copy) NSString *postScriptName; 47 | @property (nonatomic, weak) FYFontFile *fontFile; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Fonty-Demo/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /Fonty-Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcshareddata/xcschemes/Fonty-DemoTests.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 | -------------------------------------------------------------------------------- /Fonty/FYFontRegister.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontRegister.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "FYFontRegister.h" 13 | #import "FYFontManager.h" 14 | #import "FYFontFile.h" 15 | 16 | NSString * const FYFontRegisterErrorPostScriptName = @"FYFontRegisterErrorPostScriptName"; 17 | 18 | @implementation FYFontRegister 19 | 20 | + (BOOL)registerFontInFile:(FYFontFile *)file { 21 | CFStringRef fontPath = CFStringCreateWithCString(NULL, [file.localPath UTF8String], kCFStringEncodingUTF8); 22 | CFURLRef fontURL = CFURLCreateWithFileSystemPath(NULL, fontPath, kCFURLPOSIXPathStyle, 0); 23 | CFErrorRef error = NULL; 24 | CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeNone, &error); 25 | 26 | if (error) { 27 | CFRelease(fontURL); 28 | CFRelease(fontPath); 29 | CFRelease(error); 30 | return NO; 31 | } 32 | CFArrayRef fontArray = CTFontManagerCreateFontDescriptorsFromURL(fontURL); 33 | NSMutableArray *fontModels = [NSMutableArray array]; 34 | if (fontArray) { 35 | CGFloat size = 0.0; 36 | for (CFIndex i = 0 ; i < CFArrayGetCount(fontArray); i++) { 37 | CTFontDescriptorRef descriptor = CFArrayGetValueAtIndex(fontArray, i); 38 | CTFontRef fontRef = CTFontCreateWithFontDescriptor(descriptor, size, NULL); 39 | CFStringRef fontName = CTFontCopyName(fontRef, kCTFontPostScriptNameKey); 40 | UIFont *font = CFBridgingRelease(CTFontCreateWithNameAndOptions(fontName, 0.0, NULL, kCTFontOptionsDefault)); 41 | if (font) { 42 | FYFontModel *model = [[FYFontModel alloc] init]; 43 | model.postScriptName = CFBridgingRelease(fontName); 44 | model.font = font; 45 | model.fontFile = file; 46 | [fontModels addObject:model]; 47 | } 48 | CFRelease(fontRef); 49 | } 50 | file.fontModels = fontModels; 51 | if (fontModels.count > 0) { 52 | file.registered = YES; 53 | } 54 | CFRelease(fontArray); 55 | } 56 | CFRelease(fontURL); 57 | CFRelease(fontPath); 58 | 59 | dispatch_async(dispatch_get_main_queue(), ^{ 60 | [[NSNotificationCenter defaultCenter] postNotificationName:FYFontFileRegisteringDidCompleteNotification 61 | object:nil 62 | userInfo:@{FYFontFileNotificationUserInfoKey:file}]; 63 | }); 64 | 65 | return YES; 66 | } 67 | 68 | + (BOOL)unregisterFontInFile:(FYFontFile *)file { 69 | BOOL success = YES; 70 | if (file.localPath) { 71 | CFStringRef fontPath = CFStringCreateWithCString(NULL, [file.localPath UTF8String], kCFStringEncodingUTF8); 72 | CFURLRef fontURL = CFURLCreateWithFileSystemPath(NULL, fontPath, kCFURLPOSIXPathStyle, 0); 73 | if (fontURL) { 74 | success = CTFontManagerUnregisterFontsForURL(fontURL, kCTFontManagerScopeNone, NULL); 75 | } 76 | CFRelease(fontURL); 77 | CFRelease(fontPath); 78 | } 79 | return success; 80 | } 81 | 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Fonty/FYDownloadDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYDownloadDelegate.m 3 | // Fonty-Demo 4 | // 5 | // Created by QQQ on 17/4/12. 6 | // Copyright © 2017年 s2mh. All rights reserved. 7 | // 8 | 9 | #import "FYDownloadDelegate.h" 10 | #import "FYFontFile.h" 11 | #import "FYFontCache.h" 12 | #import "FYFontManager.h" 13 | 14 | @interface FYDownloadDelegate () 15 | 16 | @property (nonatomic, weak) NSURLSessionDownloadTask *task; 17 | 18 | @end 19 | 20 | @implementation FYDownloadDelegate 21 | 22 | - (instancetype)initWithTask:(NSURLSessionDownloadTask *)task 23 | { 24 | self = [super init]; 25 | if (self) { 26 | _task = task; 27 | } 28 | return self; 29 | } 30 | 31 | #pragma mark - NSURLSessionDownloadDelegate 32 | 33 | - (void)URLSession:(NSURLSession *)session 34 | downloadTask:(NSURLSessionDownloadTask *)downloadTask 35 | didWriteData:(int64_t)bytesWritten 36 | totalBytesWritten:(int64_t)totalBytesWritten 37 | totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { 38 | [self.file resetWithDownloadTask:downloadTask]; 39 | if (self.progress) { 40 | self.progress(self.file); 41 | }; 42 | dispatch_async(dispatch_get_main_queue(), ^{ 43 | [[NSNotificationCenter defaultCenter] postNotificationName:FYFontFileDownloadingNotification 44 | object:nil 45 | userInfo:@{FYFontFileNotificationUserInfoKey:self.file}]; 46 | }); 47 | } 48 | 49 | - (void)URLSession:(NSURLSession *)session 50 | downloadTask:(NSURLSessionDownloadTask *)downloadTask 51 | didFinishDownloadingToURL:(NSURL *)location { 52 | [FYFontCache cacheFile:self.file 53 | atLocation:location 54 | completionHandler:self.completionHandler]; 55 | } 56 | 57 | - (void)URLSession:(NSURLSession *)session 58 | task:(NSURLSessionDownloadTask *)task 59 | didCompleteWithError:(NSError *)error { 60 | [self.file resetWithDownloadTask:task]; 61 | 62 | if (error) { 63 | dispatch_async(dispatch_get_main_queue(), ^{ 64 | [[NSNotificationCenter defaultCenter] postNotificationName:FYFontFileDownloadingDidCompleteNotification 65 | object:nil 66 | userInfo:@{FYFontFileNotificationUserInfoKey:self.file}]; 67 | }); 68 | if (self.completionHandler) { 69 | self.completionHandler(error); 70 | } 71 | } 72 | } 73 | 74 | #pragma mark - KVO 75 | 76 | - (void)observeValueForKeyPath:(nullable NSString *)keyPath 77 | ofObject:(nullable id)object 78 | change:(nullable NSDictionary *)change 79 | context:(nullable void *)context { 80 | if ([object isKindOfClass:[NSURLSessionDownloadTask class]]) { 81 | [self.file resetWithDownloadTask:self.task]; 82 | if (self.progress) { 83 | self.progress(self.file); 84 | }; 85 | if (self.task.state != NSURLSessionTaskStateCompleted) { 86 | dispatch_async(dispatch_get_main_queue(), ^{ 87 | [[NSNotificationCenter defaultCenter] postNotificationName:FYFontFileDownloadStateDidChangeNotification 88 | object:nil 89 | userInfo:@{FYFontFileNotificationUserInfoKey:self.file}]; 90 | }); 91 | } 92 | } 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcuserdata/QQQ.xcuserdatad/xcschemes/Fonty-Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is Fonty? 2 | 3 | [Fonty](https://github.com/s2mh/Fonty) is a plugin that allows you to use third-party ttf, otf or ttc fonts in your iOS applications without bundling font files directly into the package. It was developed for use with heavy font files for pictographic languages, like Chinese and Japanese, but can be used with any font. 4 | 5 | Fonty can: 6 | - Download and cache fonts files from an external server 7 | - Register fonts 8 | - Clear cached files and unregister fonts 9 | 10 | # Demo 11 | 12 | ![](https://raw.githubusercontent.com/s2mh/Fonty/master/Screenshot/Fonty-Demo.gif) 13 | 14 | # How to use it 15 | 16 | ### Prepare URLs 17 | 18 | Upload font files to your preferred host and note the font file URL. For example, hosting Xingkai.ttc on Github might produce the URL: 19 | *https://github.com/s2mh/FontFile/raw/master/Chinese/Simplified%20Chinese/ttc/Xingkai.ttc*. 20 | 21 | ### Install 22 | 23 | There are two ways to call Fonty in your project: 24 | 25 | - using [CocoaPods](https://cocoapods.org/) 26 | ```ruby 27 | target 'TargetName' do 28 | pod 'Fonty', '~>2.0.0' 29 | end 30 | ``` 31 | - by cloning the Fonty directory into your repository 32 | 33 | 34 | ### Set URLs 35 | 36 | Tell FYFontManager( manages files and fonts) where to download the font files each time your app is launched: 37 | 38 | ```objective-c 39 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 40 | ... 41 | 42 | [FYFontManager setFileURLStrings:@[@"https://github.com/s2mh/FontFile/raw/master/Chinese/Simplified%20Chinese/ttc/Xingkai.ttc", 43 | @"https://github.com/s2mh/FontFile/raw/master/Common/Regular/YuppySC-Regular.otf", 44 | @"https://github.com/s2mh/FontFile/raw/master/English/Bold/Luminari.ttf", 45 | @"https://github.com/s2mh/FontFile/raw/master/Common/Bold/LiHeiPro.ttf"]]; 46 | 47 | return YES; 48 | } 49 | ``` 50 | 51 | This causes FYFontManager to generate the array FYFontFile: 52 | 53 | ```objective-c 54 | NSArray *fontFiles = [FYFontManager fontFiles]; 55 | ``` 56 | 57 | ### Download Files & Register Fonts 58 | 59 | To make FYFontManager download a font file: 60 | 61 | ```objective-c 62 | [FYFontManager downloadFontFile:file]; 63 | ``` 64 | FYFontManager will cache the file and register the fonts in it automatically. When the registration completes, the notification FYFontFileRegisterDidCompleteNotification will be posted. 65 | 66 | ```objective-c 67 | - (void)completeFile:(NSNotification *)notification { 68 | FYFontFile *file = [notification.userInfo objectForKey:FYFontFileNotificationUserInfoKey]; 69 | ... 70 | } 71 | ``` 72 | 73 | The file is associated with the notification. 74 | 75 | >Note:Each ttf or otf file contains only one font, a ttc file contains one or more fonts。 76 | 77 | ### Using Fonts in your App 78 | 79 | FYFontFile contains the array FYFontModel which represents a registered font. We can get the font from FYFontModel directly: 80 | 81 | ```objective-c 82 | FYFontModel *model = file.fontModels[0]; 83 | UIFont *font = [model.font fontWithSize:17.0]; 84 | ``` 85 | 86 | Another method is to set the main font in FYFontManager, and call it via a UIFont category from anywhere: 87 | 88 | ```objective-c 89 | [FYFontManager setMainFont:font]; 90 | ... 91 | 92 | textView.font = [UIFont fy_mainFontWithSize:17.0]; 93 | ``` 94 | 95 | ### Delete Files & Unregister Fonts 96 | 97 | Use FYFontManager to delete front files: 98 | 99 | ```objective-c 100 | [FYFontManager deleteFontFile:file]; 101 | ``` 102 | 103 | ### Archive 104 | 105 | To make Fonty remember your settings, archive FYFontManager before your app terminates: 106 | 107 | ```objective-c 108 | [FYFontManager archive]; 109 | ``` 110 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/xcuserdata/yanweichen.xcuserdatad/xcschemes/Fonty-Demo.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 | -------------------------------------------------------------------------------- /Fonty/FYFontCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontCache.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 16/7/2. 6 | // Copyright © 2016年 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FYFontCache.h" 11 | #import "FYFontFile.h" 12 | #import "FYFontManager.h" 13 | 14 | static NSString * const FYFontCacheDirectoryName = @"FYFont"; 15 | 16 | @implementation FYFontCache 17 | 18 | #pragma mark - Public 19 | 20 | + (BOOL)cacheObject:(id)object fileName:(NSString *)fileName { 21 | NSString *cachePath = [[self diskCacheDirectoryPath] stringByAppendingPathComponent:fileName]; 22 | NSData *cacheData = [NSKeyedArchiver archivedDataWithRootObject:object]; 23 | return [cacheData writeToFile:cachePath atomically:YES]; 24 | } 25 | 26 | + (id)objectFromCacheWithFileName:(NSString *)fileName { 27 | NSString *cachePath = [[self diskCacheDirectoryPath] stringByAppendingPathComponent:fileName]; 28 | NSData *cacheData = [NSData dataWithContentsOfFile:cachePath]; 29 | if (cacheData) { 30 | id obj = [NSKeyedUnarchiver unarchiveObjectWithData:cacheData]; 31 | return obj; 32 | } else { 33 | return nil; 34 | } 35 | } 36 | 37 | + (void)cacheFile:(FYFontFile *)file 38 | atLocation:(NSURL *)location 39 | completionHandler:(void(^)(NSError *))completionHandler { 40 | NSString *fileLocationName = [self filePathForSourceURLString:file.sourceURLString]; 41 | NSString *filePath = [[self diskCacheDirectoryPath] stringByAppendingPathComponent:fileLocationName]; 42 | NSError *error = nil; 43 | NSFileManager *fileManager = [NSFileManager defaultManager]; 44 | 45 | if ([fileManager fileExistsAtPath:filePath] && ![fileManager removeItemAtPath:filePath error:&error]) { 46 | goto completion; 47 | } 48 | 49 | if ([fileManager moveItemAtPath:location.path 50 | toPath:filePath 51 | error:&error]) { 52 | file.fileName = fileLocationName; 53 | file.localPath = filePath; 54 | } 55 | 56 | completion: 57 | dispatch_async(dispatch_get_main_queue(), ^{ 58 | [[NSNotificationCenter defaultCenter] postNotificationName:FYFontFileDownloadingDidCompleteNotification 59 | object:nil 60 | userInfo:@{FYFontFileNotificationUserInfoKey:file}]; 61 | }); 62 | 63 | if (completionHandler) { 64 | completionHandler(error); 65 | } 66 | } 67 | 68 | + (void)cleanCachedFile:(FYFontFile *)file completionHandler:(void(^)(NSError *))completionHandler { 69 | NSError *error = nil; 70 | [[NSFileManager defaultManager] removeItemAtPath:file.localPath error:&error]; 71 | 72 | dispatch_async(dispatch_get_main_queue(), ^{ 73 | [[NSNotificationCenter defaultCenter] postNotificationName:FYFontFileDeletingDidCompleteNotification 74 | object:nil 75 | userInfo:@{FYFontFileNotificationUserInfoKey:file}]; 76 | }); 77 | 78 | if (completionHandler) { 79 | completionHandler(error); 80 | } 81 | } 82 | 83 | + (NSString *)diskCacheDirectoryPath { 84 | static NSString *_diskCacheDirectoryPath; 85 | if (!_diskCacheDirectoryPath) { 86 | NSFileManager *fileManager = [NSFileManager defaultManager]; 87 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 88 | 89 | _diskCacheDirectoryPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:FYFontCacheDirectoryName]; 90 | NSError *error = nil; 91 | [fileManager createDirectoryAtPath:_diskCacheDirectoryPath 92 | withIntermediateDirectories:YES 93 | attributes:nil 94 | error:&error]; 95 | } 96 | return _diskCacheDirectoryPath; 97 | } 98 | 99 | #pragma mark - Private 100 | 101 | + (NSString *)filePathForSourceURLString:(NSString *)URLString { 102 | const char *str = [URLString UTF8String]; 103 | if (str == NULL) { 104 | return @""; 105 | } 106 | unsigned char r[CC_MD5_DIGEST_LENGTH]; 107 | CC_MD5(str, (CC_LONG)strlen(str), r); 108 | return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 109 | r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], 110 | r[11], r[12], r[13], r[14], r[15]]; 111 | } 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /Fonty-Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 汉字 45 | 46 | English 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /Fonty.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint Fonty.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "Fonty" 19 | s.version = "2.0.0" 20 | s.summary = "A thirdparty font management framework for iOS apps." 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | Use Fonty to download, cache and register your font from web. 29 | DESC 30 | 31 | s.homepage = "https://github.com/s2mh/Fonty" 32 | s.screenshots = "https://github.com/s2mh/Fonty/raw/master/Screenshot/Fonty-Demo.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | s.license = "MIT" 43 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | s.author = { "" => "s2mh@qq.com" } 57 | # Or just: s.author = "" 58 | # s.authors = { "" => "s2mh@qq.com" } 59 | # s.social_media_url = "http://twitter.com/" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | # s.platform = :ios 68 | s.platform = :ios, "8.0" 69 | 70 | # When using multiple platforms 71 | # s.ios.deployment_target = "5.0" 72 | # s.osx.deployment_target = "10.7" 73 | # s.watchos.deployment_target = "2.0" 74 | # s.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | s.source = { :git => "https://github.com/s2mh/Fonty.git", :tag => "#{s.version}" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | s.source_files = "Fonty/*.{h,m}" 95 | # s.source_files = "Classes", "Classes/**/*.{h,m}" 96 | # s.exclude_files = "Classes/Exclude" 97 | 98 | s.public_header_files = "Fonty/*.{h}" 99 | 100 | 101 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 102 | # 103 | # A list of resources included with the Pod. These are copied into the 104 | # target bundle with a build phase script. Anything else will be cleaned. 105 | # You can preserve files from being cleaned, please don't preserve 106 | # non-essential files like tests, examples and documentation. 107 | # 108 | 109 | # s.resource = "icon.png" 110 | # s.resources = "Resources/*.png" 111 | 112 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 113 | 114 | 115 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 116 | # 117 | # Link your library with frameworks, or libraries. Libraries do not include 118 | # the lib prefix of their name. 119 | # 120 | 121 | # s.framework = "SomeFramework" 122 | # s.frameworks = "SomeFramework", "AnotherFramework" 123 | 124 | # s.library = "iconv" 125 | # s.libraries = "iconv", "xml2" 126 | 127 | 128 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 129 | # 130 | # If your library depends on compiler flags you can set them in the xcconfig hash 131 | # where they will only apply to your library. If you depend on other Podspecs 132 | # you can include multiple dependencies to ensure it works. 133 | 134 | # s.requires_arc = true 135 | 136 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 137 | # s.dependency "JSONKit", "~> 1.4" 138 | 139 | end 140 | -------------------------------------------------------------------------------- /Fonty/FYFontDownloader.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontDownloader.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import "FYFontDownloader.h" 10 | #import "FYFontCache.h" 11 | #import "FYFontFile.h" 12 | #import "FYDownloadDelegate.h" 13 | 14 | @interface FYFontDownloader () 15 | 16 | @property (nonatomic, strong) NSURLSession *session; 17 | @property (nonatomic, strong) NSLock *lock; 18 | @property (nonatomic, strong) NSMutableDictionary *delegates; 19 | 20 | @end 21 | 22 | @implementation FYFontDownloader 23 | 24 | - (void)downloadFontFile:(FYFontFile *)file 25 | progress:(void(^)(FYFontFile *file))progress 26 | completionHandler:(void(^)(NSError *))completionHandler { 27 | NSURLSessionDownloadTask *downloadTask = file.downloadTask; 28 | if (!downloadTask) { 29 | downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:file.sourceURLString]]; 30 | 31 | FYDownloadDelegate *delegate = [[FYDownloadDelegate alloc] initWithTask:downloadTask]; 32 | delegate.progress = progress; 33 | delegate.completionHandler = completionHandler; 34 | delegate.file = file; 35 | 36 | [self setDelegate:delegate forTask:downloadTask]; 37 | } 38 | if (downloadTask && (downloadTask.state == NSURLSessionTaskStateSuspended)) { 39 | [downloadTask resume]; 40 | } 41 | } 42 | 43 | 44 | - (void)cancelDownloadingFile:(FYFontFile *)file { 45 | NSURLSessionDownloadTask *downloadTask = file.downloadTask; 46 | if (downloadTask && (downloadTask.state == NSURLSessionTaskStateRunning || downloadTask.state == NSURLSessionTaskStateSuspended)) { 47 | [downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {}]; 48 | } 49 | } 50 | 51 | - (void)suspendDownloadFile:(FYFontFile *)file { 52 | NSURLSessionDownloadTask *downloadTask = file.downloadTask; 53 | if (downloadTask && (downloadTask.state == NSURLSessionTaskStateRunning)) { 54 | [downloadTask suspend]; 55 | } 56 | } 57 | 58 | #pragma mark - NSURLSessionDownloadDelegate 59 | 60 | - (void)URLSession:(NSURLSession *)session 61 | downloadTask:(NSURLSessionDownloadTask *)downloadTask 62 | didWriteData:(int64_t)bytesWritten 63 | totalBytesWritten:(int64_t)totalBytesWritten 64 | totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { 65 | FYDownloadDelegate *delegate = [self delegateForTask:downloadTask]; 66 | if (delegate) { 67 | [delegate URLSession:session 68 | downloadTask:downloadTask 69 | didWriteData:bytesWritten 70 | totalBytesWritten:totalBytesWritten 71 | totalBytesExpectedToWrite:totalBytesExpectedToWrite]; 72 | } 73 | } 74 | 75 | - (void)URLSession:(NSURLSession *)session 76 | downloadTask:(NSURLSessionDownloadTask *)downloadTask 77 | didFinishDownloadingToURL:(NSURL *)location { 78 | FYDownloadDelegate *delegate = [self delegateForTask:downloadTask]; 79 | if (delegate) { 80 | [delegate URLSession:session 81 | downloadTask:downloadTask 82 | didFinishDownloadingToURL:location]; 83 | } 84 | } 85 | 86 | - (void)URLSession:(NSURLSession *)session 87 | task:(NSURLSessionDownloadTask *)task 88 | didCompleteWithError:(NSError *)error { 89 | FYDownloadDelegate *delegate = [self delegateForTask:task]; 90 | if (delegate) { 91 | [delegate URLSession:session 92 | task:task 93 | didCompleteWithError:error]; 94 | [self removeDelegateForTask:task]; 95 | } 96 | } 97 | 98 | #pragma mark - Private 99 | 100 | - (FYDownloadDelegate *)delegateForTask:(NSURLSessionTask *)task { 101 | NSParameterAssert(task); 102 | 103 | FYDownloadDelegate *delegate = nil; 104 | [self.lock lock]; 105 | delegate = self.delegates[@(task.taskIdentifier)]; 106 | [self.lock unlock]; 107 | 108 | return delegate; 109 | } 110 | 111 | - (void)setDelegate:(FYDownloadDelegate *)delegate 112 | forTask:(NSURLSessionTask *)task 113 | { 114 | NSParameterAssert(task); 115 | NSParameterAssert(delegate); 116 | 117 | [self.lock lock]; 118 | self.delegates[@(task.taskIdentifier)] = delegate; 119 | [task addObserver:delegate 120 | forKeyPath:@"state" 121 | options:NSKeyValueObservingOptionNew 122 | context:NULL]; 123 | [self.lock unlock]; 124 | } 125 | 126 | - (void)removeDelegateForTask:(NSURLSessionTask *)task { 127 | NSParameterAssert(task); 128 | 129 | [self.lock lock]; 130 | [task removeObserver:self.delegates[@(task.taskIdentifier)] forKeyPath:@"state"]; 131 | [self.delegates removeObjectForKey:@(task.taskIdentifier)]; 132 | [self.lock unlock]; 133 | } 134 | 135 | #pragma mark - Accessor 136 | 137 | - (NSURLSession *)session { 138 | if (!_session) { 139 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 140 | _session = [NSURLSession sessionWithConfiguration:configuration 141 | delegate:self 142 | delegateQueue:nil]; 143 | } 144 | return _session; 145 | } 146 | 147 | - (NSLock *)lock { 148 | if (!_lock) { 149 | _lock = [[NSLock alloc] init]; 150 | } 151 | return _lock; 152 | } 153 | 154 | - (NSMutableDictionary *)delegates { 155 | if (!_delegates) { 156 | _delegates = [NSMutableDictionary dictionary]; 157 | } 158 | return _delegates; 159 | } 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /Fonty/FYFontFile.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontFile.m 3 | // Fonty-Demo 4 | // 5 | // Created by QQQ on 17/3/27. 6 | // Copyright © 2017年 s2mh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "FYFontFile.h" 12 | #import "FYFontCache.h" 13 | #import "FYFontRegister.h" 14 | #import "FYFontDownloader.h" 15 | #import "FYFontManager.h" 16 | 17 | @interface FYFontFile () 18 | 19 | @property (nonatomic, copy, readwrite) NSString *sourceURLString; 20 | @property (nonatomic, assign, readwrite) FYFontFileDownloadState downloadStatus; 21 | @property (nonatomic, assign, readwrite) int64_t fileSize; 22 | @property (nonatomic, assign, readwrite) int64_t fileDownloadedSize; 23 | @property (nonatomic, assign, readwrite) double downloadProgress; 24 | @property (nonatomic, assign, readwrite) BOOL fileSizeUnknown; 25 | @property (nonatomic, copy, readwrite) NSError *downloadError; 26 | @property (nonatomic, strong) NSLock *lock; 27 | @property (nonatomic, weak, readwrite) NSURLSessionDownloadTask *downloadTask; 28 | 29 | @end 30 | 31 | @implementation FYFontFile 32 | 33 | - (instancetype)initWithSourceURLString:(NSString *)sourceURLString { 34 | self = [super init]; 35 | if (self) { 36 | _sourceURLString = sourceURLString; 37 | _downloadStatus = FYFontFileDownloadStateToBeDownloaded; 38 | _registered = NO; 39 | _lock = [[NSLock alloc] init]; 40 | } 41 | return self; 42 | } 43 | 44 | - (instancetype)initWithCoder:(NSCoder *)decoder { 45 | self = [super init]; 46 | if (!self) { 47 | return nil; 48 | } 49 | _sourceURLString = [decoder decodeObjectForKey:@"_sourceURLString"]; 50 | _fileName = [decoder decodeObjectForKey:@"_fileName"]; 51 | _localPath = [[FYFontCache diskCacheDirectoryPath] stringByAppendingPathComponent:_fileName]; 52 | _downloadStatus = [decoder decodeIntegerForKey:@"_downloadStatus"]; 53 | _fileSize = [decoder decodeInt64ForKey:@"_fileSize"]; 54 | _downloadProgress = [decoder decodeDoubleForKey:@"_downloadProgress"]; 55 | _registered = NO; 56 | _lock = [[NSLock alloc] init]; 57 | if (_downloadStatus == FYFontFileDownloadStateDownloaded) { 58 | _registered = [FYFontRegister registerFontInFile:self]; 59 | if (!_registered) { 60 | [self clear]; 61 | } 62 | } 63 | return self; 64 | } 65 | 66 | - (void)encodeWithCoder:(NSCoder *)encoder { 67 | [encoder encodeObject:_sourceURLString forKey:@"_sourceURLString"]; 68 | [encoder encodeObject:_fileName forKey:@"_fileName"]; 69 | if ((_downloadStatus == FYFontFileDownloadStateSuspended) || (_downloadStatus == FYFontFileDownloadStateDownloading)) { 70 | _downloadStatus = FYFontFileDownloadStateToBeDownloaded; 71 | } 72 | [encoder encodeInteger:_downloadStatus forKey:@"_downloadStatus"]; 73 | [encoder encodeInt64:_fileSize forKey:@"_fileSize"]; 74 | [encoder encodeDouble:_downloadProgress forKey:@"_downloadProgress"]; 75 | [encoder encodeBool:_registered forKey:@"_registered"]; 76 | [encoder encodeObject:_fontModels forKey:@"_fontModels"]; 77 | } 78 | 79 | #pragma mark - Public 80 | 81 | - (void)clear { 82 | [self.lock lock]; 83 | self.localPath = nil; 84 | self.fileName = nil; 85 | self.registered = NO; 86 | self.downloadProgress = 0.0; 87 | self.downloadStatus = FYFontFileDownloadStateToBeDownloaded; 88 | self.fontModels = nil; 89 | [self.lock unlock]; 90 | } 91 | 92 | - (void)resetWithDownloadTask:(NSURLSessionDownloadTask *)downloadTask { 93 | [self.lock lock]; 94 | 95 | _downloadTask = downloadTask; 96 | 97 | _fileSize = _downloadTask.countOfBytesExpectedToReceive; 98 | _fileDownloadedSize = _downloadTask.countOfBytesReceived; 99 | _fileSizeUnknown = (_fileSize == NSURLSessionTransferSizeUnknown); 100 | _downloadError = _downloadTask.error; 101 | _downloadProgress = 0.0; 102 | 103 | switch (_downloadTask.state) { 104 | case NSURLSessionTaskStateRunning: { 105 | _downloadStatus = FYFontFileDownloadStateDownloading; 106 | } break; 107 | 108 | case NSURLSessionTaskStateSuspended: { 109 | _downloadStatus = FYFontFileDownloadStateSuspended; 110 | } break; 111 | 112 | case NSURLSessionTaskStateCanceling: { 113 | _downloadStatus = FYFontFileDownloadStateToBeDownloaded; 114 | _fileDownloadedSize = 0.0; 115 | } break; 116 | 117 | case NSURLSessionTaskStateCompleted: { 118 | if (_downloadError) { 119 | _downloadStatus = FYFontFileDownloadStateToBeDownloaded; 120 | _fileDownloadedSize = 0.0; 121 | } else { 122 | _downloadStatus = FYFontFileDownloadStateDownloaded; 123 | } 124 | } break; 125 | } 126 | 127 | if (!_fileSizeUnknown) { 128 | double downloadProgress = (double)_fileDownloadedSize / _fileSize; 129 | if ((downloadProgress > _downloadProgress) || (_downloadStatus == FYFontFileDownloadStateToBeDownloaded)) { 130 | _downloadProgress = downloadProgress; 131 | } 132 | } 133 | [self.lock unlock]; 134 | } 135 | 136 | @end 137 | 138 | @implementation FYFontModel 139 | 140 | - (instancetype)initWithCoder:(NSCoder *)decoder { 141 | self = [super init]; 142 | if (!self) { 143 | return nil; 144 | } 145 | _postScriptName = [decoder decodeObjectForKey:@"_postScriptName"]; 146 | return self; 147 | } 148 | 149 | - (void)encodeWithCoder:(NSCoder *)encoder { 150 | [encoder encodeObject:_postScriptName forKey:@"_postScriptName"]; 151 | } 152 | 153 | - (NSString *)description 154 | { 155 | return [NSString stringWithFormat:@"%@", self.postScriptName]; 156 | } 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /Fonty-Demo/FYSelectFontTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYSelectFontTableViewCell.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import "FYSelectFontTableViewCell.h" 10 | 11 | static const CGFloat StripeWidth = 20.0f; 12 | 13 | @interface FYSelectFontTableViewCell () 14 | 15 | @property (nonatomic, strong) CALayer *stripesLayer; 16 | @property (nonatomic, strong) CAShapeLayer *progressLayer; 17 | 18 | @end 19 | 20 | @implementation FYSelectFontTableViewCell 21 | 22 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 23 | self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; 24 | if (self) { 25 | self.selectionStyle = UITableViewCellSelectionStyleNone; 26 | _striped = NO; 27 | _pauseStripes = NO; 28 | self.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)layoutSubviews { 34 | [super layoutSubviews]; 35 | if (self.downloadProgress == 1.0f) { 36 | [_stripesLayer removeFromSuperlayer]; 37 | [_progressLayer removeFromSuperlayer]; 38 | return; 39 | } 40 | if (self.striped) { 41 | [_progressLayer removeFromSuperlayer]; 42 | [self.layer addSublayer:self.stripesLayer]; 43 | if (self.pauseStripes) { 44 | [self pauseLayer:self.stripesLayer]; 45 | } else { 46 | [self resumeLayer:self.stripesLayer]; 47 | } 48 | } else { 49 | [_stripesLayer removeFromSuperlayer]; 50 | [self.layer addSublayer:self.progressLayer]; 51 | if (self.pauseStripes) { 52 | [self resumeLayer:self.progressLayer]; 53 | } else { 54 | [self pauseLayer:self.progressLayer]; 55 | } 56 | } 57 | } 58 | 59 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 60 | [super setSelected:selected animated:animated]; 61 | if (selected) { 62 | self.accessoryType = UITableViewCellAccessoryCheckmark; 63 | } else { 64 | self.accessoryType = UITableViewCellAccessoryNone; 65 | } 66 | } 67 | 68 | #pragma mark - Private 69 | 70 | - (void)pauseLayer:(CALayer *)layer { 71 | if (layer.speed == 0.0f) { 72 | return; 73 | } 74 | CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; 75 | layer.speed = 0.0f; 76 | layer.timeOffset = pausedTime; 77 | } 78 | 79 | - (void)resumeLayer:(CALayer *)layer { 80 | if (layer.speed != 0.0f) { 81 | return; 82 | } 83 | CFTimeInterval pausedTime = [layer timeOffset]; 84 | layer.speed = 1.0f; 85 | layer.timeOffset = 0.0f; 86 | layer.beginTime = 0.0; 87 | CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; 88 | layer.beginTime = timeSincePause; 89 | } 90 | 91 | #pragma mark - Accessor 92 | 93 | - (CALayer *)stripesLayer { 94 | if (!_stripesLayer) { 95 | _stripesLayer = [CAShapeLayer layer]; 96 | _stripesLayer.frame = CGRectMake(0.0f, 0.0f, self.bounds.size.width + (4 * StripeWidth), self.bounds.size.height); 97 | _stripesLayer.opacity = 0.5f; 98 | 99 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(StripeWidth * 4, StripeWidth * 4), NO, [UIScreen mainScreen].scale); 100 | //Fill the background 101 | [[UIColor clearColor] setFill]; 102 | UIBezierPath *fillPath = [UIBezierPath bezierPathWithRect:CGRectMake(0.0f, 0.0f, StripeWidth * 4, StripeWidth * 4)]; 103 | [fillPath fill]; 104 | //Draw the stripes 105 | [[UIColor grayColor] setFill]; 106 | for (int i = 0; i < 4; i++) { 107 | //Create the four inital points of the fill shape 108 | CGPoint bottomLeft = CGPointMake(-(StripeWidth * 4), StripeWidth * 4); 109 | CGPoint topLeft = CGPointMake(0.0f, 0.0f); 110 | CGPoint topRight = CGPointMake(StripeWidth, 0.0f); 111 | CGPoint bottomRight = CGPointMake(-(StripeWidth * 4) + StripeWidth, StripeWidth * 4); 112 | //Shift all four points as needed to draw all four stripes 113 | bottomLeft.x += i * (2.0f * StripeWidth); 114 | topLeft.x += i * (2.0f * StripeWidth); 115 | topRight.x += i * (2.0f * StripeWidth); 116 | bottomRight.x += i * (2.0f * StripeWidth); 117 | //Create the fill path 118 | UIBezierPath *path = [UIBezierPath bezierPath]; 119 | [path moveToPoint:bottomLeft]; 120 | [path addLineToPoint:topLeft]; 121 | [path addLineToPoint:topRight]; 122 | [path addLineToPoint:bottomRight]; 123 | [path closePath]; 124 | [path fill]; 125 | } 126 | //Retreive the image 127 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 128 | UIGraphicsEndImageContext(); 129 | //Set the background of the progress layer 130 | _stripesLayer.backgroundColor = [UIColor colorWithPatternImage:image].CGColor; 131 | 132 | CABasicAnimation *stripedAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 133 | stripedAnimation.duration = 0.6f; 134 | stripedAnimation.repeatCount = HUGE_VALF; 135 | stripedAnimation.removedOnCompletion = NO; 136 | stripedAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(- (2 * StripeWidth) + (self.bounds.size.width / 2.0f), self.bounds.size.height / 2.0f)]; 137 | stripedAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0 + (self.bounds.size.width / 2.0f), self.bounds.size.height / 2.0f)]; 138 | 139 | [_stripesLayer addAnimation:stripedAnimation forKey:@"stripedAnimation"]; 140 | } 141 | return _stripesLayer; 142 | } 143 | 144 | - (CAShapeLayer *)progressLayer { 145 | if (!_progressLayer) { 146 | _progressLayer = [CAShapeLayer layer]; 147 | _progressLayer.fillColor = [UIColor grayColor].CGColor; 148 | _progressLayer.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; 149 | _progressLayer.opacity = 0.5f; 150 | 151 | CABasicAnimation *flicker = [CABasicAnimation animationWithKeyPath:@"fillColor"]; 152 | flicker.duration = 0.95; 153 | flicker.repeatCount = HUGE_VALF; 154 | flicker.removedOnCompletion = NO; 155 | flicker.autoreverses = YES; 156 | flicker.toValue = (id)[UIColor lightGrayColor].CGColor; 157 | flicker.fromValue = (id)[UIColor grayColor].CGColor; 158 | [_progressLayer addAnimation:flicker forKey:@"flicker"]; 159 | } 160 | return _progressLayer; 161 | } 162 | 163 | - (void)setDownloadProgress:(double)downloadProgress { 164 | if (_downloadProgress != downloadProgress) { 165 | _downloadProgress = downloadProgress; 166 | CGRect frame = self.bounds; 167 | CGFloat width = frame.size.width; 168 | frame.origin.x = width * downloadProgress; 169 | frame.size.width = width * (1.0f - downloadProgress); 170 | _progressLayer.path = [UIBezierPath bezierPathWithRect:frame].CGPath; 171 | } 172 | } 173 | 174 | @end 175 | -------------------------------------------------------------------------------- /Fonty/FYFontManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYFontManager.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 16/7/2. 6 | // Copyright © 2016年 颜为晨. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "FYFontManager.h" 13 | #import "FYFontFile.h" 14 | #import "FYFontCache.h" 15 | #import "FYFontRegister.h" 16 | #import "FYFontDownloader.h" 17 | 18 | NSString *const FYFontFileDownloadingNotification = @"FYFontFileDownloadingNotification"; 19 | NSString *const FYFontFileDownloadStateDidChangeNotification = @"FYFontFileDownloadStateDidChangeNotification"; 20 | NSString *const FYFontFileDownloadingDidCompleteNotification = @"FYFontFileDownloadingDidCompleteNotification"; 21 | NSString *const FYFontFileRegisteringDidCompleteNotification = @"FYFontFileRegisteringDidCompleteNotification"; 22 | NSString *const FYFontFileDeletingDidCompleteNotification = @"FYFontFileDeletingDidCompleteNotification"; 23 | NSString *const FYFontFileNotificationUserInfoKey = @"FYFontFileNotificationUserInfoKey"; 24 | static NSString *const FYFontSharedManagerName = @"FYFontSharedManagerName"; 25 | 26 | @interface FYFontManager () 27 | 28 | @property (nonatomic, strong) FYFontDownloader *downloader; 29 | @property (nonatomic, copy) NSArray *URLStrings; 30 | @property (nonatomic, copy) NSArray *fontFiles; 31 | @property (nonatomic, weak) FYFontFile *mainFontFile; 32 | @property (nonatomic, copy) NSString *mainFontName; 33 | @property (nonatomic, strong) UIFont *mainFont; 34 | 35 | @end 36 | 37 | @implementation FYFontManager 38 | 39 | + (instancetype)sharedManager { 40 | static FYFontManager *manager; 41 | static dispatch_once_t onceToken; 42 | dispatch_once(&onceToken, ^{ 43 | manager = (FYFontManager *)[FYFontCache objectFromCacheWithFileName:FYFontSharedManagerName]; 44 | if (!manager) { 45 | manager = [self new]; 46 | } 47 | }); 48 | return manager; 49 | } 50 | 51 | - (instancetype)initWithCoder:(NSCoder *)decoder { 52 | self = [super init]; 53 | if (!self) { 54 | return nil; 55 | } 56 | _URLStrings = [decoder decodeObjectForKey:@"_URLStrings"]; 57 | _fontFiles = [decoder decodeObjectForKey:@"_fontFiles"]; 58 | _mainFontName = [decoder decodeObjectForKey:@"_mainFontName"]; 59 | return self; 60 | } 61 | 62 | - (void)encodeWithCoder:(NSCoder *)encoder { 63 | [encoder encodeObject:_URLStrings forKey:@"_URLStrings"]; 64 | [encoder encodeObject:_fontFiles forKey:@"_fontFiles"]; 65 | [encoder encodeObject:_mainFontName forKey:@"_mainFontName"]; 66 | } 67 | 68 | #pragma mark - Private 69 | 70 | - (void)archiveSelf { 71 | [FYFontCache cacheObject:self fileName:FYFontSharedManagerName]; 72 | } 73 | 74 | #pragma mark - Public 75 | 76 | + (void)archive { 77 | [[FYFontManager sharedManager] archiveSelf]; 78 | } 79 | 80 | + (void)downloadFontFile:(FYFontFile *)file { 81 | [self downloadFontFile:file progress:nil completionHandler:nil]; 82 | } 83 | 84 | + (void)downloadFontFile:(FYFontFile *)file progress:(void(^)(FYFontFile *file))progress completionHandler:(void(^)(NSError *error))completionHandler { 85 | FYFontManager *sharedManager = [FYFontManager sharedManager]; 86 | [sharedManager.downloader downloadFontFile:file 87 | progress:^(FYFontFile *file) { 88 | dispatch_async(dispatch_get_main_queue(), ^{ 89 | if (progress) { 90 | progress(file); 91 | } 92 | }); 93 | } 94 | completionHandler:^(NSError *error) { 95 | if (!error) { 96 | [FYFontRegister registerFontInFile:file]; 97 | } 98 | dispatch_async(dispatch_get_main_queue(), ^{ 99 | if (completionHandler) { 100 | completionHandler(error); 101 | } 102 | }); 103 | }]; 104 | } 105 | 106 | + (void)cancelDownloadingFontFile:(FYFontFile *)file { 107 | FYFontManager *sharedManager = [FYFontManager sharedManager]; 108 | [sharedManager.downloader cancelDownloadingFile:file]; 109 | } 110 | 111 | + (void)pauseDownloadingFile:(FYFontFile *)file { 112 | FYFontManager *sharedManager = [FYFontManager sharedManager]; 113 | [sharedManager.downloader suspendDownloadFile:file]; 114 | } 115 | 116 | 117 | + (void)deleteFontFile:(FYFontFile *)file{ 118 | [self deleteFontFile:file completionHandler:nil]; 119 | } 120 | 121 | + (void)deleteFontFile:(FYFontFile *)file completionHandler:(void(^)(NSError *))completionHandler { 122 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 123 | dispatch_async(queue, ^{ 124 | [FYFontRegister unregisterFontInFile:file]; 125 | [FYFontCache cleanCachedFile:file completionHandler:^(NSError *error) { 126 | UIFont *mainFont = [FYFontManager mainFont]; 127 | for (FYFontModel *model in file.fontModels) { 128 | if ([model.font isEqual:mainFont]) { 129 | [FYFontManager setMainFont:nil]; 130 | break; 131 | } 132 | } 133 | [file clear]; 134 | dispatch_async(dispatch_get_main_queue(), ^{ 135 | if (completionHandler) { 136 | completionHandler(error); 137 | } 138 | }); 139 | }]; 140 | }); 141 | } 142 | 143 | + (BOOL)registerFontFile:(FYFontFile *)file { 144 | return [FYFontRegister registerFontInFile:file]; 145 | } 146 | 147 | + (NSArray *)fileURLStrings { 148 | return [[FYFontManager sharedManager] URLStrings]; 149 | } 150 | 151 | + (void)setFileURLStrings:(NSArray *)fileURLStrings { 152 | FYFontManager *sharedManager = [FYFontManager sharedManager]; 153 | if (fileURLStrings != sharedManager.URLStrings) { 154 | NSArray *oldFontFiles = sharedManager.fontFiles; 155 | NSArray *oldSourceURLStrings = [oldFontFiles valueForKey:@"sourceURLString"]; 156 | 157 | NSMutableArray *fontFiles = [NSMutableArray array]; 158 | [fileURLStrings enumerateObjectsUsingBlock:^(NSString * _Nonnull URLString, NSUInteger idx, BOOL * _Nonnull stop) { 159 | NSUInteger index = [oldSourceURLStrings indexOfObject:URLString]; 160 | if (!oldSourceURLStrings || index == NSNotFound) { 161 | FYFontFile *file = [[FYFontFile alloc] initWithSourceURLString:URLString]; 162 | [fontFiles addObject:file]; 163 | } else { 164 | FYFontFile *file = oldFontFiles[index]; 165 | [fontFiles addObject:file]; 166 | if ((file.downloadStatus == FYFontFileDownloadStateDownloaded) && 167 | [file.fileName isEqualToString:sharedManager.mainFontName]) { 168 | sharedManager.mainFontFile = file; 169 | } 170 | } 171 | }]; 172 | 173 | sharedManager.fontFiles = fontFiles; 174 | sharedManager.URLStrings = fileURLStrings; 175 | } 176 | } 177 | 178 | + (NSArray *)fontFiles { 179 | return [[FYFontManager sharedManager] fontFiles]; 180 | } 181 | 182 | #pragma mark - Accessor 183 | 184 | + (UIFont *)mainFont { 185 | FYFontManager *sharedManager = [FYFontManager sharedManager]; 186 | if (!sharedManager.mainFont) { 187 | if (sharedManager.mainFontFile) { 188 | [FYFontRegister registerFontInFile:sharedManager.mainFontFile]; 189 | sharedManager.mainFont = [UIFont fontWithName:sharedManager.mainFontName size:17.0]; 190 | } else { 191 | sharedManager.mainFont = [UIFont systemFontOfSize:17.0]; 192 | } 193 | } 194 | return sharedManager.mainFont; 195 | } 196 | 197 | + (void)setMainFont:(UIFont *)mainFont { 198 | FYFontManager *sharedManager = [FYFontManager sharedManager]; 199 | sharedManager.mainFont = mainFont; 200 | sharedManager.mainFontName = mainFont.fontName; 201 | } 202 | 203 | - (FYFontDownloader *)downloader { 204 | if (!_downloader) { 205 | _downloader = [[FYFontDownloader alloc] init]; 206 | } 207 | return _downloader; 208 | } 209 | 210 | @end 211 | -------------------------------------------------------------------------------- /Fonty-Demo/FYSelectFontViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FYSelectFontViewController.m 3 | // Fonty 4 | // 5 | // Created by 颜为晨 on 9/9/16. 6 | // Copyright © 2016 颜为晨. All rights reserved. 7 | // 8 | 9 | #import "FYSelectFontViewController.h" 10 | 11 | #import "FYSelectFontTableViewCell.h" 12 | 13 | #import "Fonty.h" 14 | 15 | @interface FYSelectFontViewController () 16 | 17 | @property (weak, nonatomic) NSArray *fontFiles; 18 | 19 | @end 20 | 21 | @implementation FYSelectFontViewController 22 | 23 | - (instancetype)initWithStyle:(UITableViewStyle)style { 24 | self = [super initWithStyle:style]; 25 | if (!self) { 26 | return nil; 27 | } 28 | self.navigationItem.title = @"Fonty"; 29 | [self setupBarItems]; 30 | self.fontFiles = [FYFontManager fontFiles]; 31 | 32 | return self; 33 | } 34 | 35 | - (void)viewDidLoad { 36 | [super viewDidLoad]; 37 | [self.tableView registerClass:[FYSelectFontTableViewCell class] forCellReuseIdentifier:@"FYSelectFontTableViewCell"]; 38 | } 39 | 40 | - (void)viewWillAppear:(BOOL)animated { 41 | [super viewWillAppear:animated]; 42 | [[NSNotificationCenter defaultCenter] addObserver:self 43 | selector:@selector(layoutCellWithNotification:) 44 | name:FYFontFileDownloadingNotification 45 | object:nil]; 46 | [[NSNotificationCenter defaultCenter] addObserver:self 47 | selector:@selector(layoutCellWithNotification:) 48 | name:FYFontFileDownloadStateDidChangeNotification object:nil]; 49 | [[NSNotificationCenter defaultCenter] addObserver:self 50 | selector:@selector(reloadRowWithNotification:) 51 | name:FYFontFileRegisteringDidCompleteNotification 52 | object:nil]; 53 | [[NSNotificationCenter defaultCenter] addObserver:self 54 | selector:@selector(reloadRowWithNotification:) 55 | name:FYFontFileDeletingDidCompleteNotification 56 | object:nil]; 57 | [self setupSelection]; 58 | } 59 | 60 | - (void)viewWillDisappear:(BOOL)animated { 61 | [super viewWillDisappear:animated]; 62 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 63 | [FYFontManager archive]; 64 | } 65 | 66 | #pragma mark - UITableViewDataSource 67 | 68 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 69 | return self.fontFiles.count; 70 | } 71 | 72 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 73 | FYFontFile *file = self.fontFiles[section]; 74 | return (file.registered) ? file.fontModels.count : 1; 75 | } 76 | 77 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 78 | FYSelectFontTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FYSelectFontTableViewCell" forIndexPath:indexPath]; 79 | FYFontFile *file = self.fontFiles[indexPath.section]; 80 | if (file.registered) { 81 | FYFontModel *model = file.fontModels[indexPath.row]; 82 | [self assembleCell:cell withModel:model]; 83 | } else { 84 | [self assembleCell:cell withFile:file]; 85 | } 86 | return cell; 87 | } 88 | 89 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 90 | FYFontFile *file = self.fontFiles[indexPath.section]; 91 | return (file.downloadStatus == FYFontFileDownloadStateDownloaded); 92 | } 93 | 94 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 95 | if (editingStyle == UITableViewCellEditingStyleDelete) { 96 | FYFontFile *file = self.fontFiles[indexPath.section]; 97 | [FYFontManager deleteFontFile:file]; 98 | } 99 | } 100 | 101 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 102 | return [NSString stringWithFormat:@"Font file %ld", (long)section + 1]; 103 | } 104 | 105 | #pragma mark UITableViewDelegate 106 | 107 | - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { 108 | FYFontFile *file = self.fontFiles[indexPath.section]; 109 | switch (file.downloadStatus) { 110 | case FYFontFileDownloadStateToBeDownloaded: { 111 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Download Font File From" 112 | message:file.sourceURLString 113 | preferredStyle:UIAlertControllerStyleAlert]; 114 | [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" 115 | style:UIAlertActionStyleCancel 116 | handler:nil]]; 117 | [alertController addAction:[UIAlertAction actionWithTitle:@"Start" 118 | style:UIAlertActionStyleDefault 119 | handler:^(UIAlertAction * _Nonnull action) { 120 | [FYFontManager downloadFontFile:file]; 121 | }]]; 122 | [self presentViewController:alertController animated:YES completion:nil]; 123 | } 124 | break; 125 | 126 | case FYFontFileDownloadStateDownloading: { 127 | [FYFontManager pauseDownloadingFile:file]; 128 | } 129 | break; 130 | 131 | case FYFontFileDownloadStateSuspended: { 132 | [FYFontManager downloadFontFile:file]; 133 | } 134 | break; 135 | 136 | case FYFontFileDownloadStateDownloaded: { 137 | if (file.registered) { 138 | FYFontModel *model = file.fontModels[indexPath.row]; 139 | UIFont *font = model.font; 140 | if ([font.fontName isEqualToString:[FYFontManager mainFont].fontName]) { 141 | [FYFontManager setMainFont:nil]; 142 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 143 | } else { 144 | [FYFontManager setMainFont:font]; 145 | return indexPath; 146 | } 147 | } else { 148 | if (![FYFontManager registerFontFile:file]) { 149 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Can not register this font file!" 150 | message:nil 151 | preferredStyle:UIAlertControllerStyleAlert]; 152 | [alertController addAction:[UIAlertAction actionWithTitle:@"OK" 153 | style:UIAlertActionStyleDefault 154 | handler:nil]]; 155 | [self presentViewController:alertController animated:YES completion:nil]; 156 | } else { 157 | [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] 158 | withRowAnimation:UITableViewRowAnimationAutomatic]; 159 | } 160 | } 161 | } 162 | break; 163 | 164 | default: 165 | break; 166 | } 167 | 168 | return nil; 169 | } 170 | 171 | - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { 172 | return @"Clear"; 173 | } 174 | 175 | - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 176 | FYFontFile *file = self.fontFiles[indexPath.section]; 177 | if (file.downloadStatus == FYFontFileDownloadStateDownloaded) { 178 | return UITableViewCellEditingStyleDelete; 179 | } else { 180 | return UITableViewCellEditingStyleNone; 181 | } 182 | } 183 | 184 | #pragma mark - Action 185 | 186 | - (void)backAction { 187 | [self dismissViewControllerAnimated:YES completion:nil]; 188 | } 189 | 190 | #pragma mark - Notification 191 | 192 | - (void)layoutCellWithNotification:(NSNotification *)notification { 193 | FYFontFile *file = [notification.userInfo objectForKey:FYFontFileNotificationUserInfoKey]; 194 | NSInteger targetSection = [self.fontFiles indexOfObject:file]; 195 | for (NSInteger row = 0; row < self.fontFiles.count; row++) { 196 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:targetSection]; 197 | if ([self.tableView.indexPathsForVisibleRows containsObject:indexPath]) { 198 | FYSelectFontTableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 199 | [self assembleCell:cell withFile:file]; 200 | [cell setNeedsLayout]; 201 | break; 202 | } 203 | } 204 | } 205 | 206 | - (void)reloadRowWithNotification:(NSNotification *)notification { 207 | FYFontFile *file = [notification.userInfo objectForKey:FYFontFileNotificationUserInfoKey]; 208 | NSInteger targetSection = [self.fontFiles indexOfObject:file]; 209 | [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:targetSection] 210 | withRowAnimation:UITableViewRowAnimationAutomatic]; 211 | } 212 | 213 | #pragma mark - Private 214 | 215 | - (void)setupBarItems { 216 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Hide" 217 | style:UIBarButtonItemStyleDone 218 | target:self 219 | action:@selector(backAction)]; 220 | } 221 | 222 | - (void)setupSelection { 223 | NSInteger section = -1; 224 | NSInteger row = -1; 225 | UIFont *mainFont = [FYFontManager mainFont]; 226 | 227 | for (NSInteger i = 0; i < self.fontFiles.count; i++) { 228 | FYFontFile *file = self.fontFiles[i]; 229 | for (NSInteger j = 0; j < file.fontModels.count; j++) { 230 | FYFontModel *model = file.fontModels[j]; 231 | if ([model.font.fontName isEqualToString:mainFont.fontName]) { 232 | section = i; 233 | row = j; 234 | goto foundSelection; 235 | } 236 | } 237 | } 238 | 239 | foundSelection: 240 | if (section > -1) { 241 | NSIndexPath *selectedIndexPath = [NSIndexPath indexPathForRow:row inSection:section]; 242 | [self.tableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle]; 243 | } 244 | } 245 | 246 | - (void)assembleCell:(FYSelectFontTableViewCell *)cell withModel:(FYFontModel *)model { 247 | UIFont *font = [UIFont fy_fontOfModel:model withSize:12.0f]; 248 | cell.textLabel.text = model.postScriptName; 249 | cell.textLabel.font = font; 250 | cell.detailTextLabel.text = nil; 251 | cell.downloadProgress = 1.0; 252 | } 253 | 254 | - (void)assembleCell:(FYSelectFontTableViewCell *)cell withFile:(FYFontFile *)file { 255 | UIFont *font = [UIFont systemFontOfSize:12.0f weight:10.0]; 256 | cell.textLabel.text = file.sourceURLString; 257 | cell.textLabel.font = font; 258 | cell.detailTextLabel.text = nil; 259 | cell.downloadProgress = file.downloadProgress; 260 | cell.striped = NO; 261 | cell.pauseStripes = NO; 262 | 263 | switch (file.downloadStatus) { 264 | case FYFontFileDownloadStateToBeDownloaded: { 265 | if (file.downloadError) { 266 | cell.detailTextLabel.text = file.downloadError.localizedDescription; 267 | } 268 | } 269 | break; 270 | 271 | case FYFontFileDownloadStateDownloading: { 272 | cell.striped = file.fileSizeUnknown; 273 | } 274 | break; 275 | 276 | case FYFontFileDownloadStateSuspended: { 277 | cell.striped = file.fileSizeUnknown; 278 | cell.pauseStripes = YES; 279 | } 280 | break; 281 | 282 | default: 283 | break; 284 | } 285 | if (file.fileSize > 0.0f) { 286 | if (file.fileSizeUnknown) { 287 | cell.detailTextLabel.text = [NSString stringWithFormat:@"%.2fM / ?", file.fileDownloadedSize / 1000000.0f]; 288 | } else { 289 | cell.detailTextLabel.text = [NSString stringWithFormat:@"%.2fM / %.2fM", file.fileDownloadedSize / 1000000.0f, file.fileSize / 1000000.0f]; 290 | } 291 | } 292 | } 293 | 294 | @end 295 | -------------------------------------------------------------------------------- /Fonty-Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 523C70361E9E003100845940 /* FYDownloadDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 523C70351E9E003100845940 /* FYDownloadDelegate.m */; }; 11 | 52F9EA201E88B78500D7EE30 /* FYFontFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 52F9EA1F1E88B78500D7EE30 /* FYFontFile.m */; }; 12 | 6A6F37881DE3001700E0B360 /* Fonty_DemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A6F37871DE3001700E0B360 /* Fonty_DemoTests.m */; }; 13 | 6A73D6B11D86BB2600D38630 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6B01D86BB2600D38630 /* main.m */; }; 14 | 6A73D6B41D86BB2600D38630 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6B31D86BB2600D38630 /* AppDelegate.m */; }; 15 | 6A73D6B71D86BB2600D38630 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6B61D86BB2600D38630 /* ViewController.m */; }; 16 | 6A73D6BA1D86BB2600D38630 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6A73D6B81D86BB2600D38630 /* Main.storyboard */; }; 17 | 6A73D6BC1D86BB2600D38630 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A73D6BB1D86BB2600D38630 /* Assets.xcassets */; }; 18 | 6A73D6BF1D86BB2600D38630 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6A73D6BD1D86BB2600D38630 /* LaunchScreen.storyboard */; }; 19 | 6A73D6E81D86C05000D38630 /* FYFontCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6DC1D86C05000D38630 /* FYFontCache.m */; }; 20 | 6A73D6E91D86C05000D38630 /* FYFontDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6DE1D86C05000D38630 /* FYFontDownloader.m */; }; 21 | 6A73D6EA1D86C05000D38630 /* FYFontManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6E01D86C05000D38630 /* FYFontManager.m */; }; 22 | 6A73D6EC1D86C05000D38630 /* FYFontRegister.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6E41D86C05000D38630 /* FYFontRegister.m */; }; 23 | 6A73D6ED1D86C05000D38630 /* UIFont+FY_Fonty.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6E71D86C05000D38630 /* UIFont+FY_Fonty.m */; }; 24 | 6A73D6F21D86C09500D38630 /* FYSelectFontViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6EF1D86C09500D38630 /* FYSelectFontViewController.m */; }; 25 | 6A73D6F31D86C09500D38630 /* FYSelectFontTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A73D6F11D86C09500D38630 /* FYSelectFontTableViewCell.m */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 6A6F378A1DE3001700E0B360 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 6A73D6A41D86BB2600D38630 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 6A73D6AB1D86BB2600D38630; 34 | remoteInfo = "Fonty-Demo"; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 52028CF31E9B7B3200848B89 /* Fonty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Fonty.h; sourceTree = ""; }; 40 | 523C70341E9E003100845940 /* FYDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYDownloadDelegate.h; sourceTree = ""; }; 41 | 523C70351E9E003100845940 /* FYDownloadDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYDownloadDelegate.m; sourceTree = ""; }; 42 | 52F9EA1E1E88B78500D7EE30 /* FYFontFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYFontFile.h; sourceTree = ""; }; 43 | 52F9EA1F1E88B78500D7EE30 /* FYFontFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYFontFile.m; sourceTree = ""; }; 44 | 6A6F37851DE3001700E0B360 /* Fonty-DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Fonty-DemoTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 6A6F37871DE3001700E0B360 /* Fonty_DemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Fonty_DemoTests.m; sourceTree = ""; }; 46 | 6A6F37891DE3001700E0B360 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | 6A73D6AC1D86BB2600D38630 /* Fonty-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Fonty-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 6A73D6B01D86BB2600D38630 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 49 | 6A73D6B21D86BB2600D38630 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 50 | 6A73D6B31D86BB2600D38630 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 51 | 6A73D6B51D86BB2600D38630 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 52 | 6A73D6B61D86BB2600D38630 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 53 | 6A73D6B91D86BB2600D38630 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 54 | 6A73D6BB1D86BB2600D38630 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55 | 6A73D6BE1D86BB2600D38630 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 56 | 6A73D6C01D86BB2600D38630 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 6A73D6DB1D86C05000D38630 /* FYFontCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYFontCache.h; sourceTree = ""; }; 58 | 6A73D6DC1D86C05000D38630 /* FYFontCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYFontCache.m; sourceTree = ""; }; 59 | 6A73D6DD1D86C05000D38630 /* FYFontDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYFontDownloader.h; sourceTree = ""; }; 60 | 6A73D6DE1D86C05000D38630 /* FYFontDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYFontDownloader.m; sourceTree = ""; }; 61 | 6A73D6DF1D86C05000D38630 /* FYFontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYFontManager.h; sourceTree = ""; }; 62 | 6A73D6E01D86C05000D38630 /* FYFontManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYFontManager.m; sourceTree = ""; }; 63 | 6A73D6E31D86C05000D38630 /* FYFontRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYFontRegister.h; sourceTree = ""; }; 64 | 6A73D6E41D86C05000D38630 /* FYFontRegister.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYFontRegister.m; sourceTree = ""; }; 65 | 6A73D6E61D86C05000D38630 /* UIFont+FY_Fonty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+FY_Fonty.h"; sourceTree = ""; }; 66 | 6A73D6E71D86C05000D38630 /* UIFont+FY_Fonty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+FY_Fonty.m"; sourceTree = ""; }; 67 | 6A73D6EE1D86C09500D38630 /* FYSelectFontViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYSelectFontViewController.h; sourceTree = ""; }; 68 | 6A73D6EF1D86C09500D38630 /* FYSelectFontViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYSelectFontViewController.m; sourceTree = ""; }; 69 | 6A73D6F01D86C09500D38630 /* FYSelectFontTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FYSelectFontTableViewCell.h; sourceTree = ""; }; 70 | 6A73D6F11D86C09500D38630 /* FYSelectFontTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FYSelectFontTableViewCell.m; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 6A6F37821DE3001700E0B360 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 6A73D6A91D86BB2600D38630 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | 6A6F37861DE3001700E0B360 /* Fonty-DemoTests */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 6A6F37871DE3001700E0B360 /* Fonty_DemoTests.m */, 95 | 6A6F37891DE3001700E0B360 /* Info.plist */, 96 | ); 97 | path = "Fonty-DemoTests"; 98 | sourceTree = ""; 99 | }; 100 | 6A73D6A31D86BB2600D38630 = { 101 | isa = PBXGroup; 102 | children = ( 103 | 6A73D6AE1D86BB2600D38630 /* Fonty-Demo */, 104 | 6A73D6DA1D86C05000D38630 /* Fonty */, 105 | 6A6F37861DE3001700E0B360 /* Fonty-DemoTests */, 106 | 6A73D6AD1D86BB2600D38630 /* Products */, 107 | ); 108 | sourceTree = ""; 109 | }; 110 | 6A73D6AD1D86BB2600D38630 /* Products */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 6A73D6AC1D86BB2600D38630 /* Fonty-Demo.app */, 114 | 6A6F37851DE3001700E0B360 /* Fonty-DemoTests.xctest */, 115 | ); 116 | name = Products; 117 | sourceTree = ""; 118 | }; 119 | 6A73D6AE1D86BB2600D38630 /* Fonty-Demo */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 6A73D6B21D86BB2600D38630 /* AppDelegate.h */, 123 | 6A73D6B31D86BB2600D38630 /* AppDelegate.m */, 124 | 6A73D6B51D86BB2600D38630 /* ViewController.h */, 125 | 6A73D6B61D86BB2600D38630 /* ViewController.m */, 126 | 6A73D6EE1D86C09500D38630 /* FYSelectFontViewController.h */, 127 | 6A73D6EF1D86C09500D38630 /* FYSelectFontViewController.m */, 128 | 6A73D6F01D86C09500D38630 /* FYSelectFontTableViewCell.h */, 129 | 6A73D6F11D86C09500D38630 /* FYSelectFontTableViewCell.m */, 130 | 6A73D6B81D86BB2600D38630 /* Main.storyboard */, 131 | 6A73D6BB1D86BB2600D38630 /* Assets.xcassets */, 132 | 6A73D6BD1D86BB2600D38630 /* LaunchScreen.storyboard */, 133 | 6A73D6C01D86BB2600D38630 /* Info.plist */, 134 | 6A73D6AF1D86BB2600D38630 /* Supporting Files */, 135 | ); 136 | path = "Fonty-Demo"; 137 | sourceTree = ""; 138 | }; 139 | 6A73D6AF1D86BB2600D38630 /* Supporting Files */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 6A73D6B01D86BB2600D38630 /* main.m */, 143 | ); 144 | name = "Supporting Files"; 145 | sourceTree = ""; 146 | }; 147 | 6A73D6DA1D86C05000D38630 /* Fonty */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 52028CF31E9B7B3200848B89 /* Fonty.h */, 151 | 52F9EA1E1E88B78500D7EE30 /* FYFontFile.h */, 152 | 52F9EA1F1E88B78500D7EE30 /* FYFontFile.m */, 153 | 6A73D6DF1D86C05000D38630 /* FYFontManager.h */, 154 | 6A73D6E01D86C05000D38630 /* FYFontManager.m */, 155 | 6A73D6DD1D86C05000D38630 /* FYFontDownloader.h */, 156 | 6A73D6DE1D86C05000D38630 /* FYFontDownloader.m */, 157 | 523C70341E9E003100845940 /* FYDownloadDelegate.h */, 158 | 523C70351E9E003100845940 /* FYDownloadDelegate.m */, 159 | 6A73D6DB1D86C05000D38630 /* FYFontCache.h */, 160 | 6A73D6DC1D86C05000D38630 /* FYFontCache.m */, 161 | 6A73D6E31D86C05000D38630 /* FYFontRegister.h */, 162 | 6A73D6E41D86C05000D38630 /* FYFontRegister.m */, 163 | 6A73D6E61D86C05000D38630 /* UIFont+FY_Fonty.h */, 164 | 6A73D6E71D86C05000D38630 /* UIFont+FY_Fonty.m */, 165 | ); 166 | path = Fonty; 167 | sourceTree = ""; 168 | }; 169 | /* End PBXGroup section */ 170 | 171 | /* Begin PBXNativeTarget section */ 172 | 6A6F37841DE3001700E0B360 /* Fonty-DemoTests */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 6A6F378E1DE3001700E0B360 /* Build configuration list for PBXNativeTarget "Fonty-DemoTests" */; 175 | buildPhases = ( 176 | 6A6F37811DE3001700E0B360 /* Sources */, 177 | 6A6F37821DE3001700E0B360 /* Frameworks */, 178 | 6A6F37831DE3001700E0B360 /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | 6A6F378B1DE3001700E0B360 /* PBXTargetDependency */, 184 | ); 185 | name = "Fonty-DemoTests"; 186 | productName = "Fonty-DemoTests"; 187 | productReference = 6A6F37851DE3001700E0B360 /* Fonty-DemoTests.xctest */; 188 | productType = "com.apple.product-type.bundle.unit-test"; 189 | }; 190 | 6A73D6AB1D86BB2600D38630 /* Fonty-Demo */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 6A73D6C31D86BB2600D38630 /* Build configuration list for PBXNativeTarget "Fonty-Demo" */; 193 | buildPhases = ( 194 | 6A73D6A81D86BB2600D38630 /* Sources */, 195 | 6A73D6A91D86BB2600D38630 /* Frameworks */, 196 | 6A73D6AA1D86BB2600D38630 /* Resources */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | ); 202 | name = "Fonty-Demo"; 203 | productName = "Fonty-Demo"; 204 | productReference = 6A73D6AC1D86BB2600D38630 /* Fonty-Demo.app */; 205 | productType = "com.apple.product-type.application"; 206 | }; 207 | /* End PBXNativeTarget section */ 208 | 209 | /* Begin PBXProject section */ 210 | 6A73D6A41D86BB2600D38630 /* Project object */ = { 211 | isa = PBXProject; 212 | attributes = { 213 | LastUpgradeCheck = 0810; 214 | ORGANIZATIONNAME = s2mh; 215 | TargetAttributes = { 216 | 6A6F37841DE3001700E0B360 = { 217 | CreatedOnToolsVersion = 8.1; 218 | DevelopmentTeam = RR6E6G8SN5; 219 | ProvisioningStyle = Automatic; 220 | TestTargetID = 6A73D6AB1D86BB2600D38630; 221 | }; 222 | 6A73D6AB1D86BB2600D38630 = { 223 | CreatedOnToolsVersion = 7.3.1; 224 | ProvisioningStyle = Manual; 225 | }; 226 | }; 227 | }; 228 | buildConfigurationList = 6A73D6A71D86BB2600D38630 /* Build configuration list for PBXProject "Fonty-Demo" */; 229 | compatibilityVersion = "Xcode 3.2"; 230 | developmentRegion = English; 231 | hasScannedForEncodings = 0; 232 | knownRegions = ( 233 | en, 234 | Base, 235 | ); 236 | mainGroup = 6A73D6A31D86BB2600D38630; 237 | productRefGroup = 6A73D6AD1D86BB2600D38630 /* Products */; 238 | projectDirPath = ""; 239 | projectRoot = ""; 240 | targets = ( 241 | 6A73D6AB1D86BB2600D38630 /* Fonty-Demo */, 242 | 6A6F37841DE3001700E0B360 /* Fonty-DemoTests */, 243 | ); 244 | }; 245 | /* End PBXProject section */ 246 | 247 | /* Begin PBXResourcesBuildPhase section */ 248 | 6A6F37831DE3001700E0B360 /* Resources */ = { 249 | isa = PBXResourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | 6A73D6AA1D86BB2600D38630 /* Resources */ = { 256 | isa = PBXResourcesBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | 6A73D6BF1D86BB2600D38630 /* LaunchScreen.storyboard in Resources */, 260 | 6A73D6BC1D86BB2600D38630 /* Assets.xcassets in Resources */, 261 | 6A73D6BA1D86BB2600D38630 /* Main.storyboard in Resources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXResourcesBuildPhase section */ 266 | 267 | /* Begin PBXSourcesBuildPhase section */ 268 | 6A6F37811DE3001700E0B360 /* Sources */ = { 269 | isa = PBXSourcesBuildPhase; 270 | buildActionMask = 2147483647; 271 | files = ( 272 | 6A6F37881DE3001700E0B360 /* Fonty_DemoTests.m in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | 6A73D6A81D86BB2600D38630 /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 6A73D6F21D86C09500D38630 /* FYSelectFontViewController.m in Sources */, 281 | 6A73D6B71D86BB2600D38630 /* ViewController.m in Sources */, 282 | 6A73D6B41D86BB2600D38630 /* AppDelegate.m in Sources */, 283 | 6A73D6E81D86C05000D38630 /* FYFontCache.m in Sources */, 284 | 6A73D6EA1D86C05000D38630 /* FYFontManager.m in Sources */, 285 | 6A73D6F31D86C09500D38630 /* FYSelectFontTableViewCell.m in Sources */, 286 | 52F9EA201E88B78500D7EE30 /* FYFontFile.m in Sources */, 287 | 6A73D6E91D86C05000D38630 /* FYFontDownloader.m in Sources */, 288 | 6A73D6B11D86BB2600D38630 /* main.m in Sources */, 289 | 523C70361E9E003100845940 /* FYDownloadDelegate.m in Sources */, 290 | 6A73D6EC1D86C05000D38630 /* FYFontRegister.m in Sources */, 291 | 6A73D6ED1D86C05000D38630 /* UIFont+FY_Fonty.m in Sources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXSourcesBuildPhase section */ 296 | 297 | /* Begin PBXTargetDependency section */ 298 | 6A6F378B1DE3001700E0B360 /* PBXTargetDependency */ = { 299 | isa = PBXTargetDependency; 300 | target = 6A73D6AB1D86BB2600D38630 /* Fonty-Demo */; 301 | targetProxy = 6A6F378A1DE3001700E0B360 /* PBXContainerItemProxy */; 302 | }; 303 | /* End PBXTargetDependency section */ 304 | 305 | /* Begin PBXVariantGroup section */ 306 | 6A73D6B81D86BB2600D38630 /* Main.storyboard */ = { 307 | isa = PBXVariantGroup; 308 | children = ( 309 | 6A73D6B91D86BB2600D38630 /* Base */, 310 | ); 311 | name = Main.storyboard; 312 | sourceTree = ""; 313 | }; 314 | 6A73D6BD1D86BB2600D38630 /* LaunchScreen.storyboard */ = { 315 | isa = PBXVariantGroup; 316 | children = ( 317 | 6A73D6BE1D86BB2600D38630 /* Base */, 318 | ); 319 | name = LaunchScreen.storyboard; 320 | sourceTree = ""; 321 | }; 322 | /* End PBXVariantGroup section */ 323 | 324 | /* Begin XCBuildConfiguration section */ 325 | 6A6F378C1DE3001700E0B360 /* Debug */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | BUNDLE_LOADER = "$(TEST_HOST)"; 329 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 331 | DEVELOPMENT_TEAM = RR6E6G8SN5; 332 | INFOPLIST_FILE = "Fonty-DemoTests/Info.plist"; 333 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 334 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 335 | PRODUCT_BUNDLE_IDENTIFIER = "s2mh.Fonty-DemoTests"; 336 | PRODUCT_NAME = "$(TARGET_NAME)"; 337 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Fonty-Demo.app/Fonty-Demo"; 338 | }; 339 | name = Debug; 340 | }; 341 | 6A6F378D1DE3001700E0B360 /* Release */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | BUNDLE_LOADER = "$(TEST_HOST)"; 345 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 346 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 347 | DEVELOPMENT_TEAM = RR6E6G8SN5; 348 | INFOPLIST_FILE = "Fonty-DemoTests/Info.plist"; 349 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 350 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 351 | PRODUCT_BUNDLE_IDENTIFIER = "s2mh.Fonty-DemoTests"; 352 | PRODUCT_NAME = "$(TARGET_NAME)"; 353 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Fonty-Demo.app/Fonty-Demo"; 354 | }; 355 | name = Release; 356 | }; 357 | 6A73D6C11D86BB2600D38630 /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BOOL_CONVERSION = YES; 367 | CLANG_WARN_CONSTANT_CONVERSION = YES; 368 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 369 | CLANG_WARN_EMPTY_BODY = YES; 370 | CLANG_WARN_ENUM_CONVERSION = YES; 371 | CLANG_WARN_INFINITE_RECURSION = YES; 372 | CLANG_WARN_INT_CONVERSION = YES; 373 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 374 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 375 | CLANG_WARN_UNREACHABLE_CODE = YES; 376 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 377 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 378 | COPY_PHASE_STRIP = NO; 379 | DEBUG_INFORMATION_FORMAT = dwarf; 380 | ENABLE_STRICT_OBJC_MSGSEND = YES; 381 | ENABLE_TESTABILITY = YES; 382 | GCC_C_LANGUAGE_STANDARD = gnu99; 383 | GCC_DYNAMIC_NO_PIC = NO; 384 | GCC_NO_COMMON_BLOCKS = YES; 385 | GCC_OPTIMIZATION_LEVEL = 0; 386 | GCC_PREPROCESSOR_DEFINITIONS = ( 387 | "DEBUG=1", 388 | "$(inherited)", 389 | ); 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 397 | MTL_ENABLE_DEBUG_INFO = YES; 398 | ONLY_ACTIVE_ARCH = YES; 399 | SDKROOT = iphoneos; 400 | TARGETED_DEVICE_FAMILY = "1,2"; 401 | }; 402 | name = Debug; 403 | }; 404 | 6A73D6C21D86BB2600D38630 /* Release */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | ALWAYS_SEARCH_USER_PATHS = NO; 408 | CLANG_ANALYZER_NONNULL = YES; 409 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 410 | CLANG_CXX_LIBRARY = "libc++"; 411 | CLANG_ENABLE_MODULES = YES; 412 | CLANG_ENABLE_OBJC_ARC = YES; 413 | CLANG_WARN_BOOL_CONVERSION = YES; 414 | CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR; 421 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 427 | ENABLE_NS_ASSERTIONS = NO; 428 | ENABLE_STRICT_OBJC_MSGSEND = YES; 429 | GCC_C_LANGUAGE_STANDARD = gnu99; 430 | GCC_NO_COMMON_BLOCKS = YES; 431 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 433 | GCC_WARN_UNDECLARED_SELECTOR = YES; 434 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 435 | GCC_WARN_UNUSED_FUNCTION = YES; 436 | GCC_WARN_UNUSED_VARIABLE = YES; 437 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 438 | MTL_ENABLE_DEBUG_INFO = NO; 439 | SDKROOT = iphoneos; 440 | TARGETED_DEVICE_FAMILY = "1,2"; 441 | VALIDATE_PRODUCT = YES; 442 | }; 443 | name = Release; 444 | }; 445 | 6A73D6C41D86BB2600D38630 /* Debug */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | CODE_SIGN_IDENTITY = "iPhone Developer"; 450 | DEVELOPMENT_TEAM = ""; 451 | INFOPLIST_FILE = "Fonty-Demo/Info.plist"; 452 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 453 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 454 | ONLY_ACTIVE_ARCH = YES; 455 | PRODUCT_BUNDLE_IDENTIFIER = "s2mh.Fonty-Demo"; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | TARGETED_DEVICE_FAMILY = 1; 458 | }; 459 | name = Debug; 460 | }; 461 | 6A73D6C51D86BB2600D38630 /* Release */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 465 | CODE_SIGN_IDENTITY = "iPhone Developer"; 466 | DEVELOPMENT_TEAM = ""; 467 | INFOPLIST_FILE = "Fonty-Demo/Info.plist"; 468 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 470 | PRODUCT_BUNDLE_IDENTIFIER = "s2mh.Fonty-Demo"; 471 | PRODUCT_NAME = "$(TARGET_NAME)"; 472 | TARGETED_DEVICE_FAMILY = 1; 473 | }; 474 | name = Release; 475 | }; 476 | /* End XCBuildConfiguration section */ 477 | 478 | /* Begin XCConfigurationList section */ 479 | 6A6F378E1DE3001700E0B360 /* Build configuration list for PBXNativeTarget "Fonty-DemoTests" */ = { 480 | isa = XCConfigurationList; 481 | buildConfigurations = ( 482 | 6A6F378C1DE3001700E0B360 /* Debug */, 483 | 6A6F378D1DE3001700E0B360 /* Release */, 484 | ); 485 | defaultConfigurationIsVisible = 0; 486 | defaultConfigurationName = Release; 487 | }; 488 | 6A73D6A71D86BB2600D38630 /* Build configuration list for PBXProject "Fonty-Demo" */ = { 489 | isa = XCConfigurationList; 490 | buildConfigurations = ( 491 | 6A73D6C11D86BB2600D38630 /* Debug */, 492 | 6A73D6C21D86BB2600D38630 /* Release */, 493 | ); 494 | defaultConfigurationIsVisible = 0; 495 | defaultConfigurationName = Release; 496 | }; 497 | 6A73D6C31D86BB2600D38630 /* Build configuration list for PBXNativeTarget "Fonty-Demo" */ = { 498 | isa = XCConfigurationList; 499 | buildConfigurations = ( 500 | 6A73D6C41D86BB2600D38630 /* Debug */, 501 | 6A73D6C51D86BB2600D38630 /* Release */, 502 | ); 503 | defaultConfigurationIsVisible = 0; 504 | defaultConfigurationName = Release; 505 | }; 506 | /* End XCConfigurationList section */ 507 | }; 508 | rootObject = 6A73D6A41D86BB2600D38630 /* Project object */; 509 | } 510 | --------------------------------------------------------------------------------