PHPから始めるメリット・デメリット
まず自分のポジションとしてはPHPでIT業界で働き始めて10年以上経過。
今もかなりPHPにお世話になっています。
メリット
・直感的にわかりやすい。挫折しずらい
・ネット上にサンプルコードが多いのでやりたいことがすぐ実現できる。
・挫折しずらいので時間をかけてWeb周辺の知識も得られる
デメリット
・アプリ等に手を出した時にPHPよりはるかにネット上での情報が少ないので挫折しやすい。
・PHPメインの会社に就職すると全体的に緩いので成長しずらい(気がする)
ビジネス指向というかWebでアイデアを実現したい人には1番いいと思う。
将来的に技術を高めて食べて行きたいならPHPはおすすめできないかな。
ふと思ったので書きました、以上です
【ansible】hello world
はじめに
ずっと前から使おうと思って概要とかは見てたけど実際使ったことはありませんでした。
今回実際に案件で使ってみようと思って実際にいじってみました。
簡単で手軽なのをみんな謳っている感じだったのでまぁつまることもないだろうと思ってたのですが、若干時間かかりました。
で、とりあえず自分のPCからVPSやAWSへ実行してみる形を想定して手を動かして見ました。
実際に動かす
Macでの作業で今回はvagrant上のサーバへ実行してみました。
とりあえず最低限知っておいた方がよさそうなキーワードは以下
インベントリファイル
意味的にはhostsファイルみたいな感じ。使用したいサーバーはとりあえずここに書かないとダメ。
自分的には.ssh/configのHostに書いてるものを書くと解釈したらスッキリした。
playbook
手順書みたいなもの。手順書だと実際にコマンドを書くけど、ansibleのモジュール(方言)使って記述する感じ。
以下の.ssh/configの場合の例
.ssh/config
Host vagrant_web HostName 192.168.33.10 Port 22 User vagrant IdentityFile path/to/秘密鍵
※vagrantの場合、秘密鍵とかあんまり意識しないけどvagrant ssh-configでIdentityFileで確認できる
hosts(インベントリファイル)
vagrant_web
set_timezone.yml(playbook)
- hosts: vagrant_web user: vagrant become: true tasks: - name: set timezone command: cp /usr/share/zoneinfo/Japan /etc/localtime - name: set timezone copy: content='ZONE="Asia/Tokyo"' dest=/etc/sysconfig/clock
実行する
$ ansible-playbook -i ./hosts ./set_timezone.yml
何にはまったのか
いろんなサイト見てたらインベントリファイルは/etc/ansible/hostsに書いてる。けどMacだとそれがなかったから。
実際はオプションiを使えばファイルを指定できる。
ヘルプみるとそもそもデフォルトの場所もosによって違うみたい。
$ ansible -h -i INVENTORY, --inventory-file=INVENTORY specify inventory host path (default=/usr/local/etc/ansible/hosts) or comma separated host list.
タイトルはhello worldだけどhello world出てこなかった。。。
以上です
【xcode】プロジェクト名を変更するのが思ったより面倒だったので手順まとめておく
はじめに
アプリ名とかを仮のまま開発を進めて途中でアプリ名が決定。
プロジェクト名などが旧名称のままだと気持ち悪いのでプロジェクト名を変更したかったのでその時の手順をまとめておきます。
今回は以下の名前をで変更します。
変更前:SampleOld
変更後:SampleNew
とりあえず動くようにする
プロジェクト名を変更
xcodeの[Identity and Type]から「SampleOld」→「SampleNew」に変更。
赤枠の箇所をすべて修正すればたぶんOK
Cocoapods修正
Podfileにプロジェクト名の記述があるので修正
Podfile
target 'SampleNew' do # Comment the next line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for SampleNew pod 'AFNetworking' ・・・ target 'SampleNewTests' do inherit! :search_paths # Pods for testing end target 'SampleNewUITests' do inherit! :search_paths # Pods for testing end end
インストールし直す
$ pod install
Bridging-Header.h修正
まずはリネーム
SampleOld-Bridging-Header.h →Sample New-Bridging-Header.h
設定も修正
ここまででビルドとかは問題なくできるようになった。
しかしプロジェクトの中を見るとわかるが実際のフォルダ名はSampleOldのままで気持ち悪い。
旧プロジェクト名を完全になくす
プロジェクトディレクトリ直下に
SampleOld、SampleOldTests、SampleOldUITestsというフォルダが残っているのでそれぞれSampleOld => SampleNewにリネーム
テキストファイルの文字列を置換
find . -path "./.git" -prune -o -type f -print | perl -nle 'print if -f && -T' | xargs sed -i "" "s/SampleOld/SampleNew/g"
バイナリファイルの文字列を置換
バイナリファイルの置換とかやり方わからなかたったので、数も多くないのでviで直接編集した。
検索
$ find . -path "./.git" -prune -o -type f -print | xargs grep "SampleOld" 2> /dev/null Binary file ./SampleOld.xcworkspace/xcuserdata/xxx.xcuserdatad/UserInterfaceState.xcuserstate matches ・・・
ファイル編集
$ vi -b ./SampleOld.xcworkspace/xcuserdata/xxx.xcuserdatad/UserInterfaceState.xcuserstate ・・・ :%s/SampleOld/SampleNew/g # 全置換して :wq! # 保存
missing from working copy
git、svnを使ってる場合、ビルドすると上記のワーニングが出る。
コミットすると消えるらしい
さいごに
とりあえずここまでやったらちゃんと動いてる感じ。
今後何も起きないことを祈ります。以上です
以下、参考にさせて頂きました
findで特定のディレクトリを検索対象外(除外)にする - hogehoge foobar Blog Style5
findでテキストファイルのみ抽出 - Qiita
【android】Fragment + ListViewでのAPIへのリクエストのタイミングについて
はじめに
今回やりたかったことは以下
・APIから取得したデータをFragment上のListViewへセット
・ListViewのセルをタップしたら詳細画面へ遷移
・詳細画面で戻るボタンでListViewへ戻る
これだけと思ってたら1日はまってしまった。
何にはまったかというと詳細画面から戻った時にAPIへ再度リクエストしていた。
これの解決策がなかなか出てこなかった。。。
そもそもFragmentのライフサイクルとか全然頭になかったところからスタートだったので色々と知識不足
解決策
http://qiita.com/ymd_aaa/items/d04d174fef98c93ef593
中々みつからなかったがまさにここに求めていた答えがありました。
APIリクエストしてデータの取得してアダプタへのセットをonCreateViewメソッドで行なっていたのですが。
これをonCreateメソッドで行うようにすれば戻ってきた時にデータの再取得は行わずやりたいことができました。
処理イメージ
public class MyFragment extends Fragment { private ArrayList<UserData> userDataList; private UserDataAdapter adapter; @Override public void onCreate(Bundle savedInstanceState) { // データの初期化 userDataList = new ArrayList<>(); adapter = new MuserDataAdapter(getContext(), 0, userDataList); // ★ここでAPIコールしてレスポンスをアダプタにデータをセット // adapter.notifyDataSetChanged();とか } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_my, container, false); // ListViewセット ListView listView = (ListView)view.findViewById(R.id.list_view); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { ・・・ }); return view; } public class UserData { ・・・ } public class UserDataAdapter extends ArrayAdapter<UserData> { ・・・ } }
以上です
【android】FragmentのListViewを選択で画面遷移する方法
はじめに
Android開発ではFragmentを使った画面の開発が常套手段ぽい。
なので今回はFragment上の画面にListViewを表示して、セルをタップしたら詳細画面用のFragmentを表示。詳細画面へ遷移後に戻るボタンでListViewの画面に戻る画面を作ってみた。
ファイル構成とそれぞれやることは以下
・MainActivity.java、activity_main.xml
ここのレイアウトに一覧画面ではfragment_mainを詳細画面ではfragment_detailを表示する。
起動時はMainFragmentをセットする。
・MainFragment.java、fragment_main.xml
ListViewにデータの表示とセルを選択されたときにDetailFragmentを呼ぶ。
実装
メインアクティブティ
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="xxx.samplefragment.MainActivity"> <!-- ここにフラグメントをセット --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main_fragment"></LinearLayout> </RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ListView表示用のフラグメントをセット MainFragment mainFragment = new MainFragment(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.main_fragment,mainFragment); transaction.commit(); } }
ListView表示用フラグメント
fragment_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="xxx.samplefragment.MainFragment"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> </FrameLayout>
MainFragment.java
public class MainFragment extends Fragment { public MainFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main, container, false); return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { // ListViewに表示するデータ final ArrayList<String> items = new ArrayList<>(); items.add("データ1"); items.add("データ2"); items.add("データ3"); // ListViewをセット final ArrayAdapter adapter = new ArrayAdapter(this.getContext(), android.R.layout.simple_list_item_1, items); ListView listView = (ListView) view.findViewById(R.id.list_view); listView.setAdapter(adapter); // セルを選択されたら詳細画面フラグメント呼び出す listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // 詳細画面へ値を渡す DetailFragment fragment = new DetailFragment(); Bundle bundle = new Bundle(); bundle.putInt("selected",position); fragment.setArguments(bundle); // 詳細画面を呼び出す FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.replace(R.id.main_fragment, fragment); // 戻るボタンで戻ってこれるように transaction.addToBackStack(null); transaction.commit(); } }); } }
詳細画面用フラグメント
fragment_detail.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="xxx.samplefragment.DetailFragment"> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
DetailFragment.java
public class DetailFragment extends Fragment { public DetailFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle args = getArguments(); int selected = args.getInt("selected"); View view = inflater.inflate(R.layout.fragment_detail, container, false); TextView textView = (TextView)view.findViewById(R.id.textView); textView.setText(String.valueOf(selected) + "番目が選択されました"); return view; } }
コードそのままだけでこんな感じでやりたいことができました。
以上です
【android】android.support.designライブラリを追加して使用する手順
サポートライブラリ追加手順です
・[File]>[Project Structure]を開く
・[app]を選択
・ [Dependencies]を選択
・ [+]>[1 Library dependency]を選択
・ 検索バーに「design」と入力してEnter
・ [com.android.support:design(com.android.support:design:25.1.0)]を選択して[OK]をクリック
以上です
【swift】UILabelの高さを計算して動的に変更(調整)する
よくやってるつもりだったけど意外と整理できていなかったので整理
var myLabel = UILabel(); // 最大行数を指定(0は無制限) myLabel.numberOfLines = 0; // 表示するテキストをセット myLabel.text = "テキスト・・・"; // セットした文字からUILabelの幅と高さを算出 var rect: CGSize = myLabel.sizeThatFits(CGSize(width: frame.width, height: CGFloat.greatestFiniteMagnitude)) // 算出された幅と高さをセット myLabel.frame = CGRect(x: 0, y: 0, width: rect.width, height: rect.height)
以上です