THIS IS NOT A DUPLICATE QUESTION
I have searched for everything that I can, but I didn't find something meaningful.
Here is the question:
I want to download a font using CoreText API but it works in iOS 12, NOT available on iOS 13.
There is a demo project from Apple in 2013. But The API it used seems to be private since iOS 13.
/*
@param progressBlock
Callback block to indicate the progress.
Return true to continue, and return false to cancel the process.
This block is called on a private serial queue on OS X 10.15, iOS 13, and later.
*/
@available(iOS 6.0, *)
public func CTFontDescriptorMatchFontDescriptorsWithProgressHandler(_ descriptors: CFArray, _ mandatoryAttributes: CFSet?, _ progressBlock: @escaping CTFontDescriptorProgressHandler) -> Bool
As the documentation declared:
This block is called on a private serial queue on OS X 10.15, iOS 13, and later.
Here is my code for font download:
let fontName = "STXingkai-SC-Light"
let attributes = [kCTFontNameAttribute : fontName] as CFDictionary
let fontDescription = CTFontDescriptorCreateWithAttributes(attributes)
// create font font descriptor and add it in an array
let descs = [fontDescription] as CFArray
CTFontDescriptorMatchFontDescriptorsWithProgressHandler(descs, nil) { (state, progressParamater) -> Bool in
let progressValue = (progressParamater as Dictionary)[kCTFontDescriptorMatchingPercentage]?.doubleValue
switch state {
case .didBegin: print("didBegin")
case .didFinish: print("didFinish")
case .willBeginDownloading: print("willBeginDownloading")
case .didFinishDownloading:
print("--> download finish")
DispatchQueue.main.async {
self.fontLabel.font = UIFont(name: self.fontName, size: 20)
}
case .downloading:
print("downloading#####\(progressValue ?? 0.0)")
DispatchQueue.main.async {
self.progressView.progress = Float(progressValue ?? 0.0)
}
case .didFailWithError:
if let error = (progressParamater as Dictionary)[kCTFontDescriptorMatchingError] as? NSError {
print(error.description)
} else {
print("ERROR MESSAGE IS NOT AVAILABLE")
}
default: print(String(reflecting: state))
}
return true
}
I tried this API on iOS 12 and Xcode 10, everything works fine and I can download a font with provided fontName.
But, when I use this one on Xcode 11 Version 11.0 beta 6 (11M392q) and macOS Catalina 10.15 Beta (19A526h), something went wrong and that method is no longer effective. And I got some output:
didBegin
__C.CTFontDescriptorMatchingState
didFinish
done
"Error Domain=com.apple.CoreText.CTFontManagerErrorDomain Code=303 \"0
font descriptors do not have information to specify a font file.\"
UserInfo={NSLocalizedDescription=0
font descriptors do not have information to specify a font file.
0 font descriptors do not have information to specify a font file
The state will only have didBegin and didFinish, not calling downloading.
WWDC19 seeesion 227 has announced that CTFontManagerRegisterFontDescriptors(fontDescriptors:scope:enabled:registrationHandler:) is available and something about font management. But the source code from the session pdf is not clearly and I've tried, got an other error:
done
[Error Domain=com.apple.CoreText.CTFontManagerErrorDomain Code=306 "The file is not in an allowed location. It must be either in the application’s bundle or an on-demand resource." UserInfo={NSLocalizedDescription=The file is not in an allowed location. It must be either in the application’s bundle or an on-demand resource., CTFontManagerErrorFontURLs=(
"http://iweslie.com/fonts/HanziPenSC-W3.ttf"
), NSLocalizedFailureReason=Font registration was unsuccessful.}]
done
Here is my code referencing from WWDC19 session 227:
let urlString = "http://iweslie.com/fonts/HanziPenSC-W3.ttf"
let url = URL(string: urlString)! as CFURL
let fontURLArray = [url] as CFArray
CTFontManagerRegisterFontURLs(fontURLArray, .persistent, true) { (errors, done) -> Bool in
if done {
print("done")
}
print(errors as Array)
return true
}
And got the error:
Error Domain=com.apple.CoreText.CTFontManagerErrorDomain Code=306
"The file is not in an allowed location. It must be either in the application’s bundle or an on-demand resource."