Você pode construir bibliotecas dinâmicas para iOS e carregá-las em tempo de execução?

114

As bibliotecas dinâmicas são compatíveis com iOS (iPhone / iPad)?

No Xcode, tentei criar um novo projeto -> Framework e Biblioteca -> Biblioteca Cocoa (dinâmico) . Nas configurações do projeto, defini o Base SDK como iOS device 4.1e o destino iOS4.1, mas há um erro de compilação:

target especifica o tipo de produto 'com.apple.product-type.library.dynamic', mas não existe esse tipo de produto para a plataforma 'iphonesimulator' ".

A compilação que selecionei é Simulator -> Debug -> i386 .

user510951
fonte
4
iOS8 + suporta frameworks baseados em biblioteca compartilhada.
eonil
1
@Eonil, você pode explicar melhor? Eu gostaria de saber mais sobre isso, um artigo ou link para alguma informação seria muito apreciado.
Maxim Chetrusca

Respostas:

105

No momento em que esta pergunta foi feita, as bibliotecas dinâmicas não eram suportadas pelo iOS e resultariam na rejeição do seu aplicativo. Apenas bibliotecas estáticas são permitidas.

No entanto, no iOS8 você pode usar bibliotecas e estruturas dinâmicas. Deve "simplesmente funcionar"

DarkDust
fonte
14
Alguém sabe por quê? Para mim, parece completamente insano.
Erik de Castro Lopo
73
@Erik de Castro Lopo: O motivo é a segurança: como uma biblioteca dinâmica pode ser carregada e descarregada em tempo de execução, você pode baixar código executável adicional e carregá-lo (pense em um plug-in). Isso pode ser comprometido por um hacker e, então, ter um código malicioso em execução no seu telefone é uma coisa muito ruim. Também seria possível adicionar recursos não aprovados a um aplicativo aprovado. Resumindo: neste ambiente, a Apple considera o link dinâmico como uma caixa de Pandora que deve ser estritamente controlada, caso contrário, poderia comprometer a segurança e concordo que faz sentido no telefone .
DarkDust
6
Estou desenvolvendo um aplicativo interno que não será distribuído pela AppStore, portanto, não me importo com as restrições da Apple para a AppStore. É tecnicamente possível criar uma biblioteca dinâmica para aplicativos iOS?
Aliaksei,
3
@Aliaksei: Tecnicamente, sim, ou você não conseguiria se conectar às bibliotecas da Apple. O suporte da biblioteca dinâmica AFAIK é quase igual ao do Mac OS X. No entanto, o Xcode não oferece suporte, mas parece que você pode usar bundles. Veja este artigo .
DarkDust
3
Não suportado não é o mesmo que não permitido.
dtech
162

Eu realmente não estou em desacordo com a resposta de DarkDust , mas se eu pode canalizar o meu interior Bill Clinton, isso depende do que o significado suportado é :)

A Apple não quer que você faça isso para aplicativos da App Store, mas o sistema operacional certamente permite. Aplicativos Jailbreak usam essa técnica o tempo todo. Basicamente, você usa uma técnica padrão do UNIX para abrir dinamicamente uma estrutura / biblioteca e, em seguida, usa as coisas nela. A função dlopen permite que você abra a biblioteca passando o caminho para essa estrutura , ou dylib. De alguns documentos para a construção de aplicativos jailbreak , aqui está um exemplo de chamada de uma init()função implementada dentro do seu próprio dylib separado:

#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);
    }
}

Além disso, a restrição padrão contra permitir que você crie um projeto de biblioteca dinâmica para iOS é algo no Xcode que você tem a capacidade de substituir editando alguns arquivos xml XCode:

Construir e usar dylib no iOS

Depois de fazer isso, você pode construir uma biblioteca normal do iOS .dylib e usá-la de acordo com o código de exemplo acima. (sim, você provavelmente terá que desbloquear esse recurso novamente sempre que instalar uma nova versão do XCode).

Portanto, não é uma limitação técnica, mas uma limitação da política da App Store. Se você não está limitado à App Store, você pode fazer isso. Observe que essa técnica não requer jailbreak, embora se o aplicativo for sandbox, isso pode limitar de onde dylibs podem ser carregados.

Editar: para garantir que essas informações não sejam perdidas para uma futura podridão de links, aqui está o conteúdo do link que forneci sobre como habilitar dylibs iOS no Xcode. ( Observação: este processo ainda funciona no Xcode 4, mas veja o (s) comentário (s) abaixo para atualizações de caminhos, etc.) A fonte é o blog iOS Place :


O Xcode não permite que você crie dylib para iOS. O aplicativo será rejeitado se não for binário único. Mas eu tenho um aplicativo que possui arquitetura de plug-in para carregar módulos opcionais. Eu só quero um protótipo rápido para provar o conceito antes de transferi-lo totalmente para o iOS. É mais rápido de fazer se dylib pudesse simplesmente funcionar. Portanto, este post mostra como construir e usar dylib, mas esteja ciente de que não será aprovado na App Store. (Testado com Xcode 3.2.4 em 10.6.4)

1. Abra esses arquivos no Property List Editor: /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. Localize o item em “ MacOSX Product Types.xcspec ” que contém o tipo de produto com.apple.product-type.library.dynamice arraste-o para “ iPhone Simulator ProductTypes.xcspec ”.

Captura de tela 1 do Xcode

3. Abra “ MacOSX Package Types.xcspec ” e “ iPhone Simulator PackageTypes.xcspec ” encontrados nos mesmos lugares.

4. Localize o item em “ MacOSX Product Types.xcspec ” que contém o tipo de pacote com.apple.package-type.mach-o-dylibe arraste-o para “ iPhone Simulator PackageTypes.xcspec ”.

Captura de tela 2 do Xcode

5. Repita as etapas para “ iPhoneOS.platform ” e reinicie o Xcode se estiver em execução.

Agora, vamos construir um dylib. Comece com o modelo “ Cocoa Touch Static Library ”. Isso deve incluir o Foundation.framework no projeto. Aqui estão as alterações que fiz na parte superior do modelo para construir o dylib.

1. Abra o arquivo project.pbxproj (encontrado dentro do pacote de arquivos do projeto Xcode) em um Editor de Texto. Pesquise a string “ producttype ”, altere seu valor para com.apple.product-type.library.dynamic;

Agora, abra o projeto com o Xcode, vá para Projeto-> Editar configurações do projeto

2.Diretório de instalação ” definido como @executable_path/porque pretendo colocar o dylib no mesmo diretório que o executável do aplicativo.

3.Mach-O Type ” definido para Dynamic Library

4.Extensão executável ” definida como dylib

5.Prefixo executável ” definido como vazio

6. Adicione um ou dois métodos simples à biblioteca e construa-a.

Agora, crie um aplicativo para testá-lo. Desta vez, escolho o aplicativo baseado em visualização . Conecte um UIButton e um UILabel para chamar o lib e mostrar a mensagem de retorno. Você pode baixar o projeto completo TestApp e brincar com ele.

Nate
fonte
2
A partir do XCode 4.5, esses arquivos podem ser encontrados em (por exemplo) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications
Chris Devereux
@ChrisDevereux, obrigado! Eu coloquei uma nota para verificar seu comentário por caminhos atualizados ... que, claro, podem mudar novamente em uma versão futura :)
Nate
3
Esta resposta precisa de mais votos positivos (e deve realmente ser a resposta aceita, mas duvido que o usuário510951 volte depois de ficar afastado do SO por 2 anos). Muito boa resposta Nate!
chown
1
Deve haver algum tipo de substituição principal onde se @chown disser que uma resposta está correta ... está muito bem correta.
Tim
@Panagiotis, por favor poste uma nova pergunta, para que ela possa ser respondida adequadamente. Mostre o código que você está usando e todas as mensagens de erro. Se desejar, você também pode retornar a esta pergunta / resposta. Se você adicionar a tag "iphone-privateapi", eu verei. Você deve declarar que isto não é para a app store, ou as pessoas podem votar para fechar a questão.
Nate
0

Não são permitidas bibliotecas dinâmicas a partir do Xcode 11.4.1 (seu projeto não compilará para todos os destinos). A nova maneira de usar libs / frameworks é o create-xcframework do xcodebuild.

Carla Camargo
fonte