Использование libcurl на iOS 5 в качестве альтернативы NSURLConnection
Обновление: теперь NSURLConnection корректно поддерживает 100-Continue. В любом случае этот ответ содержит ссылку на script для сборки libcurl для iOS/OSX.
Мне немного сложно с NSURLConnection
, учитывая, что он не поддерживает раздел 8.2.3 RFC 2616 (HTTP/1.1).
В основном клиент должен иметь возможность поддерживать отправку заголовка Expect: 100-Continue
; после отправки заголовков запроса он должен дождаться ответа от сервера с кодом состояния 100
перед отправкой телу POST
/PUT
.
Кроме того, NSURLConnection
(и, следовательно, все libs, которые строятся поверх него) не возвратит никакого ответа с сервера до тех пор, пока не будут загружены все данные - это боль, поскольку сервер может сразу же отказаться от загрузки (недействителен учетные данные, отсутствие места, файл слишком большой и т.д.).
Хотя он "работает" для небольших файлов (контент полностью загружен и вызывается метод делегата с ответом), на большие файлы вместо получения ответа об ошибке с сервера (который я уверенно уверен,)), Я просто получаю сообщение "Ошибка подключения".
Я знаю, что libcurl
правильно поддерживает спецификацию 100-Continue
, поэтому мне нужна помощь в ее компиляции и ее запуске и запуске в проекте iOS 5.
Я начал с этот пост (прокрутите вниз), но я не мог далеко продвинуться...
Сделал эти изменения...
export CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2
export CFLAGS="-arch armv7 --sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
export CPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-cpp-4.2
export AR=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar
./configure --disable-shared --without-ssl --without-libssh2 --without-ca-bundle --without-ldap --disable-ldap --host=arm-apple-darwin10 --build=arm-apple-darwin10
make clean
make
ar rv libcurl.armv7.a lib/*.o
... но компиляция завершается с сообщением
(...)
checking for arm-apple-darwin10-gcc... /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2
checking whether the C compiler works... no
configure: error: in `/Users/bruno/Downloads/curl-7.21.4':
configure: error: C compiler cannot create executables
Я использую curl 7.21.4, загруженный из Apple сайт с открытым исходным кодом.
Итак, как я могу скомпилировать curl и использовать его в проекте iOS 5, желательно с поддержкой SSL?
Ответы
Ответ 1
Это работало для меня с последним SDK:
#!/bin/sh
export SDK=5.0
buildit()
{
target=$1
platform=$2
export CC=/Developer/Platforms/${platform}.platform/Developer/usr/bin/gcc
export CFLAGS="-arch ${target} -isysroot /Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}${SDK}.sdk"
export CPP="/Developer/Platforms/${platform}.platform/Developer/usr/bin/llvm-cpp-4.2"
export AR=/Developer/Platforms/${platform}.platform/Developer/usr/bin/ar
export RANLIB=/Developer/Platforms/${platform}.platform/Developer/usr/bin/ranlib
./configure --disable-shared --without-ssl --without-libssh2 --without-ca-bundle --without-ldap --disable-ldap \
--host=${target}-apple-darwin10
make clean
make
$AR rv libcurl.${target}.a lib/*.o
}
buildit armv6 iPhoneOS
buildit armv7 iPhoneOS
buildit i386 iPhoneSimulator
lipo -create libcurl.armv7.a libcurl.armv6.a libcurl.i386.a -output libcurl.a
Ответ 2
Важное обновление для людей, получающих: C compiler cannot create executables
Убедитесь, что вы установили инструменты командной строки XCode...
В меню XCode выберите: Preferences --> downloads --> Command Line Tools
... и нажмите "Установить", если он не установлен.
Проблема с приведенным выше script заключается в том, что он работает со старыми версиями XCode. Если вы установили последний XCode, расположение всех инструментов компилятора будет иным. Я изменил script, чтобы поддерживать как старые, так и новые версии XCode, и имеет встроенную встроенную проверку ошибок. Помогает ли это?
Ниже - я предполагаю SDK версии 5.1 - вам может потребоваться изменить это...
#!/bin/bash
set -e
export SDK=5.1
checkExists() {
if [ ! -e $1 ]
then
echo "Didn't find: $1 -- try to locate parts of this to see how to fix the path"
exit 1
else
echo "using $1"
fi
}
buildit() {
target=$1
platform=$2
root="/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer"
oldRoot="/Developer/Platforms/${platform}.platform/Developer"
if [ ! -d "${root}" ]
then
root="${oldRoot}"
fi
if [ ! -d "${root}" ]
then
echo " "
echo "Oopsie. You don't have an iOS SDK root in either of these locations: "
echo " ${root} "
echo " ${oldRoot}"
echo " "
echo "If you have 'locate' enabled, you might find where you have it installed with:"
echo " locate iPhoneOS.platform | grep -v 'iPhoneOS.platform/'"
echo " "
echo "and alter the 'root' variable in the script -- or install XCode if you can't find it... "
echo " "
exit 1
fi
export CC="${root}/usr/bin/gcc"
export CFLAGS="-arch ${target} -isysroot ${root}/SDKs/${platform}${SDK}.sdk"
export CPP="${root}/usr/bin/llvm-cpp-4.2"
export AR="${root}/usr/bin/ar"
export RANLIB="${root}/usr/bin/ranlib"
checkExists ${CC}
checkExists ${root}/SDKs/${platform}${SDK}.sdk
checkExists ${CPP}
checkExists ${AR}
checkExists ${RANLIB}
./configure --disable-shared --without-ssl --without-libssh2 --without-ca-bundle --without-ldap --disable-ldap --host=${target}-apple-darwin10
make clean
make
$AR rv libcurl.${target}.a lib/*.o
}
buildit armv6 iPhoneOS
buildit armv7 iPhoneOS
buildit i386 iPhoneSimulator
lipo -create libcurl.armv7.a libcurl.armv6.a libcurl.i386.a -output libcurl.a
Ответ 3
Выполните script с помощью sudo:
$ sudo library.sh
my script:
#!/bin/sh
export SDK=5.0
buildit()
{
target=$1
platform=$2
export CC=/Developer/Platforms/${platform}.platform/Developer/usr/bin/gcc
export CFLAGS="-arch ${target} -isysroot /Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}${SDK}.sdk"
export CPP="/Developer/Platforms/${platform}.platform/Developer/usr/bin/llvm-cpp-4.2"
export AR=/Developer/Platforms/${platform}.platform/Developer/usr/bin/ar
export RANLIB=/Developer/Platforms/${platform}.platform/Developer/usr/bin/ranlib
sudo ./configure --disable-shared --without-ssl --without-libssh2 --without-ca-bundle -- without-ldap --disable-ldap \ --host=${target}-apple-darwin10
make clean
make
$AR rv libcurl.${target}.a lib/*.o
}
buildit armv6 iPhoneOS
buildit armv7 iPhoneOS
buildit i386 iPhoneSimulator
lipo -create libcurl.armv7.a libcurl.armv6.a libcurl.i386.a -output libcurl.a
Ответ 4
Проблема заключается в следующем:
C compiler cannot create executables
Причина:
Ваш компилятор C для iOS, arm-apple-darwin9-gcc, является кросс-компилятором: он работает на ПК, но генерирует код для iDevices. Таким образом, он не может использовать собственные ресурсы программирования (библиотеки, файлы заголовков). Вы должны сказать, где найти iOS собственные заголовки и библиотеки. Вы можете сделать это, передав ему опцию -isysroot=/path/to/iOS_SDK/
. Например, следующее не будет работать из коробки:
/path/to/arm-apple-darwin10-gcc hello.c -o hello
Но следующее:
/path/to/arm-apple-darwin10-gcc -isysroot /Developer/Platforms/iPhoneOS.platform/SDKs/iPhoneOS5.0.1.sdk hello.c -o hello
Я не использую Xcode, также у меня нет Mac, поэтому я не знаю точное местоположение iOS toolchain sysroot, но может быть что-то вроде того, что было в приведенной выше команде.
И как использовать все это при настройке? Ну, у вас есть 3 этапа компиляции: предварительная обработка, компиляция и привязка. Итак, вы должны сообщить препроцессору и компилятору, где он может найти заголовки, и компоновщик, где он может найти библиотеки. (В частности, вы должны забыть сказать препроцессору, где находится ваш sysroot). Итак, сделайте что-нибудь вроде этого:
export CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2
export CFLAGS="-arch armv7 -isysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
export CPPFLAGS="-isysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
export LDFLAGS="-arch armv7 -isysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
export CPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-cpp-4.2
export AR=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar
./configure --disable-shared --without-ssl --without-libssh2 --without-ca-bundle --without-ldap --disable-ldap --host=arm-apple-darwin10 --build=arm-apple-darwin10
make
sudo make install
Ответ 5
"Я все еще получаю ту же ошибку," компилятор C не может создавать исполняемые файлы ": |" Просто запустите. /configure как root (sudo./configure....)
Ответ 6
Я создал проект на GitHub, который строит curl (только для HTTP) с SSL и без него (GnuTLS и OpenSSL). Осталось много комментариев на месте, поэтому должно быть достаточно легко, чтобы кто-либо мог изменить его в соответствии с его конкретными потребностями.
Ответ 7
Этот script работал у меня со средой Xcode 4.4.1 (извините мои почти несуществующие навыки sh):
#!/bin/sh
#run with sudo
export OSSDK="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/"
export SIMSDK="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/"
export SDKROOT=$OSSDK
export VER=5.1
buildit()
{
target=$1
platform=$2
export CC="${root}/usr/bin/llvm-gcc-4.2"
export CFLAGS="-arch ${target} -isysroot=${PLATFORM}/${SDKROOT}/${PLATFORM}${SDK}.sdk"
export CPPFLAGS="-isysroot=${SDKROOT}/${platform}${SDK}.sdk"
export LDFLAGS="-arch ${target} -isysroot=${SDKROOT}/${platform}${SDK}.sdk"
export CPP="${root}/usr/bin/llvm-cpp-4.2"
export AR="${root}/usr/bin/ar"
export RANLIB="${root}/usr/bin/ranlib"
sudo ./configure --disable-shared --without-ssl --without-libssh2 --without-ca-bundle --without-ldap --disable-ldap --host=arm-apple-darwin10 --build=arm-apple-darwin10
sudo make clean
sudo make
sudo $AR rv libcurl.${target}.a lib/*.o
}
# Run once for armv6 & armv7, then for i386. Comment lines alternatively, as explained below.
# Run for armv6 & armv7 by changing line 6 to "export SDKROOT=$OSSDK". Comment line with "buildit i386..."
#buildit armv6 iPhoneOS
#buildit armv7 iPhoneOS
# Run for i386 by changing line 6 to "export SDKROOT=$SIMSDK". Comment line with buildit "armv6..." and "buildit armv7..."
buildit i386 iPhoneSimulator
sudo lipo -create libcurl.armv7.a libcurl.armv6.a libcurl.i386.a -output libcurl.a