CoreText CopyFontsForRequest received mig IPC error - objective-c

I've been working on a BIG project (there's no point of showing any actual code anyway) and I've notice that the following message appears in the logs:
CoreText CopyFontsForRequest received mig IPC error (FFFFFFFFFFFFFECC) from font server
The error pops up as soon as a WebView has finished loading. And I kinda believe it's the culprit behind a tiny lag.
Why is that happening? What can I do to fix this?
P.S. Tried the suggested solution here to check whether it was something system-specific, but it didn't work.
More details:
The error appears when using the AMEditorAppearance.car NSAppearance file, from the Appearance Maker project. Disabling it (= not loading it all) makes the error go away.
I don't really care about the error message, other than that it creates some weird issues with fonts. E.g. NSAlert panels, with input fiels, show a noticeable flicker and the font/text seems rather messed up, in a way I'm not sure I can accurately describe. (I could post a video with that if that'd help)

This is probably related to system font conflicts and can easily be fixed:
Open Font book
Select all fonts
Go to the file menu and select "Validate fonts"
Resolve all font conflicts (by removing duplets).
Source: Andreas Wacker

Answer by #Abrax5 is excellent. I just wanted to add my experience with this problem and could not fit it into a comment:
As far as I can tell, this error is raised only on the first failed attempt to initialise an NSFont with a font name that is not available. NSFont initialisers are failable and will return nil in such a case at which time you have an opportunity to do something about it.
You can check whether a font by a given name is available using:
NSFontDescriptor(fontAttributes: [NSFontNameAttribute: "<font name>"]).matchingFontDescriptorWithMandatoryKeys([NSFontNameAttribute]) != nil
Unfortunately, this also raises the error! The following method does not, but is deprecated:
let fontDescr = NSFontDescriptor(fontAttributes: [NSFontNameAttribute: "<font name>"])
let isAvailable = NSFontManager.sharedFontManager().availableFontNamesMatchingFontDescriptor(fontDescr)?.count ?? 0 > 0
So the only way I found of checking the availability of a font of a given name without raising that error is as follows:
public extension NSFont {
private static let availableFonts = (NSFontManager.sharedFontManager().availableFonts as? [String]).map { Set($0) }
public class func available(fontName: String) -> Bool {
return NSFont.availableFonts?.contains(fontName) ?? false
}
}
For example:
NSFont.available("Georgia") //--> true
NSFont.available("WTF?") //--> false
(I'm probably overly cautious with that optional constant there and if you are so inclined you can convert the returned [AnyObject] using as! [String]...)
Note that for the sake of efficiency this will not update until the app is started again, i.e. any fonts installed during the app's run will not be matched. If this is an important issue for your particular app, just turn the constant into a computed property:
public extension NSFont {
private static var allAvailable: Set<String>? {
return (NSFontManager.sharedFontManager().availableFonts as? [String]).map { Set($0) }
}
private static let allAvailableAtStart = allAvailable
public class func available(fontName: String) -> Bool {
return NSFont.allAvailable?.contains(fontName) ?? false
}
public class func availableAtStart(fontName: String) -> Bool {
return NSFont.allAvailableAtStart?.contains(fontName) ?? false
}
}
On my machine available(:) takes 0.006s. Of course, availableAtStart(:) takes virtually no time on all but the first call...

This is caused by calling NSFont fontWithFamily: with a family name argument which is not available on the system from within Chromium's renderer process. When Chromium's sandbox is active this call triggers the CoreText error that you're observing.
It happens during matching CSS font family names against locally installed system fonts.
Probably you were working on a Chromium-derived project. More info can be found in Chromium Bug 452849.

Related

activeComplications of the CLKComplicationServer are nil, although a complication is displayed

I have a watch app with complications. Updating the complication on a watch face did work for a long time, but stopped recently, maybe due to a watchOS update.
The reason is that the activeComplications property of the CLKComplicationServer.sharedInstance() is nil, although my complication placeholder is shown on the watch face (device & simulator).
The code could not be simpler:
final class ComplicationController: NSObject, CLKComplicationDataSource {
// …
func updateComplications() {
//…
let complicationServer = CLKComplicationServer.sharedInstance()
if let activeComplications = complicationServer.activeComplications {
for complication in activeComplications {
complicationServer.reloadTimeline(for: complication)
}
}
//…
}
//…
}
If I stop at a breakpoint at the if let instruction, complicationServer has the following values:
And the following lldb command outputs nil:
What could be the reason?
My bad: I solved the problem 4 years ago, but forgot the solution during refactoring of the app.
Actually I don’t know if this is a solution, a workaround or a hack:
I suspect that the CLKComplicationServer or its CLKComplicationDataSource, i.e. the ComplicationController, is not correctly initialized if ComplicationController.shared is executed anywhere in the code. If not, the ComplicationController is correctly initialized by the CLKComplicationServer.
Therefore, one cannot call any function in the ComplicationController, e.g. to update complications. Instead one can send a notification to the ComplicationController that executes the requested function. Of course, one has to ensure that the ComplicationController is already initialized and registered to receive such a notification before it is posted.
If so, CLKComplicationServer.sharedInstance().activeComplications is no longer nil, and the complication update works.

Having Trouble Getting the UIDocumentBrowserController to open docs in a Document based app

I've been working on a new Document-based app, and was super glad about the new UIDocumentBrowserController...trying to roll my own solution for the document browser UI was tricky!
I'm having some trouble getting the browser to open documents after they've been created.
What happens now is that when I choose to create a new document in the document browser, the document is created and opened as expected, although an error message is logged. However, after the doc is closed, I cannot reopen the file, either immediately or upon subsequent launches, even though the document is displayed. However, a weird clue here is that if I stop running the app after creating the document, but without adding new information to it (triggering the save cycle), and run the project again, I can open the file correctly. Whuch makes me think that there's something in the way the files are being saved that is the issue.
(Note: At this phase, I'm working on getting the local, non/icloud implentation working, before I move on to the icloud implementation.)
Here is the error message at any point in the code whenthe document is saved to disk (or at least most of the time!):
2017-06-20 13:21:58.254938-0500 Sermon Design 2 iOS[22454:5000138] [default] [ERROR] Could not get attribute values for item file:///Users/stevenhovater/Library/Developer/CoreSimulator/Devices/9A4364F2-B3A1-4AD9-B680-FB4BC876C707/data/Containers/Data/Application/DD534ED8-C4A3-40FE-9777-AED961976878/Documents/Untitled-9.sermon. Error: Error Domain=NSFileProviderInternalErrorDomain Code=1 "The reader is not permitted to access the URL." UserInfo={NSLocalizedDescription=The reader is not permitted to access the URL.}
I suspect that the issue lies somewher in my document types plists, which I've tried to set up by imitating the setup in the video for wwdc 2017 session 229.
My docs are encapuslated by an NSData object, using what I take to be a pretty standard subclass implentation of UIDocument. (I'm omitting the code to generate the thumbnails)
override func contents(forType typeName: String) throws -> Any {
print("Saving Document Changes")
if sermon != nil {
let newData = NSKeyedArchiver.archivedData(withRootObject: sermon!)
return newData
} else {
let newData = NSKeyedArchiver.archivedData(withRootObject: Sermon())
return newData
}
}
override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocumentSaveOperation) throws -> [AnyHashable : Any] {
let thumbnail:UIImage = self.createThumbnail()
let thumbnaildict = [URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey : thumbnail]
let dict = [URLResourceKey.thumbnailDictionaryKey:thumbnaildict]
return dict
}
override func load(fromContents contents: Any, ofType typeName: String?) throws {
guard let newSermon:Sermon = NSKeyedUnarchiver.unarchiveObject(with: contents as! Data) as? Sermon else{
throw documentErrors.invalidFile
}
self.sermon = newSermon
}
In my subclass of UIDocumentBrowserViewController, Here is my code for getting a local filename and for creating the new document.
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: #escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
var newDocumentURL: URL? = nil
print("creating new local document")
guard let target = self.newLocalFilename() else {
return
}
let targetSuffix = target.lastPathComponent
let tempURL = URL(fileURLWithPath: NSTemporaryDirectory() + targetSuffix)
let newDocument:SDDocument = SDDocument(fileURL: tempURL)
newDocument.sermon = Sermon()
/
newDocument.save(to: tempURL, for: .forCreating) { (saveSuccess) in
/
guard saveSuccess else {
/
importHandler(nil, .none)
return
}
/
newDocument.close(completionHandler: { (closeSuccess) in
/
guard closeSuccess else {
/
importHandler(nil, .none)
return
}
/
importHandler(tempURL, .move)
})
}
}
func newLocalFilename() -> URL? {
let fileManager = FileManager()
guard let baseURL = self.localDocumentsDirectoryURL.appendingPathComponent("Untitled")
else {return nil}
var target = baseURL.appendingPathExtension(DocumentBrowserViewController.documentExtension)
var nameSuffix = 2
while fileManager.fileExists(atPath: target.path) {
target = URL(fileURLWithPath: baseURL.path + "-\(nameSuffix).\(DocumentBrowserViewController.documentExtension)")
nameSuffix += 1
}
let targetSuffix = target.lastPathComponent
print("Target name: \(targetSuffix)")
print("new url: \(target)")
return target
}
After four or five hours of work banging my head against this problem, I discovered a simple solution: don't test in the Simulator. I switched to testing on my device and instantly everything started working as advertised.
[I can't speak from experience here, but it may be that the "doesn't work in the Simulator" problem is confined to Sierra, but that the Simulator does work in High Sierra. This would explain why some users see this issue and others don't, and especially why Apple seems blissfully unaware of it in the WWDC video.]
I had exactly the same issue when I was trying to save to NSTemporaryDirectory().
If you instead save to the documents directory ([[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject]), it appears to work fine!
Update: it looks like this issue is fixed in iOS 11 beta 3, and you can now save newly created documents to NSTemporaryDirectory() correctly.
Here is my current theory.
This error
Error Domain=NSFileProviderInternalErrorDomain Code=1 "The reader is not permitted to access the URL."
shows up when first creating a UIDocument at a new URL using -initWithFileURL. It's basically saying "this URL doesn't exist yet," but in a way that makes it sound more like a permissions issue.
As far as I can tell, it doesn't prevent you from saving, opening, editing, or closing the file. So I think it's just a superfluous error that Apple should have taken out.
I found that the error happens on simulator when LSSupportsOpeningDocumentsInPlace property is set to YES in the info.plist.
Turn this property to NO, then it starts working, in my case.
On the real device, it works anyway without having error.
Had similar problem, and tried the method for providing a default Core Location in the Schemes settings and it works now. The method was mentioned in this answer: IOS 9 Error Domain=kCLErrorDomain Code=0 "(null)"

How can I suppress the autosave “The file has been changed by another application” alert?

I have a NSDocument subclass that presents a text document from disk. I’m trying to make it refresh automatically on detecting file changes on disk. I’ve overridden -presentedItemDidChange like this:
- (void)presentedItemDidChange
{
[super presentedItemDidChange];
// Ignoring bundles and error-handling for the moment.
NSData *newData = [NSData dataWithContentsOfURL:self.presentedItemURL];
self.textView.string = [[NSString alloc] initWithData:newData encoding:NSUTF8StringEncoding];
}
The UI refreshes fine when the file is changed in another application. The problem is, I get this dialog when I try to save the document in my application after it is modified by another app:
I kind of have an idea why this happens (not sure whether it’s correct): The modification time of the document is later (because it’s modified by another application) than the latest saved version in my app. But can I notify the autosaving system that I have done something with it and let it go away? Or am I doing things wrong when I refresh the document, and I should do it some other way to handle document versions correctly? I need to consider both external applications support or do not support autosave.
Thanks in advance.
#uranusjr's answer pointed me in the right direction -- only revertDocumentToSaved: wasn't exactly the right place.
override func presentedItemDidChange() {
dispatch_async(dispatch_get_main_queue()) {
self.reloadFromFile()
}
}
func reloadFromFile() {
guard let fileURL = self.fileURL else { return }
do {
try revertToContentsOfURL(fileURL, ofType: "YOUR TYPE HERE IF NECESSARY")
} catch {
// TODO handle error
print(error)
}
}
This simply reloads the file. readFromURL(url:, ofType:) (or the NSData/file wrapper based variants) is called and you can re-create your data structures from there.
Stumbled across the solution today (finally). You can “cheat” OS X into not warning about this by reverting the document (but not the file itself) before actually updating the internal data structure:
// Somehow read the updated data.
NSString *content = ...;
// Revert the document.
// This will discard any user input after the last document save,
// so you might want to present some UI here, like an NSAlert.
[self revertDocumentToSaved:self];
// Update the internal state.
self.content = content;
Now OS X will be happy when you save the document.

How to register component interface in wxwebconnect?

I'm doing an experiment with wxWebConnect test application, incorporating the xpcom tutorial at "http://nerdlife.net/building-a-c-xpcom-component-in-windows/"
I adapt MyComponent class as necessary to compile together with testapp.exe (not as separate dll), and on MyApp::OnInit I have the following lines:
ns_smartptr<nsIComponentRegistrar> comp_reg;
res = NS_GetComponentRegistrar(&comp_reg.p);
if (NS_FAILED(res))
return false;
ns_smartptr<nsIFactory> prompt_factory;
CreateMyComponentFactory(&prompt_factory.p);
nsCID prompt_cid = MYCOMPONENT_CID;
res = comp_reg->RegisterFactory(prompt_cid,
"MyComponent",
"#mozilla.org/mycomp;1",
prompt_factory);
Those lines are copied from GeckoEngine::Init(), using the same mechanism to register PromptService, etc. The code compiles well and testapp.exe is running as expected.
I put javascript test as below :
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const cid = "#mozilla.org/mycomp;1";
obj = Components.classes[cid].createInstance();
alert(typeof obj);
// bind the instance we just created to our interface
alert(Components.interfaces.nsIMyComponent);
obj = obj.QueryInterface(Components.interfaces.nsIMyComponent);
} catch (err) {
alert(err);
return;
}
and get the following exception:
Could not convert JavaScript argument arg 0 [nsISupport.QueryInterface]
The first alert says "object", so the line
Components.classes[cid].createInstance()
is returning the created instance.
The second alert says "undefined", so the interface nsIMyComponent is not recognized by XULRunner.
How to dynamically registering nsIMyComponent interface in wxWebConnect environment ?
Thx
I'm not sure what is happening here. The first thing I would check is that your component is scriptable (I assume it is, since the demo you copy from is). The next thing I would check is whether you can instantiate other, standard XULRunner components and get their interface (try something like "alert('Components.interfaces.nsIFile');" - at least in my version of wxWebConnect this shows an alert box with string "nsIFile".
Also, I think it would be worth checking the Error Console to make sure there are no errors or warnings reported. A magic string to do that (in Javascript) is:
window.open('chrome://global/content/console.xul', '', 'chrome,dialog=no,toolbar,resizable');

Symbian: kern-exec 3 panic on RLibrary::Load

I have troubles with dynamic loading of libraries - my code panics with Kern-Exec 3. The code is as follows:
TFileName dllName = _L("mydll.dll");
TFileName dllPath = _L("c:\\sys\\bin\\");
RLibrary dll;
TInt res = dll.Load(dllName, dllPath); // Kern-Exec 3!
TLibraryFunction f = dll.Lookup(1);
if (f)
f();
I receive panic on TInt res = dll.Load(dllName, dllPath); What can I do to get rid of this panic? mydll.dll is really my dll, which has only 1 exported function (for test purposes). Maybe something wrong with the DLL? Here's what it is:
def file:
EXPORTS
_ZN4Init4InitEv # 1 NONAME
pkg file:
#{"mydll DLL"},(0xED3F400D),1,0,0
;Localised Vendor name
%{"Vendor-EN"}
;Unique Vendor name
:"Vendor"
"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\mydll.dll"-"!:\sys\bin\mydll.dll"
mmp file:
TARGET mydll.dll
TARGETTYPE dll
UID 0x1000008d 0xED3F400D
USERINCLUDE ..\inc
SYSTEMINCLUDE \epoc32\include
SOURCEPATH ..\src
SOURCE mydllDllMain.cpp
LIBRARY euser.lib
#ifdef ENABLE_ABIV2_MODE
DEBUGGABLE_UDEBONLY
#endif
EPOCALLOWDLLDATA
CAPABILITY CommDD LocalServices Location MultimediaDD NetworkControl NetworkServices PowerMgmt ProtServ ReadDeviceData ReadUserData SurroundingsDD SwEvent TrustedUI UserEnvironment WriteDeviceData WriteUserData
source code:
// Exported Functions
namespace Init
{
EXPORT_C TInt Init()
{
// no implementation required
return 0;
}
}
header file:
#ifndef __MYDLL_H__
#define __MYDLL_H__
// Include Files
namespace Init
{
IMPORT_C TInt Init();
}
#endif // __MYDLL_H__
I have no ideas about this... Any help is greatly appreciated.
P.S. I'm trying to do RLibrary::Load because I have troubles with static linkage. When I do static linkage, my main program doesn't start at all. I decided to check what happens and discovered this issue with RLibrary::Load.
A KERN-EXEC 3 panic is caused by an unhandled exception (CPU fault) generated by trying to invalidly access a region of memory. This invalid memory access can be for both code (for example, bad PC by stack corruption) or data (for example, accessing freed memory). As such these are typically observed when dereferencing a NULL pointer (it is equivalent to a segfault).
Certainly the call to RLibrary::Load should never raise a KERN-EXEC 3 due to programmatic error, it is likely to be an environmental issue. As such I have to speculate on what is happening.
I believe the issue that is observed is due to stack overflow. Your MMP file does not specify the stack or heap size the initial thread should use. As such the default of 4Kb (if I remember correctly) will be used. Equally you are using TFileName - use of these on the stack is generally not recommended to avoid... stack overflow.
You would be better off using the _LIT() macro instead - this will allow you to provide the RLibrary::Load function with a descriptor directly referencing the constant strings as located in the constant data section of the binary.
As a side note, you should check the error value to determine the success of the function call.
_LIT(KMyDllName, "mydll.dll");
_LIT(KMyDllPath, "c:\\sys\\bin\\");
RLibrary dll;
TInt res = dll.Load(KMyDllName, MyDllPath); // Hopefully no Kern-Exec 3!
if(err == KErrNone)
{
TLibraryFunction f = dll.Lookup(1);
if (f)
f();
}
// else handle error
The case that you can't use static linkage should be a strong warning to you. It shows that there is something wrong with your DLL and using dynamic linking won't change anything.
Usually in these cases the problem is in mismatched capabilities. DLL must have at least the same set of capabilities that your main program has. And all those capabilities should be covered by your developer cert.