Puoi creare librerie dinamiche per iOS e caricarle in fase di esecuzione?


114

Le librerie dinamiche sono supportate su iOS (iPhone / iPad)?

In Xcode, ho provato a creare un Nuovo progetto -> Framework e libreria -> Cocoa Library (dinamico) . Nelle impostazioni del progetto, ho impostato Base SDK su iOS device 4.1e destinazione iOS4.1, ma ha un errore di compilazione:

target specifica il tipo di prodotto "com.apple.product-type.library.dynamic", ma non esiste un tipo di prodotto simile per la piattaforma "iphonesimulator" ".

La build che ho selezionato è Simulator -> Debug -> i386 .



4
iOS8 + supporta framework basati su libreria condivisa.
eonil

1
@Eonil, puoi approfondire questo? Vorrei saperne di più, un articolo o un collegamento ad alcune informazioni sarebbe molto apprezzato.
Maxim Chetrusca

Risposte:


105

Al momento in cui è stata posta questa domanda, le librerie dinamiche non erano supportate da iOS e la tua app verrà rifiutata. Sono consentite solo librerie statiche.

Tuttavia, in iOS8 puoi utilizzare librerie e framework dinamici. Dovrebbe "funzionare"


14
Qualcuno sa perché è così? A me sembra completamente folle.
Erik de Castro Lopo

73
@Erik de Castro Lopo: Il motivo è la sicurezza: poiché una libreria dinamica può essere caricata e scaricata in fase di esecuzione, è possibile scaricare codice eseguibile aggiuntivo e caricarlo (si pensi al plug-in). Questo potrebbe essere compromesso da un hacker e quindi l'esecuzione di codice dannoso sul tuo telefono è una cosa molto brutta. Consentirebbe inoltre di aggiungere funzionalità non approvate a un'app approvata. In breve: in questo ambiente, Apple considera il collegamento dinamico come una scatola di Pandoras che deve essere strettamente controllata, altrimenti potrebbe compromettere la sicurezza e sono d'accordo che abbia senso al telefono .
DarkDust

6
Sto sviluppando un'app interna che non verrà distribuita tramite AppStore, quindi non mi interessano le restrizioni di Apple per AppStore. È tecnicamente possibile creare una libreria dinamica per app iOS?
Aliaksei

3
@Aliaksei: Tecnicamente sì, altrimenti non saresti in grado di collegarti alle librerie di Apple. Il supporto per le librerie dinamiche AFAIK è più o meno lo stesso di Mac OS X. Tuttavia, Xcode non lo supporta, ma sembra che tu possa usare i bundle. Vedi questo articolo .
DarkDust

3
Non supportato non equivale a non consentito.
dtech

162

Io non sono davvero in disaccordo con la risposta di DarkDust , ma se posso incanalare la mia interna Bill Clinton, dipende da quale sia il significato di sostegno è :)

Apple non vuole che tu lo faccia per le app dell'App Store, ma il sistema operativo lo consente sicuramente. Le app di jailbreak utilizzano sempre questa tecnica. Fondamentalmente usi una tecnica UNIX standard per aprire dinamicamente un framework / libreria, e quindi usare le cose in esso. La funzione dlopen ti permette di aprire la libreria passando il percorso a quel framework , o dylib. Da alcuni documenti per la creazione di app di jailbreak , ecco un esempio di chiamata di una init()funzione implementata all'interno del tuo dylib separato:

#include <dlfcn.h>

initWrapper() {
    char *dylibPath = "/Applications/myapp.app/mydylib2.dylib";

    void *libHandle = dlopen(dylibPath, RTLD_NOW);
    if (libHandle != NULL) {
        // This assumes your dylib’s init function is called init, 
        //    if not change the name in "".
        void (*init)() = dlsym(libHandle, "init");
        if (init != NULL)  {
            init();
        }
        dlclose(libHandle);
    }
}

Inoltre, la restrizione predefinita che impedisce di creare un progetto di libreria dinamica per iOS è qualcosa in Xcode che hai la possibilità di sovrascrivere modificando alcuni file xml XCode:

Crea e usa dylib su iOS

Dopo averlo fatto, puoi creare una normale libreria iOS .dylib e usarla secondo il codice di esempio sopra. (sì, probabilmente dovrai sbloccare nuovamente questa funzionalità ogni volta che installi una nuova versione di XCode).

Quindi, non è una limitazione tecnica, ma una limitazione dei criteri dell'App Store. Se non sei limitato all'App Store, puoi farlo. Tieni presente che questa tecnica non richiede il jailbreak, sebbene se l'app è in modalità sandbox, potrebbe limitare la posizione da cui è possibile caricare i dylib.

Modifica: per assicurarti che queste informazioni non vengano perse per la futura decomposizione dei link, ecco il contenuto del link che ho fornito su come abilitare i dylibs iOS in Xcode. ( Nota: questo processo funziona ancora su Xcode 4, ma vedi i commenti di seguito per gli aggiornamenti ai percorsi, ecc.) La fonte è il blog iOS Place :


Xcode non ti consente di creare dylib per iOS. L'app verrà rifiutata se non è un binario singolo. Ma ho un'applicazione che ha un'architettura plug-in per caricare moduli opzionali. Voglio solo un prototipo veloce per dimostrare il concetto prima di portarlo completamente su iOS. È più veloce da fare se dylib potesse semplicemente funzionare. Quindi, questo post mostra come creare e utilizzare dylib, ma tieni presente che non sarà approvato per App Store. (Testato con Xcode 3.2.4 su 10.6.4)

1. Aprire questi file nell'Editor elenco proprietà: /Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec e /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications/ / iPhone Simulator ProductTypes.xcspec

2. Individua l'elemento in " MacOSX Product Types.xcspec " che contiene il tipo di prodotto com.apple.product-type.library.dynamice trascinalo su " iPhone Simulator ProductTypes.xcspec ".

Screenshot di Xcode 1

3. Apri " MacOSX Package Types.xcspec " e " iPhone Simulator PackageTypes.xcspec " che si trovano negli stessi posti.

4. Individua l'elemento in " MacOSX Product Types.xcspec " che ha il tipo di pacchetto com.apple.package-type.mach-o-dylibe trascinalo su " iPhone Simulator PackageTypes.xcspec ".

Screenshot di Xcode 2

5. Ripeti i passaggi per " iPhoneOS.platform " e riavvia Xcode se era in esecuzione.

Ora, costruiamo un dylib. Inizia con il modello " Cocoa Touch Static Library ". Ciò dovrebbe includere il Foundation.framework nel progetto. Ecco le modifiche che ho apportato sopra il modello per creare dylib.

1. Aprire il file project.pbxproj (che si trova all'interno del pacchetto di file di progetto Xcode) in un editor di testo. Cerca la stringa " producttype ", cambia il suo valore in com.apple.product-type.library.dynamic;

Ora apri il progetto con Xcode, vai su Progetto-> Modifica impostazioni progetto

2. " Directory di installazione " impostato su @executable_path/perché ho intenzione di inserire dylib nella stessa directory dell'eseguibile dell'app.

3.Mach-O Type ” impostato su Dynamic Library

4. " Estensione eseguibile " impostata su dylib

5. " Prefisso eseguibile " impostato su vuoto

6. Aggiungere uno o due metodi semplici alla libreria e crearla.

Ora crea un'app per testarla. Questa volta, scelgo l' applicazione basata sulla visualizzazione . Collega un UIButton e un UILabel per chiamare la lib e mostrare il messaggio di ritorno. Puoi scaricare il progetto completo TestApp e giocare con esso.


2
A partire da XCode 4.5, questi file possono essere trovati in (es.) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications
Chris Devereux

@ChrisDevereux, grazie! Ho inserito una nota per controllare il tuo commento per i percorsi aggiornati ... che ovviamente potrebbe cambiare di nuovo in una versione futura :)
Nate

3
Questa risposta richiede più voti positivi (e dovrebbe essere davvero la risposta accettata, ma dubito che user510951 tornerà dopo essere stato lontano da SO per 2 anni). Risposta molto bella Nate!
chown

1
Dovrebbe esserci una sorta di sovrascrittura principale in cui se @chown dice che una risposta è corretta ... è dannatamente corretta.
Tim

@Panagiotis, per favore posta una nuova domanda, in modo che possa essere affrontata correttamente. Mostra il codice che stai utilizzando e tutti i messaggi di errore. Se lo desideri, puoi anche ricollegarti a questa domanda / risposta. Se aggiungi il tag "iphone-privateapi", lo vedrò. Dovresti affermare che questo non è per l'app store, altrimenti le persone potrebbero votare per chiudere la domanda.
Nate

0

A partire da Xcode 11.4.1 le librerie dinamiche non sono consentite (il tuo progetto non verrà compilato per tutte le destinazioni). Il nuovo modo di usare libs / frameworks è create-xcframework da xcodebuild.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.