Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using libcurl on iOS 5 as an alternative to NSURLConnection

Update: NSURLConnection now seems to properly support 100-Continue. In any case, this answer contains a link to the script to build libcurl for iOS/OSX.

I'm having a bit of a hard time with NSURLConnection, given that it doesn't support Section 8.2.3 of RFC 2616 (HTTP/1.1).

Basically the client needs to be able to support sending the header Expect: 100-Continue; after sending the request headers, it must wait for a response from the server with the status code 100 before sending the POST/PUT body.

Furthermore, NSURLConnection (and consequently all libs that build on top of it) won't return any response from the server until all data is uploaded - which is a pain since the server may reject the upload right away (invalid credentials, no space, file too large, etc). While it does "work" for small files (content is fully uploaded and delegate method with response is called), on large files instead of getting the error response from the server (which I am positively sure is sent), I just get a "Connection failed" error.

I know libcurl properly supports the 100-Continue spec so I need some help compiling it and getting it up and running on a iOS 5 project.

I started with this post(scroll to bottom) but I couldn't get far...

Made these changes...

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

... but compilation fails with message

(...)
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

I'm using curl 7.21.4, downloaded from Apple's open source site.

So, how can I compile curl and use it on a iOS 5 project, preferably with SSL support?

like image 791
biasedbit Avatar asked Jan 27 '12 20:01

biasedbit


3 Answers

This worked for me with the latest 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
like image 183
Bob Avatar answered Nov 07 '22 03:11

Bob


Important Update for people getting: C compiler cannot create executables
Make sure you install the command line XCode tools...

From XCode menu select: Preferences --> downloads --> Command Line Tools

...and hit "Install" if not installed.

The issue with the above script is that it works with older versions of XCode. If you installed the latest XCode, the location of all the compiler tools will be different. I've changed the script to support both old and new XCode versions, and have some error checking built-in. Does this help?

Below -- I assume SDK version 5.1 -- you may need to modify that...

#!/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
like image 22
Bernie Habermeier Avatar answered Nov 07 '22 05:11

Bernie Habermeier


Execute script with 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
like image 28
Guilhem BERTHALON Avatar answered Nov 07 '22 05:11

Guilhem BERTHALON