Xcode4 & Unfuddle(git)でバージョン管理を行う

まず、
http://blog.katsuma.tv/2009/02/first_github.html
のページの「SSH公開鍵をgithubに登録」という所に、
keyの作り方が書いてあります。

これを、Unfuddleの自分のユーザー名の右側の「Edit」を押した先の
「Public Keys」に登録します。


■既にあるプロジェクトをgitリポジトリに追加する場合

※既にリポジトリにあり、xcodeに取り込みたいだけの場合、
手順7からで大丈夫です。


この場合、xcodeだけでやる方法がわからなかったので、
SourceTreeというフリー(但しアカウントを作る必要はある)の
バージョン管理ソフトを使いました。


・1
SourceTreeを立ち上げ、
「ブックマーク」ウインドウから「リポジトリを追加」を選択。

・2
「ソースパス/URL」の欄には、
unfuddleに表示されている
「git@xxxxx.unfuddle.com:xxxxx/xxx.git」
のような指定のアドレスをペースト。

その後「クローン」ボタンが押せるようになるので選択。

・3
「ブックマーク」ウインドウに新しいプロジェクトが現れました。
また、最初の、まだ何もアップロードしていない状態の物が、
ローカルにコピーされました。

・4
このフォルダに、gitで管理したい、xcodeのプロジェクトフォルダの中身を全てコピー。

・5
「ブックマーク」ウインドウに現れた新しいプロジェクトを開き、
「作業ツリー」に出ているファイルを全て選択し、
「追加」ボタンを押し、その後「コミット」ボタンを押し、一旦ローカルにコミットする。

コミットメッセージは
「added; 最初のアップロード。」という感じでしょうか。

(左側のペインの
「ブランチ master」
と出ている所をクリックすると、現状の状態がわかります。)

・6
「プッシュ」ボタンを押し、
中のウインドウで「プッシュしますか?」と書かれているチェックボックスをチェックする。
その後「OK」ボタンを事でプッシュされ、
unfuddle上からも確認出来るかと思います。
このアップロードされた物を、xcode側からcloneし、認識させます。

・7
welcomウインドウの左側の「Connect to a repositry」を選択。

Locationには手順2と同じ物を入れます。
「Clone」が押せるようになるので選択、
場所を選択するウインドウが出るので選択し、
「Clone」を押すことで、ファイルがコピーされます。

無事、File-Source Control-Repositries..で出るウインドウの中に追加されているかと思います。


■Xcode上で新規にプロジェクトを作る際、
「Create local git repository for this project」
のチェックを入れていて、既にローカルでの管理は行われている場合

・1
File-Source Control-Repositries..に既に出ているので、作成したプロジェクトの名前の、
「Remotes」を選択し、画面下に出る「Add Remote」を選択。

出たウインドウのRemote Nameには任意の名前、
Locationには、unfuddleに表示されている
「git@xxxxx.unfuddle.com:xxxxx/xxx.git」
のような指定のアドレスをペースト。

・2
「Create」が押せるようになるので選択。

後は普通にFile-Source Control-pushを選択し、アップしていくだけです。
(選択した後、若干、サーバの認識に時間がかかり、初めの数秒、
「Repository is offline」とでますが、その後すぐに「Repository is online」と復帰します)

| | コメント (1) | トラックバック (0)

【エンジニアカフェEvent】エンジニアカフェ× CyberX 技術勉強会 #2  ~スマホ対応でJavascript、HTML5はどう使う?~ に行ってきました

【エンジニアカフェEvent】エンジニアカフェ× CyberX 技術勉強会 #2  ~スマホ対応でJavascript、HTML5はどう使う?~
http://www.pasonatech.co.jp/event/index.jsp?no=3434&key=caf
の勉強会に行ってきました。

家に帰ってblogに書くまでが勉強会!ということで、まとめてみました。

「事例の発表」ではなく、Tipsを多く語っていただいたので、
非常に参考になりました(*゚▽゚)ノ


--------------------
■アニメーションのオーサリングから、専用ツールを使うパターン

現状、メジャーどころでは
・adobe edge(JQueryベース)
・sencha animator
・hype
がある。


■アニメーションの方法は2通りある。

・DOMベースで作る
domのパラメータを変えてアニメーションさせる

・Canvasベースで作る
マイフレーム書き換える(CanvasにDrawする)、
よくある他のプラットフォームのアニメーション描画と同じ感じ。

※透明の画像を重ねていくと、DOMだとかなり重くなる。
※それもあり、現状だと、canvasベースの方が速度が出るのでお勧めとのこと。


■jsのアニメーションに使えるライブラリも、
アニメーション用だけに作られているわけではないが、
以下の物がある。

・enchant.js DOMベース、今度canvasベースの物が出るらしい。
・arctic.js canvasベース、FLASHライク
・easel.js adobeが採用


■FLA、SWFを変換するツールに関して
・swf animator converterという、
swfをマイフレームキャプチャーして、
javascriptで再生させるようなツールもある。

・Swiffy等の変換ツールを使うと、svgで画像が出されるが、
一部、android機種が対応していないので、pngに置き換える必要がある。

・android2.1系にcanvas処理にバグがある!
(拡大回転すると正しく出ないとか)

・FlashForward(カヤック)も検討したが、
グラデーションの変換が上手くいかないので採用を見送った。

・ツールを使ってもandroidでは動かないことがある
(大量に機種があるのでチェックも大変・・)

・Adobe createJSというFLASHからhtml5を出せる物が出るらしいので
それには期待している。


--------------------

■実際にhtml5+javascriptでフィーチャーフォン向けのアプリを、
スマフォWEBアプリに移植した際のTips

・素材pngは表示サイズの2倍で持っている(大きい解像度の時対策)

・User-Agent偽造には、タッチイベントを取得出来ない場合は利用できないようにするとかで対応
(でもこの方法もすり抜けることは可能とのこと・・)

・忘れがちだが、js内のajaxで値を送る際、
そのままではエスケープされていない文字列になってしまっているので、
きちんとエスケープするようにする。

・Reel(グリー)やExGame(モバゲー)は非常に使えるのだが、
それぞれのプラットフォームで動かす時しか使えない・・

・スマートフォンWEBアプリは容量無制限だが、3G回線で悲惨なことになるので、
cssスプライトを使って画像を1枚にまとめ、httpリクエスト減らす。
→css sprite generatorなどの便利ツールもある

・あと画像を利用しないボタン(HTML5+css3)にするとか

・ファイル圧縮ツールを使う
1/3くらい縮むのでオススメ、さらにソースを読みにくくしてくれる

Mlnify PHPで実装された圧縮ツール
YUI Compressor  ←オススメらしいです
Google Closure Compiler

・Apatchにmod_deflateをいれ、
サーバ上で圧縮してからレスポンスを返す方法もある。
この方法は協力で、サイズがおよそ半分くらいに減る。
(※但し、もちろんサーバのCPUを食うので注意)

・時間かかる処理は遅延実行!
firebugなどを使って、レンダリング時にどこに時間がかかっているのか調べて、
重い処理は非同期で実行させる。
bodyのonLoadよりも、
DOMContentLoadedを使う方がコンマ何秒か早いのでオススメとのこと。

・DOM処理はまとめておこなおう
ajax→json取得→for内でappedしているのは、
ループ回数分のレンダリングが発生するので重い。
配列にappedしたいhtmlをため込んで、最後にappendする。
(1000回forで追加していく場合と比べ、2〜5倍ほど早かった)

・xhr(xmlHttpRequest)の連射による描画は止めよう!
間違えて実行してしまったxhrの完了を待ってから、次のxhrが実行されることになってしまう。

なので、止める必要がある場合は、xmlHttpRequest.abort()
で破棄するように。
(サーバに投げられたオブジェクトは、
もちろん生き残ったままになってしまうが・・)

・リアルタイムに合成を必要としないFlashは、
画面のパラパラマンガ再生で乗り切れる。
(swf animator converterを使うと言うこと?)

--------------------

| | コメント (0) | トラックバック (0)

Caused by: android.view.inflatingException: Binary XML file line #N

自作classをlayoutのxmlに指定した時、
Caused by: android.view.inflatingException: Binary XML file line #..
というエラーが起きてしまいました。


その自作classは、Viewを継承したclassで、

package jp.test;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class GraphicView extends View {
public GraphicView(Context context) {
super(context);
}

@Override
public void onDraw(Canvas canvas) {
// 座標系がわかるような罫線を引く
Paint paint = new Paint();
paint.setColor(Color.rgb(255, 255, 0));
paint.setStrokeWidth(10);
canvas.drawLine(10, 40, 300, 70, paint);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
}
}


※↑すみません、<p>タグがどうやっても入ってしまうので、除いてご利用いただければと思いますm(_ _)m

という中身でした。
この問題は、



package jp.test;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class GraphicView extends View {
public GraphicView(Context context,AttributeSet attrs) {
super(context,attrs);
}

@Override
public void onDraw(Canvas canvas) {
// 座標系がわかるような罫線を引く
Paint paint = new Paint();
paint.setColor(Color.rgb(255, 255, 0));
paint.setStrokeWidth(10);
canvas.drawLine(10, 40, 300, 70, paint);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
}
}


というように、AttributeSetを持つコンストラクタに変更することで、
無事に修正出来まして、動作確認も出来ました。

| | コメント (0) | トラックバック (0)

【GAE/Python】Goolge cloud sqlをローカルで動かす

サーバにアップした状態での動作は、
https://developers.google.com/cloud-sql/docs/developers_guide_python
を見ることで問題無く完了した。


しかし、ローカルで動作させるためにはいくつか手順が必要で、
それは上記サイトに詳しい説明はない。

なので、上記サイトを参考にしつつも、
インストールが必要な物を調べて、
動作までいったのでそれをメモ代わりに残す。
(※こちらの環境はmacで、windowsの方法とは違う可能性があります、
ご注意下さいm(_ _)m)


まず、
http://www.mysql.com/
より、MySQL Community Serverを落とし、インストール。

インストールは、
http://labs.torques.jp/2010/02/14/844/
が詳しく、参考にさせていただき、システム環境設定に出して起動し、
初期設定、テーブルの作成なども行う。


その後、GoogleAppEngineLauncherのEdit→Application Settingsの
Extra Flagsの部分に
--mysql_user=root --mysql_password=xxxxxxx
と上記で設定したパスワードを入れ、
起動時にオプション付きで起動するように設定しておく。


次に、MySQL-pythonをインストールする。
http://d.hatena.ne.jp/ama-ch/20080610/1213076652

※ mysql_configのパスは、自分の場合も、
mysql_config = /usr/local/mysql/bin/mysql_config
というパスで設定する必要があった。

※自分の場合、このMySQL-pythonのインストール先が、
/Library/Python/2.7/site-packages/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg
になっていた。

GoogleAppEngineLauncherのPreferencesから確認出来る、python pathも
/usr/bin/python2.7 と、2.7になっているので特に何も変えなかったが、
2つのバージョンが違う場合、変える必要があるかも知れない。


その後、
/usr/local/bin/dev_appserver.py
の頭に(22行目辺りに)import MySQLdb の記述を追加。
http://googlecloudsql.blogspot.com/2012/03/re-rdbms-api-is-not-available-because.html


この状態で動かすと、

import MySQLdb
File "build/bdist.macosx-10.7-intel/egg/MySQLdb/__init__.py", line 19, in
File "build/bdist.macosx-10.7-intel/egg/_mysql.py", line 7, in

というエラーが出て、そもそも起動すら出来なかった。


なので、
http://www.rustyrazorblade.com/2011/11/installing-mysqldb-on-macos-lion/
にある、


sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

sudo ln -s /usr/local/mysql/lib /usr/local/mysql/lib/mysql


という2つのコマンドをターミナルから実行、
その後起動してみると成功し、ローカルから動作を確認出来た。

| | コメント (0) | トラックバック (0)

GAE/Pythonで、Amazon Product Advertising APIを使い、商品を検索してみる

GAEということで、なるべく標準の物を使った方が良いと思い、
返ってきたxmlの解析はElementTreeを使うことにしました。

使い方は、こちらを参考にさせていただきました
http://blog.livedoor.jp/yawamen/archives/51520512.html

amazon apiとのやりとりは、
bottlenoseを使うことにしました。

使い方は、こちらを参考にさせていただきました。
http://www.ninxit.com/blog/2011/06/09/python-amazon-product-advertising-api/

from xml.etree.ElementTree import *
import bottlenose

AWS_KEY = ''
SECRET_KEY = ''
ASSOCIATE_TAG = '-22'

class TestAmazonSearchHandler(webapp.RequestHandler):
def get(self):

amazon = bottlenose.Amazon(AWS_KEY, SECRET_KEY,ASSOCIATE_TAG)
result = amazon.ItemSearch(Keywords=u'jobs', SearchIndex='Books', ItemPage='1', ResponseGroup='Small')
root = fromstring(result)

count = 0

xmlns = '{http://webservices.amazon.com/AWSECommerceService/2011-08-01}'

Items = root.find(xmlns+'Items')
if Items:
for item in Items.findall(xmlns +'Item'):

print "-"
print item.findtext(xmlns+'DetailPageURL')
print "-"

itemAttributes = item.find(xmlns+'ItemAttributes')

if itemAttributes:
#print itemAttributes.findtext(xmlns+'Author') #authorは本によって無い場合があったのでひとまず外した
print itemAttributes.findtext(xmlns+'Title')
print itemAttributes.findtext(xmlns+'Manufacturer')
print itemAttributes.findtext(xmlns+'ProductGroup')

count += 1
print str(count)

print "-----"


※↑すみません、<p>タグがどうやっても入ってしまうので、除いてご利用いただければと思いますm(_ _)m


これで、こちらの環境では・・


-
http://www.amazon.co.jp/%E3%82%B9%E3%83%86%E3%82%A3%E3%83%BC%E3%83%96%E3%83%BB%E3%82%B8%E3%83%A7%E3%83%96%E3%82%BA-I-%E3%82%A6%E3%82%A9%E3%83%AB%E3%82%BF%E3%83%BC%E3%83%BB%E3%82%A2%E3%82%A4%E3%82%B6%E3%83%83%E3%82%AF%E3%82%BD%E3%83%B3/dp/4062171260%3FSubscriptionId%3DAKIAJ7HHIWJRA6ZU54AA%26tag%3Dsuzukikuni-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4062171260
-
スティーブ・ジョブズ I/
講談社/
Book
1
-----
-
http://www.amazon.co.jp/History-Jobs-Apple-1976%E3%80%9C20XX%E3%80%90%E3%82%B8%E3%83%A7%E3%83%96%E3%82%BA%E3%81%A8%E3%82%A2%E3%83%83%E3%83%97%E3%83%AB%E5%A5%87%E8%B9%9F%E3%81%AE%E8%BB%8C%E8%B7%A1%E3%80%91-100%25%E3%83%A0%E3%83%83%E3%82%AF%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4863913141%3FSubscriptionId%3DAKIAJ7HHIWJRA6ZU54AA%26tag%3Dsuzukikuni-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4863913141
-
The History of Jobs & Apple 1976〜20XX【ジョブズとアップル奇蹟の軌跡】 (100%ムックシリーズ)/
晋遊舎/
Book
2
-----
..以下、10冊目まで続く


という形で出力が確認出来ました。


※著者の名前や本のタイトルなど、
日本語になっている部分をそのまま出すとUnicodeEncodeErrorが出るので、
デフォルトのエンコーディングを変える必要があります。
http://blog.livedoor.jp/matssaku/archives/50525168.html

| | コメント (0) | トラックバック (0)

Error generating final archive: Debug certificate expired on ...

http://d.hatena.ne.jp/hypercrab/20100619/1276925032

の記事にあったのですが、しばらく使っていなかったら本当に出てしまった・・。

macだと、ユーザーディレクトリ/.android にdebug.keystoreがあり、
それを削除した後、クリーンビルドすればOKでした。
(日付を変えて戻す、ということは必要ありませんでした。)

| | コメント (0) | トラックバック (0)

Facebook/javascript sdk使用時、IEのみ、multiqueryに制限がある?

例えば、友達の日本語の名前を人数分、一括で取得したいと思い、
fql.multiqueryを呼んでみたが、
firefox、chromeでは問題無いが、IE8、IE9ではFB.apiのレスポンスが返ってこなかった。

取得する際の件数が多すぎるのかと思い、
20件程度に絞って実行すると、最初の一回は返ってくるが、
もう一度multiqueryを実行すると(時間を空けて実行しても)、
同じく返ってこない。

そこで15件にしてみると、ちゃんとレスポンスが複数回返ってきて、
IEでも正常に動作するようになった。

なので友達の人数を上限として、
15件ごとに、何回もmultiqueryを呼ぶように変更した。

| | コメント (0) | トラックバック (0)

【GAE】memcacheの1MBという制限に関して

http://unkar.org/r/php/1267057923
の439辺りで初めて知ったのだが、
memcacheの1MBという制限は、1個のデータに対する制限であって、
トータルで1MBしか作れないと言うことではないのか・・!

今までトータルで1MBしか作れないと思っていた・・

| | コメント (0) | トラックバック (0)

Google Cloud Storageにappengine/pythonからアップしてみる

from __future__ import with_statement
from google.appengine.api import urlfetch
from google.appengine.ext import webapp
import logging

try:
files.gs
except AttributeError:
import gs
files.gs = gs

class WriteImageHandler(webapp.RequestHandler):

BUCKET = 'xxxxx'

def post(self):

try:
read_path = '/gs/%s/%s' % (self.BUCKET, 'test.jpg')//保存先のファイル名
write_path = files.gs.create(read_path, mime_type='image/jpeg' , acl='public-read')//ファイルによって、mime_typeを変える

result = urlfetch.fetch('http://')//取得先の画像のアドレス
if result.status_code == 200:
with files.open(write_path, 'a') as fp:
fp.write(result.content)
else:
logging.debug("uploadError:" + str(result.status_code))
return False

files.finalize(write_path)
logging.debug("upload correct!")
except:
logging.debug("uploadError")
return False


※↑すみません、<p>タグがどうやっても入ってしまうので、除いてご利用いただければと思いますm(_ _)m


アップすると、Google Cloud Storage Managerから見ることができ、
acl='public-read'で書き込んでいるので、
http://commondatastorage.googleapis.com/' + バケット名 + "/" + ファイル名
というアドレスをブラウザに打つと、ファイルにアクセスできます。


http://code.google.com/appengine/docs/python/googlestorage/overview.html
のページを参考にしました。


もしかしてジェネレーター
作る際に画像を保存したくて、このアップロード機能を実装しました。

| | コメント (0) | トラックバック (0)

【GAE/Python】ファイルをブラウザにダウンロードさせたい

fileName = "test.jpg"
print "Content-Type:application/octet-stream;\r\nContent-Disposition: attachment; filename=" + fileName + "\r\n"
f = urllib.urlopen("http://xxx.jpg")
data = f.read();
print data
f.close()


とすることで、ブラウザにDLさせることが出来ました。

f = urllib.urlopen("http://xxx.jpg")
の部分を、
f = open('./local.jpg' , "r")
という形に変えれば、ローカルの物でも大丈夫です。

また、取得先のサーバの状態によって違うかも知れないのですが、
getの変数によってhtmlの内容が可変するような場合、


result = urlfetch.fetch(path)
if result.status_code == 200:
//成功
print result.content
else:
//失敗

というように、
urlfetch.fetchを使わないと成功しませんでした。
(具体的には、変数が渡っていないかのようなhtmlになってしまっていました。
ただ、それも渡っている場所と渡っていない場所があり、最終的な原因はわからなかったのですが・・)


※appengineでローカル、WEB上のどちらも動作確認済みです。

| | コメント (0) | トラックバック (0)

«Google Cloud Storage Python APIのアクセスコントロール