2015/06/06

[iOS][Objective-C][Google App Engine][Python]iOSからBlobstoreを使う

Google App EngineのBlobstore Python API Overviewの説明を見ると、PCないし、スマホwebからのPOSTしかやり方が書いていない。

iOS側からPOST送信でBlobstoreが使えるかどうか検証してみた。

まずサーバーサイド側を下のようにして組んだ。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import webapp2
import json

from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers

from google.appengine.ext import db
from google.appengine.ext import ndb

#--------------------------------------------------------------------
#image登録用のURL作成処理
#--------------------------------------------------------------------
class CreateURLHandler(webapp2.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'
    ret_dict = {
      "url":blobstore.create_upload_url("/create")
    }
    self.response.out.write(json.dumps(ret_dict))

#--------------------------------------------------------------------
#登録処理
#--------------------------------------------------------------------
def create_data(prms):

  hoge = Hoge(
    uploaded_image_key  = prms["uploaded_image_key"],
    comment             = "",
  )
  hoge.put()
 

class CreateDataHandler(blobstore_handlers.BlobstoreUploadHandler):

    def post(self):

      self.response.headers['Content-Type'] = 'text/plain'
      ret_dict = {}

      try:

        uploaded_image_key = self.get_uploads()[0]
        uploaded_image_key = uploaded_image_key.key()

        post_data = {
          "uploaded_image_key":uploaded_image_key
        }

        try:

          ndb.transaction(lambda: create_data(post_data),xg=True)
          ret_dict["hoge_id"] = "hoge_id"

        except db.TransactionFailedError(),val:
          ret_dict["errors"] = [{"message":("%s" % val),"code":6}]
        except NameError,val:
          ret_dict["errors"] = [{"message":("%s" % val),"code":7}]
        except db.BadRequestError(),val:
          ret_dict["errors"] = [{"message":("%s" % val),"code":8}]
        except Exception,val:
          ret_dict["errors"] = [{"message":("%s" % val),"code":9}]
        except:
          ret_dict["errors"] = [{"message":("%s" % val),"code":10}]

      except BaseException,val:
        msg = "".join(map(str,val))
        ret_dict["errors"] = [
          { 
            "message":("%s" % msg),
            "code":11
          }
        ]

      self.response.out.write(json.dumps(ret_dict))


#--------------------------------------------------------------------
#更新処理
#--------------------------------------------------------------------
class UpdateDataHandler(webapp2.RequestHandler):
    def post(self):
      self.response.headers['Content-Type'] = 'text/plain'

      ret_dict = {}


      hoge_id = str(self.request.get('hoge_id',default_value=""))

      try:
        post_data = {
          "comment":comment,
        }
        hoge = Hoge.get_by_id(hoge_id)
        ndb.transaction(lambda: easyupdate_image(hoge,post_data))

      except db.TransactionFailedError(),val:
        ret_dict["errors"] = [{"message":("%s" % val),"code":8}]
      except NameError,val:
        ret_dict["errors"] = [{"message":("%s" % val),"code":9}]
      except db.BadRequestError(),val:
        ret_dict["errors"] = [{"message":("%s" % val),"code":10}]
      except Exception,val:
        ret_dict["errors"] = [{"message":("%s" % val),"code":11}]
      except:
        ret_dict["errors"] = [{"message":"error" ,"code":12}]

      self.response.out.write(json.dumps(ret_dict))

#簡易更新
def easyupdate(hoge_m,prms):
    hoge_m.comment = prms["comment"]
    hoge_m.put()



app = webapp2.WSGIApplication([
    ('/createurl', CreateURLHandler),
    ('/create', CreateDataHandler),
    ('/update', UpdateDataHandler),
], debug=True)
まず、createurlにアクセスしてPOST先のURLを発行する。

次に、発行したURL向けてUIImageのデータを送信する。

最後にupdateアクセスしてその他のデータ(UITextViewなどのテキストデータ)を保存する。


ちなみに、blobstore_handlers.BlobstoreUploadHandlerを継承したクラスは、Blobデータ意外にも
class CreateDataHandler(blobstore_handlers.BlobstoreUploadHandler):

    def post(self):

      self.response.headers['Content-Type'] = 'text/plain'
      ret_dict = {}

      try:

        uploaded_image_key = self.get_uploads()[0]
        uploaded_image_key = uploaded_image_key.key()
        userid = str(self.request.get('userid'))
という形でデータを受け取ることはできるのだが、日本語データなどの受け取りはうまくいかなかったので、別URLでポストする必要があると思った。

リファレンスにはiOSについて何も書かれていなかったのでできるかどうか不安だったけど、無事にできたので、ほっと胸をなでおろした。

0 コメント:

コメントを投稿