Upload an image with Swift & Django REST API framework

This post is about how to simply upload an image via a POST request in Swift. I’m relatively new to Swift and programming for iOS, and there doesn’t seem to be too much documentation about these things around, so I figured I’d share how I did it here, so others may benefit.

Basically wat I was looking to do was POST an UIImage in Swift to a Python / Django written API set up with the Django REST Framework. I use the CreateAPIView, which accepts multipart form data.

1) Django POST API

The image is stored as an ImageField, together with some other customer data params, let’s for simplicity say just name and email. To give you an idea of my Django setup:

models.py


def get_image_path(instance, filename):
    """
    Puts image in MEDIA_ROOT/photos/instance_id/file
    """
    return 'orders/%s/%s' % (instance.id, filename)

class PhotoOrder(models.Model):
    photo = models.ImageField(upload_to=get_image_path)
    email = models.EmailField(max_length=254)
    name = models.CharField(max_length=110)

serializers.py

class OrderSerializer(serializers.ModelSerializer):

    class Meta:
        model = PhotoOrder

    def create(self, validated_data):
        return PhotoOrder.objects.create(**validated_data)

views.py

class OrderList(CreateAPIView):
    serializer_class = OrderSerializer

    def post(self, request, format=None):
        serializer = OrderSerializer(data=request.data) 
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Quite simple and straightforward really, so lets move on to the most interesting part:

2) Upload image via Swift

There are a few posts around how to do this, either by using Swift’s own request structure or by using Alamofire. I found both quite messy and had a hard time getting it working for my situation. Probably because I’m quite inexperienced at Swift. In the end though, I found this repository on Github that worked like a charm in less then 15 lines of code:

https://github.com/sraj/Swift-SRWebClient

func uploadImage(image:UIImage) {
    let imageData:NSData = UIImageJPEGRepresentation(image, 100)
    SRWebClient.POST("http://localhost:8000/api/orders/")
        .data(imageData, fieldName:"photo", data: ["email":"vincentleeuwen@gmail.com","name":"Vincent"])
        .send({(response:AnyObject!, status:Int) -> Void in
            // process success response
        },failure:{(error:NSError!) -> Void in
            // process failure response
        })
    }

You’ll notice that the above code is a slightly adjusted version of the snippets on the Swift-SRWebClient Github page. I’ve replaced NSData.dataWithData with UIImageJPEGRepresentation.as the former is deprecated.

Also, don’t forget to drag SRWebClient.swift into your project folder, otherwise this won’t work :)

Alright, that was it. Hope this will help those looking to do some image uploads! If you’ve got any questions or remarks, feel free to ping me on twitter!

 
119
Kudos
 
119
Kudos

Now read this

Looking back: What I learned in 2013

One of the things I like best about blogging is to write down experiences. By writing things down, I learn from them once more. As such, I could not pass on the opportunity to reflect on some of the things I learned the past year. Some... Continue →