江西南昌网站建设招标,国外网站开发公司,济南网站建设推荐企优互联不错,开发公司的设计费计入什么会计科目iOS开发-使用网络特殊字体下载CoreText 
在开发中遇到需要将字体下载后再显示的情况#xff0c;这种特殊字体下载后才能正常。 
一、字体下载器 
在AFNetworking中添加 
pod Reachability字体下载器使用AFNetworking实现将字体文件下载 代码如下 
#import SDFontDownloa…iOS开发-使用网络特殊字体下载CoreText 
在开发中遇到需要将字体下载后再显示的情况这种特殊字体下载后才能正常。 
一、字体下载器 
在AFNetworking中添加 
pod Reachability字体下载器使用AFNetworking实现将字体文件下载 代码如下 
#import SDFontDownloaderClient.h
#import AFNetworking.himplementation SDFontDownloaderClientErrorendinterface SDFontDownloaderClient ()property (nonatomic, strong) AFHTTPSessionManager *httpManager;endimplementation SDFontDownloaderClient (instancetype)sharedInstance {static SDFontDownloaderClient *_sharedInstance  nil;static dispatch_once_t onceToken;dispatch_once(onceToken, ^{_sharedInstance  [[SDFontDownloaderClient alloc] init];_sharedInstance.httpManager  [AFHTTPSessionManager manager];_sharedInstance.httpManager.responseSerializer.acceptableContentTypes  [NSSet setWithObjects:application/json, text/json, text/javascript, text/html, text/plain, nil];});return _sharedInstance;
}- (AFHTTPSessionManager *)httpManager{if (!_httpManager) {_httpManager  [[AFHTTPSessionManager alloc] init];_httpManager.operationQueue.maxConcurrentOperationCount  6;_httpManager.requestSerializer  [AFJSONRequestSerializer serializer];[_httpManager.requestSerializer willChangeValueForKey:timeoutInterval];[_httpManager.requestSerializer setTimeoutInterval:10];[_httpManager.requestSerializer setStringEncoding:NSUTF8StringEncoding];_httpManager.responseSerializer  [AFJSONResponseSerializer serializer];_httpManager.responseSerializer.acceptableContentTypes  [NSSet setWithObjects:text/plain, multipart/form-data, application/json, text/html, image/jpeg, image/png, application/octet-stream, text/json, text/javascript, text/html, nil];_httpManager.requestSerializer.HTTPMethodsEncodingParametersInURI  [NSSet setWithArray:[POST, GET, HEAD, PUT, DELETE]];}[_httpManager.requestSerializer setValue:application/x-www-form-urlencoded forHTTPHeaderField:Content-Type];return _httpManager;
}#pragma mark - Http Request Failure
- (SDFontDownloaderClientError *)httpRequestFailure:(NSHTTPURLResponse *)responseerror:(NSError *)error {SDFontDownloaderClientError *e  [[SDFontDownloaderClientError alloc] init];if(error.code  NSURLErrorNotConnectedToInternet || error.code  NSURLErrorCannotFindHost || error.code  NSURLErrorCannotConnectToHost){e.message  网络连接失败!;return e;}if (error.code  NSURLErrorTimedOut){e.message  网路连接超时!;return e;}NSInteger statusCode  response.statusCode;if (statusCode  401) {e.message  认证失败;} else if (statusCode  400){e.message  无效请求;} else if (statusCode  404) {e.message  访问的资源丢失了!;} else if (statusCode  500){e.message  服务器居然累倒了!;}#ifdef DEBUGtry {// 这里只是测试用//第一步、首先从error根据NSErrorFailingURLKey拿到valueNSError *errorFail  [error.userInfo objectForKey:NSUnderlyingError];//第二步、通过errorFail根据com.alamofire.serialization.response.error.data拿到valueNSData *data  nil;if (errorFail) {data  [errorFail.userInfo objectForKey:com.alamofire.serialization.response.error.data];} else {data  [error.userInfo objectForKey:com.alamofire.serialization.response.error.data];}NSLog(data:%,data);//第三部、将NSData转成NSString因为NSString字符串比较直观if (data) {NSString *errorString  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSLog(errorString:%,errorString);}} catch (NSException *exception) {} finally {}#else#endifreturn e;
}#pragma mark - Http download
/**请求下载param aUrl aurlparam aSavePath aSavePathparam aFileName aFileNameparam aTag aTagparam downloadprogress downloadprogressparam success successparam failure failure*/
- (void)downloadFileURL:(NSString *)aUrlsavePath:(NSString *)aSavePathfileName:(NSString *)aFileNametag:(NSInteger)aTagdownloadProgress:(void(^)(CGFloat progress))downloadprogresssuccess:(void(^)(NSURLResponse *response,NSString *filePath))successfailure:(void(^)(SDFontDownloaderClientError * e))failure {NSFileManager *fileManger  [NSFileManager defaultManager];if ([fileManger fileExistsAtPath:[aSavePath stringByAppendingPathComponent:aFileName]]) {//文件存在return;}//2.确定请求的URL地址NSString *requestUrl  aUrl;NSMutableURLRequest *request  [self.httpManager.requestSerializer requestWithMethod:GET URLString:requestUrl parameters:nil error:nil];__block NSURLSessionDownloadTask *downloadTask  nil;downloadTask  [self.httpManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {NSLog(progress current thread:%, [NSThread currentThread]);dispatch_async(dispatch_get_main_queue(), ^{downloadprogress(1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);});} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {NSLog(destination current thread:%, [NSThread currentThread]);return [NSURL fileURLWithPath:aSavePath];} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {NSLog(completionHandler current thread:%, [NSThread currentThread]);if(error  nil) {success(response,[filePath path]);} else {//下载失败NSHTTPURLResponse *httpResponse  (NSHTTPURLResponse *)response;SDFontDownloaderClientError *e  [self httpRequestFailure:httpResponse error:error];failure(e);}}];[downloadTask resume];
}end二、字体管理 
字体文件在下载后将注册到CTFontManager 
//注册指定路径下的字体文件
- (void)registerFont:(NSString *)fontPath {//调整位置NSURL *fontUrl  [NSURL fileURLWithPath:fontPath];CGDataProviderRef providerRef  CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);CFErrorRef error;CGFontRef font  CGFontCreateWithDataProvider(providerRef);if(!font){CGDataProviderRelease(providerRef);CGFontRelease(font);return;}BOOL ctfmrgf  CTFontManagerRegisterGraphicsFont(font, error);if (!ctfmrgf) {//注册失败CFStringRef errorDescription  CFErrorCopyDescription(error);CFRelease(errorDescription);if (error) {CFRelease(error);}}CGFontRelease(font);CFRelease(providerRef);
}字体管理完整代码如下 
#import SDFontManager.himplementation SDFontLoadErrorendstatic SDFontManager *manager  nil;interface SDFontManager ()endimplementation SDFontManager (instancetype)shareInstance {static dispatch_once_t onceToken;dispatch_once(onceToken, ^{manager  [[SDFontManager alloc] init];});return manager;
}- (void)downloadAppleFontName:(NSString *)fontNamefontSize:(CGFloat)fontSizebeginLoadBlock:(SDFontBeginLoadBlock)beginLoadBlockprogressBlock:(SDFontLoadProgressBlock)progressBlockcompletionBlock:(SDFontLoadCompletionBlock)completionBlock {self.beginLoadBlock  beginLoadBlock;self.progressBlock  progressBlock;self.completionBlock  completionBlock;UIFont* aFont  [UIFont fontWithName:fontName size:fontSize];// If the font is already downloadedif (aFont  ([aFont.fontName compare:fontName]  NSOrderedSame || [aFont.familyName compare:fontName]  NSOrderedSame)) {// Go ahead and display the sample text.if (self.beginLoadBlock) {self.beginLoadBlock();}if (self.progressBlock) {self.progressBlock(1.0);}if (self.completionBlock) {self.completionBlock(aFont, nil);}return;}// Create a dictionary with the fonts PostScript name.NSMutableDictionary *attrs  [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil];// Create a new font descriptor reference from the attributes dictionary.CTFontDescriptorRef desc  CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs);NSMutableArray *descs  [NSMutableArray arrayWithCapacity:0];[descs addObject:(__bridge id)desc];CFRelease(desc);__block BOOL errorDuringDownload  NO;// Start processing the font descriptor..// This function returns immediately, but can potentially take long time to process.// The progress is notified via the callback block of CTFontDescriptorProgressHandler type.// See CTFontDescriptor.h for the list of progress states and keys for progressParameter dictionary.CTFontDescriptorMatchFontDescriptorsWithProgressHandler( (__bridge CFArrayRef)descs, NULL,  ^(CTFontDescriptorMatchingState state, CFDictionaryRef progressParameter) {//NSLog( state %d - %, state, progressParameter);double progressValue  [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] doubleValue];if (state  kCTFontDescriptorMatchingDidBegin) {dispatch_async( dispatch_get_main_queue(), ^ {// Show an activity indicator// 开始下载字体显示加载进度if (self.beginLoadBlock) {self.beginLoadBlock();}NSLog(Begin Matching);});} else if (state  kCTFontDescriptorMatchingDidFinish) {dispatch_async( dispatch_get_main_queue(), ^ {// Remove the activity indicatorif (!errorDuringDownload) {NSLog(% downloaded, fontName);}if(self.progressBlock){self.progressBlock(1.0f);}// 完成下载字体if (self.completionBlock) {if ([self isAvaliableFont:fontName fontSize:fontSize]) {[self saveAppleFontPathWithFontName:fontName];UIFont *aFont  [UIFont fontWithName:fontName size:fontSize];self.completionBlock(aFont, nil);} else {NSLog(font % is Unavaliable, fontName);}}});} else if (state  kCTFontDescriptorMatchingWillBeginDownloading) {dispatch_async( dispatch_get_main_queue(), ^ {// Show a progress barif(self.progressBlock){self.progressBlock(0.0f);}NSLog(Begin Downloading);});} else if (state  kCTFontDescriptorMatchingDidFinishDownloading) {dispatch_async( dispatch_get_main_queue(), ^ {// Remove the progress barif(self.progressBlock){self.progressBlock(1.0f);}NSLog(Finish downloading);});} else if (state  kCTFontDescriptorMatchingDownloading) {dispatch_async( dispatch_get_main_queue(), ^ {// Use the progress bar to indicate the progress of the downloadingif(self.progressBlock){self.progressBlock(progressValue / 100.0);}NSLog(Downloading %.0f%% complete, progressValue);});} else if (state  kCTFontDescriptorMatchingDidFailWithError) {// An error has occurred.// Get the error messageNSError *error  [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];NSString *errorMessage  nil;if (error ! nil) {errorMessage  [error description];} else {errorMessage  ERROR MESSAGE IS NOT AVAILABLE!;}// Set our flagerrorDuringDownload  YES;dispatch_async( dispatch_get_main_queue(), ^ {if (self.completionBlock) {SDFontLoadError *error  [[SDFontLoadError alloc] init];error.errorMessage  errorMessage;self.completionBlock(nil, error);}NSLog(Download error: %, errorMessage);});}return (bool)YES;});
}- (void)downloadCustomFontName:(NSString *)fontNamefontDownloadUrl:(NSString *)fontDownloadUrlfontSize:(CGFloat)fontSizebeginLoadBlock:(SDFontBeginLoadBlock)beginLoadBlockprogressBlock:(SDFontLoadProgressBlock)progressBlockcompletionBlock:(SDFontLoadCompletionBlock)completionBlock {self.beginLoadBlock  beginLoadBlock;self.progressBlock  progressBlock;self.completionBlock  completionBlock;UIFont* aFont  [UIFont fontWithName:fontName size:fontSize];// If the font is already downloadedif (aFont  ([aFont.fontName compare:fontName]  NSOrderedSame || [aFont.familyName compare:fontName]  NSOrderedSame)) {// Go ahead and display the sample text.if (self.beginLoadBlock) {self.beginLoadBlock();}if (self.progressBlock) {self.progressBlock(1.0);}if (self.completionBlock) {self.completionBlock(aFont, nil);}return;}//如果不存在重新下载解压NSString *savefontDirectoryPath  [self fontDirectoryPath];//下载成功NSString *afileName  [[NSURL URLWithString:fontDownloadUrl] lastPathComponent];NSString *afilePath  [NSString pathWithComponents:[savefontDirectoryPath, afileName]];//下载成功NSString *aFontFileName  [[NSURL URLWithString:fontDownloadUrl] lastPathComponent];BOOL exsit  [self exsitCustomFontFileWithFontName:aFontFileName];if (exsit) {  //如果已经下载过了// 检查字体是否可用[self registerFont:afilePath];UIFont *font  [self fontWithPath:afilePath fontSize:fontSize];//更新UIif (self.progressBlock) {self.progressBlock(1.0);}if (self.completionBlock) {self.completionBlock(font, nil);}return;}__weak typeof(self) weakSelf  self;[[SDFontDownloaderClient sharedInstance] downloadFileURL:fontDownloadUrl savePath:afilePath fileName:afilePath tag:[afilePath hash] downloadProgress:^(CGFloat progress) {if (self.progressBlock) {self.progressBlock(progress);}} success:^(NSURLResponse *response, NSString *filePath) {NSLog(filePath:%,filePath);dispatch_async(dispatch_get_main_queue(), ^{NSString *fontPath  filePath;[weakSelf registerFont:fontPath];  //注册字体文件UIFont *font  [weakSelf fontWithPath:fontPath fontSize:fontSize];if (weakSelf.completionBlock) {weakSelf.completionBlock(font, nil);}});} failure:^(SDFontDownloaderClientError *e) {dispatch_async(dispatch_get_main_queue(), ^{SDFontLoadError *error  [[SDFontLoadError alloc] init];error.errorMessage  e.message;if (weakSelf.completionBlock) {weakSelf.completionBlock(nil, error);}});}];
}//注册苹果字体并保存路径(这里苹果的字体不在沙盒目录无法注册)
- (void)saveAppleFontPathWithFontName:(NSString *)fontName{CTFontRef fontRef  CTFontCreateWithName((__bridge CFStringRef)fontName, 0., NULL);CFURLRef fontURL  CTFontCopyAttribute(fontRef, kCTFontURLAttribute);NSURL *fontPathURL  (__bridge NSURL*)(fontURL);//把苹果的字体路径保存起来[self registerFont:fontPathURL.path];  //注册字体CFRelease(fontURL);CFRelease(fontRef);
}//注册指定路径下的字体文件
- (void)registerFont:(NSString *)fontPath {//调整位置NSURL *fontUrl  [NSURL fileURLWithPath:fontPath];CGDataProviderRef providerRef  CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);CFErrorRef error;CGFontRef font  CGFontCreateWithDataProvider(providerRef);if(!font){CGDataProviderRelease(providerRef);CGFontRelease(font);return;}BOOL ctfmrgf  CTFontManagerRegisterGraphicsFont(font, error);if (!ctfmrgf) {//注册失败CFStringRef errorDescription  CFErrorCopyDescription(error);CFRelease(errorDescription);if (error) {CFRelease(error);}}CGFontRelease(font);CFRelease(providerRef);
}- (UIFont *)fontWithPath:(NSString *)fontPath fontSize:(CGFloat)fontSize {NSURL *fontUrl  [NSURL fileURLWithPath:fontPath];CGDataProviderRef providerRef  CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);CGFontRef font  CGFontCreateWithDataProvider(providerRef);if(!font){CGDataProviderRelease(providerRef);CGFontRelease(font);return nil;}CGDataProviderRelease(providerRef);CTFontManagerUnregisterGraphicsFont(font,nil);CTFontManagerRegisterGraphicsFont(font, NULL);NSString *newFamilyName  CFBridgingRelease(CGFontCopyPostScriptName(font));UIFont *uifont  [UIFont fontWithDescriptor:[UIFontDescriptor fontDescriptorWithName:newFamilyName size:fontSize] size:fontSize];CGFontRelease(font);return uifont;
}//判断字体是否可用
- (BOOL)isAvaliableFont:(NSString *)fontName fontSize:(CGFloat)fontSize {UIFont *aFont  [UIFont fontWithName:fontName size:fontSize];return aFont  ([aFont.fontName compare:fontName]  NSOrderedSame || [aFont.familyName compare:fontName]  NSOrderedSame);
}//是否存在fontFileName
- (BOOL)exsitCustomFontFileWithFontName:(NSString *)fontName {NSString *fontPath  [[self fontDirectoryPath] stringByAppendingPathComponent:fontName];BOOL exsit  [[NSFileManager defaultManager] fileExistsAtPath:fontPath];return exsit;
}// 字体存储的路径path
- (NSString *)fontDirectoryPath {NSString *documentsDirectory  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];NSString *fontDirectoryPath  [documentsDirectory stringByAppendingPathComponent:fonts];[self createDirectoryIfNotExsitPath:fontDirectoryPath];   //创建目录return fontDirectoryPath;
}//创建目录
- (BOOL)createDirectoryIfNotExsitPath:(NSString *)path {BOOL success  YES;if(![[NSFileManager defaultManager] fileExistsAtPath:path]){  //如果则创建文件夹NSError * error  nil;success  [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:error];if (!success || error) {NSLog(Error! %, error);} else {NSLog(Create fonts directory Success!);}}return success;
}//依fontName构建font
- (UIFont *)fontWithFontName:(NSString *)fontName fontSize:(CGFloat)fontSize{if ([self isAvaliableFont:fontName fontSize:fontSize]) {return [UIFont fontWithName:fontName size:fontSize];}return nil;
}end三、使用下载注册后的字体 
我这里使用下载注册后的字体 
- (void)lookButtonAction {[[SDFontManager shareInstance] downloadCustomFontName:猫啃网糖圆体 fontDownloadUrl:https://j1-common-bucket.s3.cn-northwest-1.amazonaws.com.cn/as/2020/12/16/oLmJQK1608104260841.ttf fontSize:20 beginLoadBlock:^{NSLog(beginLoadBlock);} progressBlock:^(CGFloat progress) {NSLog(progressBlock:%f, progress);} completionBlock:^(UIFont *font, SDFontLoadError *error) {NSLog(completionBlock font:%, error:%, font, error);if (font  !error) {self.titleLabel.font  font;}}];
}#pragma mark - lazy
- (UILabel *)titleLabel {if (!_titleLabel) {_titleLabel   [[UILabel alloc] initWithFrame:CGRectZero];_titleLabel.backgroundColor  [UIColor clearColor];_titleLabel.textColor  [UIColor blackColor];_titleLabel.font  [UIFont systemFontOfSize:11];_titleLabel.textAlignment  NSTextAlignmentCenter;}return _titleLabel;
}四、小结 
iOS开发-使用网络特殊字体下载CGFontRef 
在开发中遇到需要将字体下载后再显示的情况这种特殊字体下载后才能正常。。 
学习记录每天不停进步。