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!