is dlopen use inside a static library in iOS allowed - ios

I am working with a fat static library that uses dlopen() to load interal modules(.so) files inside the static library. On stackoverflow, developers says dlopen() is a private API.
In this case is it fine to use dlopen() or being an private API it shouldn't be used in user libraries irrespective of the library nature i.e static/dynamic.
If I can't use the dlopen() then can someone point to any resource for alternative way to accomplish the same task.
Note: This is regarding baresip BSD library. (http://www.creytiv.com/)
Update: The library is first trying to load all configured modules statically and if it fails then it is trying to load them dynamically using dlopen(). so removing the dynamic loading code will resolve my problem.

dlopen is not allowed on the iOS versions < iOS 8. See e.g. here.

Using dlopen with literal parameters has always been OK.
dlopen is documented, so it’s not a private API. Just type man dlopen in your terminal, or see App Extension Programming Guide > Handling Common Scenarios, or Dynamic Library Usage Guideline >1, 2.
If you try to use dlopen with code signed by you but not included in the app reviewed, you are infringing App Review Guidelines 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, including other apps.
and you may get a message like this:
Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with App Store Review Guideline 2.5.2 and section 3.3.2 of the Apple Developer Program License Agreement.
This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes. This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior and/or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.

Related

Does iOS lost most of the advantage of using dynamic frameworks?

Does iOS lost most of the advantage of using dynamic frameworks?
Since iOS will copy all the dynamic frameworks needed into the app bundle, it doesn't share dynamic frameworks between apps and save memory. Except for sharing memory with the main app and its extensions.
App using dlOpen can not ship to App Store. Which means Apple disallow dynamic framework from being used officially.
The old Apple document says dynamic frameworks save app launch time, but the new document says they don't. Is the old document outdated?
Here is the comparision:
make the app launch faster and use less memory once it’s launched
Load fewer dynamic libraries. This can be one of the longest parts of an app’s total launch time. Apple recommends using only up to six non-system frameworks
See if you can remove any of the dynamic libraries you’re using by replacing them with static versions or compiling their sources directly.
Does it mean if we use dynamic frameworks with dlOpen to load them later, it will be faster than static frameworks? Because the dynamic frameworks take some time to link in the begining, but they save more time in loading into memory. And loading time of static frameworks is greater then the linking time in dynamic frameworks. Is that true?
So it looks like there is none adavantage of using dynamic frameworks on iOS, right?
And how about on macOS and Linux? Do dynamic frameworks have any advantage? If so, how do they work?
You're correct in all of this. Non-system (i.e. not provided by Apple) dynamic libraries going to be less efficient in pretty much every way on iOS. They give you no space or memory savings, and they cost you at launch time.
The old Apple document you reference was almost entirely written before the iPhone. It's referring to late-loading libraries in Mac apps, which can help launch time.
On systems with shared libraries (or when using system libraries, which are shared on iOS), dynamic libraries save disk space, and can be shared between processes which saves memory and load time (because it's already loaded by some other process). But if you don't share the library, you can't really get any of those benefits. On systems that allow runtime loading of libraries (not iOS), dynamic libraries can delay the cost of loading seldom-used code, possibly indefinitely (if the code is never used). Furthermore, it opens up the opportunities for plugins and other extensions.

Why Apple disallows static library in a framework?

As in the Appole doc
it states that:
If you are building your own static library and using shell scripts to
package it in a .framework directory, you need to migrate to building
a framework with a dynamic library instead, as this is the correct way
to build a framework. Static frameworks are not a supported way of
sharing static libraries.
Why Apple disallows static library in a framework?
And is it a contraction of this post ?
Or maybe that post confuses static library and static framework?
All frameworks in iOS are dynamic, right?
Apple said:
A framework is a hierarchical directory that encapsulates a dynamic library, header
files, and resources, such as storyboards, image files, and localized
strings, into a single package. Apps using frameworks need to embed
the framework in the app's bundle.
A static library has to be loaded when app launches, without considering wether if its required right away or not. At the other hand a dynamic library is loaded only when it is required, hence improving the launch timings of the app and decreasing the memory pressure of the phone.
As an example consider I am using an e-commerce app which also allows to scan barcode and give details about the products. Now when I launch the app, I won't need the barcode functionality rightaway. I need to land inside the app first and start shopping. When I need to scan some barcode, I am happy to wait and let the framework loaded then but not at the start of the app.
Here is how Apple says this in its documentation:
Two important factors that determine the performance of apps are their launch times and their memory footprints. Reducing the size of an app’s executable file and minimizing its use of memory once it’s launched make the app launch faster and use less memory once it’s launched. Using dynamic libraries instead of static libraries reduces the executable file size of an app. They also allow apps to delay loading libraries with special functionality only when they’re needed instead of at launch time. This feature contributes further to reduced launch times and efficient memory use.
Documentation link: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html

Can Cocoapods support using a shared framework in both an iOS app and iOS extension where the shared framework uses APIs that aren't extension-safe?

I support a suite of related iOS apps, some of which make use of extensions (WatchKit and Today Widget). All of these apps and extensions make use of a shared private framework I've built up over time for handling certain workflows around authentication and common business logic. This framework is maintained as a private pod.
Recently, I've run into a problem where I'd like to add a method to the framework that's only really useful for the iOS apps (extensions don't need it) that uses certain APIs that are unavailable to extensions (such as [UIApplication sharedApplicaion]). I'd like to get the usual benefit of shared code, where this is implemented in only one place (the shared framework) for all my various apps to leverage. However, I can't find a way to conditionally include that method for just the apps and not the extensions without getting a compile-time error.
Normal recommendations around this problem usually suggest the use of a preprocessor macro to opt-out around the problematic code if desired, but that doesn't really work for a shared framework situation. Macros are applied at compile-time, so the shared framework is either going to include that method, or not, and there doesn't seem to be a runtime solution to optionally exclude it. If it's included, the extensions can't compile. If it's not included, my apps can't make use of the feature.
I also started investigating if there was some way that Cocoapods could automatically make two versions of the framework, one to be used by the apps, and one by the extensions, but this would seem to introduce problems around duplicate symbols, and generally doesn't seem supported.
Are there any other suggestions for how to handle this, apart from just extracting out the problematic functionality into a different framework? (I really would prefer to just share one)

is "connected" a private api?

Is "connected" a private API? apple told me so.
Appstore was saying I have used a private API when I submit my app :
Performance - 2.5.1
Your app still uses or references the following non-public APIs:
connected
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.
Next Steps
Please revise your app to remove any non-public APIs. If you have
defined methods in your source code with the same names as the
above-mentioned APIs, we suggest altering your method names so that
they no longer collide with Apple's private APIs to avoid your
application being flagged in future submissions.
Additionally, 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.
Is this sure? or they made a mistake?
Thank you very much!

Modules in IOS with Air app

We have a problem in our company with an application and would like to advise us an optimal solution, the point is that we have an application for tablets made with Flex mobile, our application can open modules in execution time downloading it from a server, these modules are opened perfectly with AIR or Android but in IOS is not possible, that's not working. Some solutions for us to have the extra functionality that provide these modules have occurred, are as follows:
1. Create a library for each extra functionality of each client and import all of them in the main application project.
2. Create a unique library with the functionality of all clients and then, import it in the main application project.
3. Create as many native extensions (ANE) and functionalities as are required by our different customer and import them into our application.
I would like to know which solution is optimal because in the future we can get 100 customers and maybe too much functionality may slow down the application.
Thank you very much.
Apple does not allow dynamic linking at runtime. Modules are executable code and need to be bundled at build time, only then they can be loaded from the bundle.
Otherwise you could circumvent the AppStore and add any, potentially harmful code at execution time.

Resources