Xcode6でコンパイルまでは無事に通ったのですが、iOS6で実機確認すると、
dyld: Symbol not found: _UITransitionContextFromViewControllerKeyみたいなエラーが発生して、超てんぱってしまった。
原因は、わからないのだが、ライブラリを最新にして、ターゲットのビルドパスを適切なものに設定したら治ったのだが、今後も同じようなことが発生した場合に見返せるように、1エントリー。
常にテンパってます。
Xcode6でコンパイルまでは無事に通ったのですが、iOS6で実機確認すると、
dyld: Symbol not found: _UITransitionContextFromViewControllerKeyみたいなエラーが発生して、超てんぱってしまった。
iOS7以降のフラットデザインに対してtoolbarの色を変更するにはどうすればいいのだろうか?
ずばり下のように組めばおkみたい。
[UIToolbar appearance].barTintColor = [UIColor whiteColor];ちなみに、これはiOS7以降で使えるので、iOS6では適用できないので、注意が必要。
コンパイルするときに、
ld: warning: directory not found for option "〜"というエラーが発生して、これ原因なにかなーっと調べていたら、ちょーど同じことに悩んでた方を発見。
"$(SRCROOT)/アプリ名"っていうところを削除したらエラーがとれた。
Xcodeが最新の6になって、各プログラムを最新にしようとしたところ、Google Analytics iOS SDKでリンクエラーが多発。
なぜかなーっと思って調べてみると、どうやら
iOS アプリに Google Analytics を導入する(2014/08 時点)
を読むと、「libGoogleAnalyticsServices.a」がないために発生していたようだ。
これマニュアルを読むとインストールしろって書いてなかったじゃん!!
すんごい悩みましたー。
自前でWebViewを開くプログラムを組むのがめんどくさくなってきたので、オープンソースを利用することに。
SVWebViewControllerを使えばめちゃくちゃ簡単に実装することができる。
具体的には、下のように組めばおk
SVWebViewController *webViewController = [[SVWebViewController alloc] initWithAddress:@"https://m.facebook.com/lovenailapp"]; webViewController.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewController:webViewController animated:YES];ちなみに、上のようにhidesBottomBarWhenPushedプロパティをYESに設定すれば画面遷移の時に、tabbarを隠すこともできる。
#import "SVWebViewController.h"と書けばいいだけなので、めちゃおススメです。
4年前に頂いた本をようやく読むことができた。訳者まえがき
via:目次
まえがき
1章 はじめに
1.1 ウェブアプリケーションとは?
1.2 ウェブアプリケーションの構築法
1.3 アーキテクチャとは?
1.4 どう始めるか
2章 ウェブアプリケーションのアーキテクチャ
2.1 階層化されたソフトウェアアーキテクチャ
2.2 階層化技術
2.3 ソフトウェアインタフェースの設計
2.4 A地点からB地点へ
2.5 ソフトウェアとハードウェアの分離
2.6 ハードウェアプラットフォーム
2.6.1 共有ハードウェア
2.6.2 専用ハードウェア
2.6.3 コロケーション
2.6.4 セルフホスティング
2.7 ハードウェアプラットフォームの成長
2.7.1 入手可能性と調達期間
2.7.2 輸入、出荷、設置
2.7.3 場所
2.7.4 電源
2.7.5 ネットワークオペレーションセンター(NOC)
2.7.6 接続性
2.8 ハードウェア冗長性
2.9 ネットワーキング
2.10 言語、技術、データベース
3章 開発環境
3.1 3つのルール
3.2 ソース管理の実施
3.2.1 ソース管理とは何か?
3.2.2 ユーティリティ
3.2.3 ソース管理製品
3.2.4 ソース管理に入れるべきもの
3.2.5 ソース管理に入れるべきでないもの
3.3 ワンステップビルド
3.3.1 サイトの直接編集
3.3.2 作業環境の構築
3.3.3 リリース過程のまとめ
3.3.4 ビルドツール
3.3.5 リリース管理
3.3.6 自動化すべきでないもの
3.4 問題追跡管理
3.4.1 最低限の機能
3.4.2 問題追跡管理ソフトウェア
3.4.3 何を追跡管理すべきか
3.4.4 問題管理戦略
3.4.5 CADT
3.5 開発モデルの大規模化
3.6 コーディング規準
3.7 テスト
3.7.1 リグレッションテスト(回帰テスト)
3.7.2 手動テスト
4章 国際化とローカライゼーションとUnicode
4.1 国際化とローカライゼーション
4.1.1 ウェブアプリケーションの国際化
4.1.2 ウェブアプリケーションのローカライゼーション
4.2 Unicodeの概要
4.3 UTF-8エンコーディング
4.4 UTF-8ウェブアプリケーション
4.4.1 出力の制御
4.4.2 入力の制御
4.5 PHPでUTF-8を使う
4.6 他の言語でUTF-8を使う
4.7 MySQLでUTF-8を使う
4.8 電子メールでUTF-8を使う
4.9 JavaScriptでUTF-8を使う
4.10 APIでUTF-8を使う
5章 データの一貫性とセキュリティ
5.1 データ一貫性ポリシー
5.2 良好、正当、不正
5.3 UTF-8のフィルタリング
5.4 制御文字のフィルタリング
5.5 HTMLのフィルタリング
5.5.1 なぜHTMLを使うのか?
5.5.2 HTML入力のフィルタリング
5.5.3 ブラックリストとホワイトリスト
5.5.4 開始タグと終了タグの対応づけ
5.5.5 HTMLの処理
5.6 クロスサイトスクリプティング(XSS)
5.6.1 正規の抜け穴
5.6.2 ユーザー入力に関するセキュリティホール
5.6.3 タグと括弧の対応づけ
5.6.4 プロトコルフィルタリング
5.7 SQLインジェクション攻撃
5.7.1 SQLインジェクション攻撃の対策
5.7.2 SQLインジェクション攻撃の防止
6章 電子メール
6.1 メールの受信
6.1.1 ファイルのアップロード
6.1.2 モバイルブログ
6.1.3 追跡機能のサポート
6.1.4 単純な自動化とAPI
6.2 電子メール機能のアプリケーションへの組み込み
6.2.1 別のアプローチ
6.3 MIMEフォーマット
6.4 単純なMIMEメールの解析
6.5 UUエンコードされた添付ファイルの解析
6.6 TNEF添付ファイル
6.7 携帯電話
6.8 文字セットとエンコーディング
6.9 ユーザーの認識
6.10 単体テスト
7章 リモートサービス
7.1 リモートサービスの掟
7.2 ソケット
7.3 HTTPの利用
7.3.1 HTTPの要求と応答のサイクル
7.3.2 HTTP認証
7.3.3 HTTPリクエストの生成
7.4 リモートサービスの冗長性
7.5 非同期のシステム
7.6 XMLによる情報交換
7.6.1 XMLの解析
7.6.2 REST
7.6.3 XML-RPC
7.6.4 SOAP
7.7 ライトウェイトプロトコル
7.7.1 メモリ使用量
7.7.2 ネットワーク速度
7.7.3 解析の速度
7.7.4 書き込み速度
7.7.5 欠点
7.7.6 ソースからシステムを作る
8章 ボトルネック
8.1 ボトルネックの特定
8.1.1 ソフトウェアコンポーネントによる分割
8.1.2 ハードウェアコンポーネントによる分割
8.2 CPU使用率
8.2.1 コードのプロファイリング
8.2.2 Opcodeキャッシング
8.2.3 テンプレート処理の高速化
8.2.4 一般的な解決方法
8.3 I/O
8.3.1 ディスクI/O
8.3.2 ネットワークI/O
8.3.3 メモリI/O
8.4 メモリとスワッピング
8.5 外部サービスとブラックボックス
8.6 データベース
8.6.1 クエリのスポットチェック
8.6.2 クエリのプロファイリング
8.6.3 クエリとインデックスの最適化
8.6.4 キャッシング
8.6.5 非正規化
9章 ウェブアプリケーションのスケーリング
9.1 スケーリングにまつわる神話
9.1.1 スケーラビリティとは?
9.1.2 ハードウェアプラットフォームのスケーリング
9.1.3 垂直方向のスケーリング
9.1.4 水平方向のスケーリング
9.1.5 継続作業
9.1.6 冗長性
9.2 ネットワークのスケーリング
9.3 PHPのスケーリング
9.4 ロードバランシング(負荷分散)
9.4.1 ハードウェアを使ったロードバランシング
9.4.2 ソフトウェアによるロードバランシング
9.4.3 レイヤ4
9.4.4 レイヤ7
9.4.5 きわめて大規模なバランシング
9.4.6 非HTTPのトラフィックのバランシング
9.5 MySQLのスケーリング
9.5.1 ストレージバックエンド
9.5.2 MyISAM
9.5.3 InnoDB
9.5.4 BDB
9.5.5 ヒープ
9.6 MySQLのレプリケーション
9.6.1 マスタ/スレーブのレプリケーション
9.6.2 ツリーレプリケーション
9.6.3 マスタ/マスタレプリケーション
9.6.4 レプリケーションの失敗
9.6.5 レプリケーションのタイムラグ
9.7 データベースの分割
9.7.1 クラスタリング
9.7.2 フェデレーション(連携)
9.8 大規模なデータベースのスケーリング
9.9 ストレージのスケーリング
9.9.1 ファイルシステム
9.9.2 プロトコル
9.9.3 RAID
9.9.4 フェデレーション(連係)
9.10 キャッシング
9.10.1 データのキャッシング
9.10.2 HTTPリクエストのキャッシング
9.11 スケーリングのまとめ
10章 統計、監視、警告
10.1 ウェブ統計の追跡
10.1.1 サーバログファイル
10.1.2 分析
10.1.3 ビーコンの使用
10.1.4 Spread
10.1.5 ロードバランサ
10.1.6 カスタマイズされたメトリックの追跡
10.2 アプリケーションの監視
10.2.1 バンド幅の監視
10.2.2 長期的なシステム統計
10.2.3 視覚化のカスタマイズ
10.3 警告
10.3.1 稼働時間のチェック
10.3.2 リソースレベルの監視
10.3.3 閾値のチェック
10.3.4 下限値のチェック
11章 API
11.1 データフィード
11.1.1 RSS
11.1.2 RDF
11.1.3 Atom
11.1.4 その他
11.1.5 フィードの自動検知
11.1.6 フィードのテンプレート
11.1.7 OPML
11.1.8 フィードの認証
11.2 モバイルコンテンツ
11.3 ウェブサービス
11.4 APIトランスポート
11.4.1 REST
11.4.2 XML-RPC
11.4.3 SOAP
11.4.4 トランスポートの抽象化
11.5 APIの乱用
11.5.1 APIキーによる監視
11.5.2 スロットリング
11.5.3 キャッシング
11.6 認証
11.6.1 認証なし
11.6.2 プレーンテキスト
11.6.3 MAC
11.6.4 トークンベースのシステム
11.7 将来
索引
昨日、jdkのインストール方法について書いたが、その後、eclipseを入れたら、下のように警告がでて、起動できない。
なぜかなーっと思っていたら、どうやらセキュリティ関連らしく、システム環境設定の「セキュリティとプライバシー」で、「このまま開く」というボタンを押せば起動できた。
何故か、MavericksでJava 6が発見できなかったので、インストールしてみることに。
で、方法は、jdk 6 on mountain lionを読みながらインストールを行った。
Downloads for Apple DevelopersページでJavaと検索する。
Java for OS X 2013-005 Developer Packageを選択して、java_for_os_x_2013005_dp__11m4609.dmgファイルをダウンロードする。
java_for_os_x_2013005_dp__11m4609.dmgをダブルクリックする。
JavaDeveloper.pkgをダブルクリックする。
「続ける」ボタンを押す
「続ける」ボタンを押す
「続ける」ボタンを押す
「同意する」ボタンを押す
「インストール」ボタンを押す
インストールされるまで待つ
「閉じる」ボタンを押してインストール完了。
インストールができたかどうかの確認は、ターミナルで
java -versionと打って
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)とでればおk
タグを自動で実装してくれるtagsInputプラグインというものを同僚から教えてもらったので、使い方の勉強。
使い方は超簡単。
<link href="./jquery.tagsinput.css" media="all" rel="stylesheet" type="text/css" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="./jquery.tagsinput.min.js"></script>上記のscriptとstyleをインクルード。
<input name="tags" id="tags" value="" />init時のscriptは下のようにすればおk
jQuery(function($){ var $tags = $('#tags'); $tags.tagsInput({ 'onAddTag':function(e){ }, 'onRemoveTag':function(e){ }, 'onChange' : function(e){ }, 'defaultText':'テキストを入力してください', 'maxChars':20 }); });defaultText:パラメータでタグが入力されていないときの文言を設定
$('#tags').addTag('foo');でtagを動的に追加したり、
$('#tags').removeTag('foo');で削除することができる。
Xcode6にしたらなぜかMWPhotoBrowserが不具合を起こしてしまう。
おそらくSDWebImageを最新にしたからだと思うのだが、Pullリクエストに
_webImageOperation = [manager downloadImageWithURL:_photoURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { [self fetchImageProgressWithReceivedSize:receivedSize expectedSize:expectedSize]; } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (error) { MWLog(@"SDWebImage failed to download image: %@", error); } _webImageOperation = nil; self.underlyingImage = image; [self imageLoadingComplete]; }];にしてほしいと書いてあったので、コールバックの部分を
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {にしたらなおった、一見落着、落着。
前回、gqlからkeyを取得する方法を書いたがその取得したKeyを使ってデータを取得するには、
key hogeModel.get(key)という形でクラスメソッドでgetを呼び出せばおk
Jinja2のlistループ中にindexを取得したい場合はどうすればいいだろうか?
Template Designer Documentationを読むと下のように組めばおkみたい。
{% for item in items %} <!;-- 1からスタート --> {{ loop.index }} <!;-- 0からスタート --> {{ loop.index0 }} {% endfor %}これ逆にいうと、loopが予約語になっているのかなー?
昨日、積み上げ式の横棒グラフを作り方を書きました。
$.jqplot( 'horizontalbarchart', [...] ,{ stackSeries: true, seriesDefaults:{ renderer:$.jqplot.BarRenderer, rendererOptions: { barDirection: 'horizontal' }, pointLabels: { show: true } }, axes:{ yaxis:{ renderer: $.jqplot.CategoryAxisRenderer } } });で上のようにpointLabelsパラメータを設定してもなぜか表示されない。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="./jquery.jqplot.min.js"></script> <script src="./plugins/jqplot.categoryAxisRenderer.min.js"></script> <script src="./plugins/jqplot.barRenderer.min.js"></script> <script src="./plugins/jqplot.pointLabels.min.js"></script>めでたし、めでたし。
積み上げ式の横棒グラフを作るにはどうすればいいのだろうか?
jQuery の jqPlot プラグインで作る積み上げ横棒グラフ
を読みながら下のように組んでみた。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="./jquery.jqplot.min.js"></script> <script src="./plugins/jqplot.categoryAxisRenderer.min.js"></script> <script src="./plugins/jqplot.barRenderer.min.js"></script>
$.jqplot( 'horizontalbarchart', [...] ,{ stackSeries: true, seriesDefaults:{ renderer:$.jqplot.BarRenderer, rendererOptions: { barDirection: 'horizontal' } }, axes:{ yaxis:{ renderer: $.jqplot.CategoryAxisRenderer } } });で、実行したらところ、ちゃんと横棒グラフが表示された。
gqlからkeyを取得するにはどうすればいいだろうか?
下のように組めばおk
query = db.GqlQuery("SELECT * FROM Hoge") for q in query: q.key()
Jinja2を使ってリストを展開するにはどうすればいいのだろうか?
Welcome to Jinja2を読むと下のようにすればおkみたい。
<!-- items = [ {name:"hoge" }, {name:"bar" }, ] --> {% for item in items %} <li>{{ item.name }} </li> {% endfor %}
円グラフ上に表示されるラベルの色を変更するにはどうすればいいだろうか?
下のようにclass="jqplot-pie-series"にcolorプロパティを設定すればおk
.jqplot-pie-series{ color:#ffffff; }
線グラフに面を設定するには、下のようにfillXXXプロパティーを設定すればおk
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="./jquery.jqplot.min.js"></script>
$.jqplot('linechart', [...] ,{ seriesDefaults: { fill: true, fillAndStroke: true, fillAlpha: 0.7, fillColor:'#fbfbfb' } });
前回、カメラを起動する方法を書きました。
で、その時は、サムネイルの表示だったのですが、今回は、とった写真をそのまま表示する方法について。
static final int REQUEST_IMAGE_CAPTURE = 1; private Uri imageUri; Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.US).format(new Date()); String mCurrentPhotoFileName = "JPEG_MEMO_" + timeStamp + "_"; ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.TITLE, mCurrentPhotoFileName); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); }上のプログラムでカメラを起動し、下のプログラムで画像を表示させます。
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { ImageView imageView = (ImageView) findViewById(R.id.imageview); imageView.setImageURI(imageUri); }問題は、端末を傾けてしまうと画像が表示されなくなってしまうこと。
Graph APIを使っていいねの数を取得することはできるのだろうか?
答えはできるみたい。
Get FB likes count for specific URL and page
よると
https://graph.facebook.com/?ids=http://www.your-website.com/the-url-or-soというようにURLをたたけばでるようなのだが、
FB.api( "/?id=http%3A%2F%2Fwww.imdb.com%2Ftitle%2Ftt2015381%2F", function (response) { if (response && !response.error) { response.shares } } );
プログラムからカメラを起動する方法をTaking Photos Simplyを読みながら実装してみた。
manifest.xmlに定義を追加
<manifest ... > <uses-feature android:name="android.hardware.camera" android:required="false" /> ... </manifest>強制的にカメラ機能が必要ではない場合は、falseを設定する。
static final int REQUEST_IMAGE_CAPTURE = 1; Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); }上のプログラムをたたくと、カメラが起動する。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); ImageView mImageView; mImageView.setImageBitmap(imageBitmap); } }上のプログラムでサムネイルを取得することができる。
前回、ArrayAdapterを使ったList Viewの表示方法について書きました。
で、今回は、SimpleCursorAdapterを使った表示方法について。
import android.widget.AdapterView; import android.support.v4.widget.SimpleCursorAdapter; ListView listView; Cursor c = db.query( /* ... */ ); String[] FROM = {TableName.ColumnName}; int[] TO = new int[] {android.R.id.text1}; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1, c, FROM, TO,0); listView.setAdapter(adapter);上のように今回は、sqliteからデータを取得して表示する方法について書いたけど、めっちゃシンプル。
divタグのwidthとheightを設定して円グラフを表示させたのだが、ちょっと小さい気がする。
どうすれば大きくなるかなーっと思って色々と調べたところ、下のようにしたら大きくなった。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="./jquery.jqplot.min.js"></script> <script src="./plugins/jqplot.pieRenderer.min.js"></script>
$.jqplot('piechart', [['bar',97],['hoge',3]], { seriesDefaults: { renderer: $.jqplot.PieRenderer, rendererOptions: { showDataLabels: true, padding: 10 } }, legend: { show:true, location: 'e' } });rendererOptionsキーのpaddingパラメータを設定すればおkなんですね。
前回、ListViewの表示方法について書きました。
で、ListViewをタップした時の処理をしたいのだが、どうすればいいのだろうか?
ListView listView; listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id) { } });上のようにした結果、クリックイベントを取得することができた。
前回、積み重ねの棒グラフを作る方法について書きました。
で、それをベースにX軸上の各メモリ値を変更することができないかなーっと調べていたら、
jqplotによるグラフの描き方
に方法が記載されていたので、それを参考に前回のプログラムを下のように修正しました。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="./jquery.jqplot.min.js"></script> <script src="./plugins/jqplot.barRenderer.min.js"></script>
<script> d = [ [2,3], [4,6] ]; $.jqplot('barchart', d ,{ stackSeries: true, seriesDefaults:{ renderer:$.jqplot.BarRenderer, highlightMouseDown: true, pointLabels: {show: true} } axes:{ xaxis:{ renderer: $.jqplot.CategoryAxisRenderer, ticks:['foo','bar'] }, yaxis:{ min:0 } } series:['red','yellow'] }); </script>xaxisキーのticksパラメータの設定で変更できます。
アラートダイアログ(AlertDialog)を使用するにはを読みながらalertの表示方法を勉強する。
実際に組んだのは下のプログラム
import android.app.AlertDialog; import android.content.DialogInterface; //thisは、ActionBarActivityをextendしたクラス AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("エラー"); builder.setMessage("入力してください。"); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show();実行したら確かにアラートが表示された。