Estou tentando criar uma estrutura dinâmica para um aplicativo iOS. Graças à nova versão do Xcode (6), podemos selecionar um Cocoa Touch Framework quando criamos um novo projeto e não há mais necessidade de adicionar um alvo agregado, executar o script e, assim, criar um. Eu não tenho nenhum problema quando eu construo o framework. Mas quando estou tentando usá-lo dentro de um aplicativo iOS, recebo alguns problemas de arquitetura.
ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (arm64): /Library/Frameworks/MyFramework.framework/MyFramework Undefined symbols for architecture arm64: "_OBJC_CLASS_$_MyFrameworkWebService", referenced from: objc-class-ref in AppDelegate.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (armv7): /Library/Frameworks/MyFramework.framework/MyFramework Undefined symbols for architecture armv7: "_OBJC_CLASS_$_MyFrameworkWebService", referenced from: objc-class-ref in AppDelegate.o ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
Bem, tentei alterar as configurações do projeto e do destino da estrutura (Arquiteturas e Construir apenas arquiteturas válidas e Arquiteturas válidas). Eu fiz a mesma coisa para o projeto do aplicativo iOS, mas nada funciona. Eu acho que há algo que eu não entendi.
Por exemplo, quando eu construo uma estrutura para apenas i386 (iOS Simulator), verifique com a linha de comando “xcrun lipo -info MyFramework”, eu tenho um problema que
ld: aviso: ignorando o arquivo /Library/Frameworks/MyFramework.framework/MyFramework, o arquivo foi criado para x86_64, que não é a arquitetura que está sendo vinculada (i386) …
Se alguém puder me ajudar a obter uma estrutura que funcione para todas as arquiteturas iOS, incluindo simuladores.
Com base em todas as respostas, o post sobre raywenderlich.com e a essência criada por Chris Conway I surgiu com isso .
Executando as etapas a seguir, consegui criar uma estrutura do Cocoa Touch (incluindo arquivos Swift e Objective-C) que contém todas as arquiteturas para simulador e dispositivo:
Espero que ajude 🙂
ATUALIZAÇÃO: Corrigido um erro na essência em que os caminhos na etapa 3 estavam incorretos. Graças a Tokuriku !!
UPDATE No Xcode 7 e 8, clique em File> New> Target … e selecione o grupo “Other” para selecionar Aggregate target
Tente as etapas a seguir para criar um espaço de trabalho que contenha um projeto de estrutura e um projeto de aplicativo.
Área de trabalho:
Projeto de estrutura:
Projeto App:
Observe que o exemplo acima demonstra como criar um aplicativo que é executado no simulador . Se você precisar criar uma biblioteca estática universal que seja executada no simulador e nos dispositivos , as etapas gerais serão:
Há boas referências na web sobre isso, aqui por exemplo.
Criar um binário universal para o framework: navegue para o diretório Derived Data, em seguida, / Build / Products , o seguinte comando deve ajudá-lo a criar um binário universal no diretório Products :
lipo -create -output "framework-test-01-universal" "Debug-iphonesimulator/framework-test-01.framework/framework-test-01" "Debug-iphoneos/framework-test-01.framework/framework-test-01"
Observe que o framework-test-01 é o nome do meu projeto de framework.
Defina ONLY_ACTIVE_ARCH=NO
nas Build Settings
do seu projeto.
Abra na pasta de Products
console para o seu framework (você pode abri-lo pela pasta de estrutura aberta e cd ..
de lá)
Execute esse script na pasta Products
. Cria um framework de gordura nesta pasta. (ou manualmente, como explicado abaixo em 4. 5. )
framework_name="${$(basename $(find ./Debug-iphoneos -type d -name '*.framework' -maxdepth 1))%.*}" && \ cp -R Debug-iphoneos/$framework_name.framework ./$framework_name.framework && \ lipo -create -output "$framework_name.framework/$framework_name" "Debug-iphonesimulator/$framework_name.framework/$framework_name" "Debug-iphoneos/$framework_name.framework/$framework_name"
Ou:
Combine esses 2 Frameworks usando lipo por este script (substitua YourFrameworkName
pelo nome do Framework)
lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
Substitua por um novo binário dos frameworks existentes:
cp -R Debug-iphoneos/YourFrameworkName.framework ./YourFrameworkName.framework mv YourFrameworkName ./YourFrameworkName.framework/YourFrameworkName
./YourFrameworkName.framework
– está pronto para usar binário de gordura! Você pode importá-lo para o seu projeto! Para projeto, isso não no xcworkspace
-es:
Você também pode tentar usar essa essência. Mas parece que não funciona para projetos em espaços de trabalho.
A maneira como fiz isso é semelhante ao vladof, mas espero que seja um pouco mais simples. Eu fiz do framework um subprojeto do projeto de aplicativo.
Projeto Framework
Projeto App
Para um aplicativo Obj-C
Para um aplicativo Swift
Ao fazer isso dessa maneira, o aplicativo depende da estrutura, portanto, se você fizer uma alteração nas classs da estrutura, não precisará alterar os alvos para criar a estrutura separadamente; ela apenas compilará a estrutura primeiro e, em seguida, o aplicativo.
Eu mudei o script de alguém um pouco para suportar todas as arquiteturas do Simulador:
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal # make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}" # Step 1. Build Device and Simulator versions xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator VALID_ARCHS="x86_64 i386" BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build # Step 2. Copy the framework structure to the universal folder cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/" # Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" # Step 4. Convenience step to copy the framework to the project's directory cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}" # Step 5. Delete temporary build directory in the project's directory rm -rf "${PROJECT_DIR}/build" # Step 6. Convenience step to open the project's directory in Finder open "${PROJECT_DIR}"
Um vídeo antigo que eu fiz desde o link acima anteriormente não está mais disponível.
Como criar um framework Cocoa Touch usando o Xcode 6
Poucos pontos adicionais em torno da abordagem compartilhada pelo vladof são mais aplicáveis a Frameworks baseados em
Finalmente, consegui que funcionasse para mim! E desculpe pelo grande quadro amarelo, não tenho idéia de como formatá-lo melhor.
A solução veio de Claudio Romandi, mas o script vinculado tem um pequeno problema. Eu não posso comentar sobre o post dele, pois eu preciso da reputação de 50, então não tenho mais escolha a não ser copiar o post dele para ter uma solução completa.
Coloque o seguinte código nele:
#!/bin/sh UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal # make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}" # Step 1. Build Device and Simulator versions xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build # Step 2. Copy the framework structure (from iphoneos build) to the universal folder cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/" # Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" # Step 5. Convenience step to copy the framework to the project's directory cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}" # Step 6. Convenience step to open the project's directory in Finder open "${PROJECT_DIR}"
Selecione o agregado na seleção suspensa de seleção de esquema
O problema era que o diretório do simulador estava apontando para um diretório inexistente, mudando “Framework” para “$ {PROJECT_NAME}” em 2 lugares, deu certo 🙂
Desculpe por deixar este tópico aberto por um longo tempo … Alguns de vocês responderam corretamente à minha pergunta. Quando eu escrevi essa pergunta, não percebi que havia duas fatias em uma estrutura completa (também chamada de gordura) (pronta para uso). Um para os dispositivos iOS e outro para o simulador. Quando descobri que fiz um script usando o comando lipo para fundir as duas fatias e obtive automaticamente uma estrutura completa.