I am trying to write a demo according to Thread Programming Guide about run loops.
When I implement NSPortDelegate's - (void)handlePortMessage:(NSPortMessage *)portMessage; method it prompts an error:
Receiver type 'NSPortMessage' for instance message is a forward declaration
So I try to import by "Foundation/NSPortMessage.h", after which it says:
Foundation/NSPortMessage.h file not found.
So I wonder whether we can use NSPortMesssage in iOS?
NSPortMessage doesn't seem to be in the iOS documentation so is presumably a private API. Xcode does code completion of NSPortMessage for me when I try to use it, presumably because of the forward declaration. However, if I ask Xcode to show me the definition of NSPortMessage it says the symbol is not found which would confirm that it is a private API.
The class exists in the Objective-C Runtime on my iPhone 4s so it is on the device. However NSPortMessage allows inter-process communication which I assume would be against the iOS sandboxing security. Perhaps it will work for inter-thread communications though.
I certainly wouldn't try and use it in an app that is intended for the App Store.
Since the iOS version of distributed object programming guide and certain APIs are also deprecated, it seems that all stuff related to port-based input source are discouraged to be used for iOS development. But setting up a port-based channel to communicate between threads using Core Foundation function still be an available choice.
Related
Goal
I'm building an iOS app using flutter for frontend, and C/C++ as backend. They must interoperate through FFI, which is a language binding scheme through C dynamic libraries. I intend to submit it to iOS App Store.
Problems
The Dart FFI sample on accessing C-struct works on macOS through dynamic liking and binding. Now dynamic linking is technically possible on iOS according to Xcode 9 - No option to create dylib project iOS, however, it's unclear to me how to ship the app to AppStore, because dynamic linking is not allowed according to Apple Guidelines Section 2.5.2.
2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they
download, install, or execute code which introduces or changes
features or functionality of the app, including other apps.
Educational apps designed to teach, develop, or allow students to test
executable code may, in limited circumstances, download code provided
that such code is not used for other purposes. Such apps must make the
source code provided by the Application completely viewable and
editable by the user.
Quite a few SO questions confirm this problem, such as:
can I use dynamic library(shared object) in my iphone app?
Will Appstore reviewers allow us to use dynamic library in iOS8?
Then official flutter documentation says
Dynamically linked libraries are automatically loaded by the dynamic
linker when the app starts. Their constituent symbols can be resolved
using DynamicLibrary.process. You can also get a handle to the library
with DynamicLibrary.open to restrict the scope of symbol resolution,
but it’s unclear how Apple’s review process handles this.
Questions
As of the date when I post this (2020), does this say that I could never ship an app using this architecture to App Store?
Is it possible that I static link my C/C++ code into a single binary of a flutter app? Take Unity as an example, their iOS plugin system recompiles the plugin into native app. If flutter has a similar mechanism, how?
The answers saying you can't use dynamic libraries on iOS date to before iOS 8, when support for user-provided dynamic libraries was added.
Nothing in 2.5.2 days you can't use dynamic libraires as long as they are shipped as part of your app. So:
As of the date when I post this (2020), does this say that I could never ship an app using this architecture to App Store?
No it doesn't, as long as "this architecture" refers to using a dynamic library that you link to at build time and bundle into your application.
Adding inputs from Reddit's FlutterDev channel
#escamoteur
As I understand it you are not allowed to load any library from
outside your installation folder. Especially not downloading something
at a later point of time. Could you make this a Stackoverflow question
and tag it with Flutter?
#airflow_matt
Since iOS 8 there can be shared libraries in the bundle, when properly
codesigned I don't see why dlopen wouldn't work. Or you can link the
library with main executable itself (just like flutter does) and
dlopen self (DynamicLibrary.process()). I think it's worth a shot.
I'm developing an app in UWP. I need to send to my printer a RAW string (or file) and get that printed. I succed in using the old RawPrinterHelper from here.
I have some problems verifiyng the app using the Windows App Certification Kit.
I get errors like this one :
API ClosePrinter in winspool.drv is not supported for this application type. MyApp.dll calls this API.
I think that DllImport() in RawPrinterHelper is wrong.
Is there a way to use a diffent RawPrinterHelper or bypass the Windows App Certification Kit in some way?
P.S. I need to publish the app on the Microsoft Store.
If you have already run the WACK test with the release build, then as the error described there are APIs not supported for the windows store app. More details please reference Supported API test.
Is there a way to use a diffent RawPrinterHelper or bypass the Windows App Certification Kit in some way
For print relative features in windows store app, please follow this tutorial and the official sample. This provide alternatives to the windows print relative APIs. Details please reference Printing and documents section of Alternatives to Windows APIs in Universal Windows Platform (UWP) apps.
If you want the print feature with no print dialog you may reference this thread.
Guideline 2.5.1 - Performance - Software Requirements
Your app uses or references the following non-public APIs:
PrivateFrameworks/Pegasus.framework (PGHostedWindow)
The use of non-public APIs is not permitted on the App Store because
it can lead to a poor user experience should these APIs change.
Continuing to use or conceal non-public APIs in future submissions of
this app may result in the termination of your Apple Developer
account, as well as removal of all associated apps from the App Store.
Next Steps
If you are using third-party libraries, please update to the most
recent version of those libraries. If you do not have access to the
libraries' source, you may be able to search the compiled binary using
the "strings" or "otool" command line tools. The "strings" tool can
output a list of the methods that the library calls and "otool -ov"
will output the Objective-C class structures and their defined
methods. These tools can help you narrow down where the problematic
code resides. You could also use the "nm" tool to verify if any
third-party libraries are calling these APIs.
Can anyone please tell how I solve this error? I am not using Pegasus framework at all.
And also which apis consider as non-public?
I think you have used the private framework. The file PGHostedWindow is of Pegasus.framework and may be this file has been used in your app.
You can see the following link which show which file are available in Pegasus.framework:-
https://github.com/JaviSoto/iOS10-Runtime-Headers/tree/master/PrivateFrameworks/Pegasus.framework
You can also see the list of Private Framework on GitHub in the following link:-
https://github.com/nst/iOS-Runtime-Headers/tree/master/PrivateFrameworks
The non-public API refers to Apple API methods that are not documented and offered to the programmer.
Apple does not guarantee that this part of the API will work in future upgrades. These API can freely change this part.
I have some debugging code that I want to run when my app is either running in the simulator, or running on a development device (with or without debugger attached). I don't want this debugging code to run when the app is running on a device after being downloaded from the app store.
Is there any easy way to achieve this?
Note: The above-mentioned code will be in a library that will be used by other developers, so I would prefer to use some code that I can embed in this library, without requiring any further action from the developers using the library.
Although my library is a C# library (Xamarin.iOS), any Objective-C, Swift, or Xamarin.iOS answers would all be useful.
When you're running it on the simulator or in Xcode, you can set the Scheme to debug and just put if-statments in. When it runs from the store it won't be in debug mode unless you've hard coded that somewhere.
To answer your question directly: No you're not able to detect the apps source (App Store Vs Xcode deployment) as far as I know.
You can use DEBUG macro, it's defined in Objective-C projects for debug builds. But better way is to use your own macro to enable additional logging. Add information about this macro to docs and developer will decide to enable logging or not by defining it in his project. Also how to set preprocessor macros I described in this answer.
I share a framework between an app and it's action extension. The framework uses API that is not available to extensions.
My question is: Is the app going to get rejected if I keep there references to APIs such as UIApplication.sharedApplication without actually calling them (setting “Require Only App-Extension-Safe API” to NO), or do I need to completely remove any references from the code (i.e. using #ifdef)?
Yes it will be rejected even if it references restricted APIs. We are going through the same process to remove such calls in our framework, alternatively you can have two targets for your framework, one extension-safe and one not with #ifdef guards.
Apple docs: (https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html)
If you have a custom framework that does contain such APIs, you can
safely link to it from your containing app but cannot share that code
with the app’s contained extensions. The App Store rejects any app
extension that links to such frameworks or that otherwise uses
unavailable APIs."
Update for iOS 9: Apple is removing access to invalid frameworks for specific targets, so you won't be able to reference unavailable APIs regardless, and will have to follow what the accepted answer states.
-- Original Answer --
If it's not a huge inconvenience, it's probably best to #ifdef around the references. It will make your code more forward-compatible in the event Apple ever decides in the future to break compilation if your extension references the restricted API (much like they did with trying to get the UUID of the device).
In addition, this will make your framework usable in other scenarios where you might not have UIKit access, like on OS X.