【xcode】AppIconにiPadのエリアがなかった時の対応
またたいした話じゃないけど、アプリの開発をひととおり行ってアプリのアイコンを設定しようとしたらiPad用のエリアがなかった。
iPhoneのみ
理由はプロジェクトを作った時にDevicesをiPhoneを選択して作ったから。
あとからUniversalに変更したのでなかったので手動で追加した。
Assets.xcassetsをFinderで開くとAppIcon.appiconsetフォルダがあってこの中にContents.jsonがあるのでそれを編集。
iPhoneの設定の下にiPad用の設定を追加すればいけた
Contents.jsonに以下を追加
Contents.jsonに以下を追加
{ "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" }
以上です
sftpをプロキシ(squid)または踏み台(ポートフォワーディング)経由で使用できるようにする
はじめに
やりたかったことはタイトル通りなのですが。
登場人物は以下
・作業用PC
・中継サーバー(踏み台 or プロキシ)
・開発サーバー
今回は中継サーバーと開発サーバーはcentos6.5で、作業PCはMacで確認。
アクセス制限は以下
・開発サーバーへのSSHでのアクセスは中継サーバーからしか接続できない。
・中継サーバーへは作業PCから接続できる。
作業するのがプログラマ以外なのでFTPクライアントソフトとかで接続できるようにしたい。というのがやりたかったことです。
調べてみて簡単に実装できそうな方法が2つ。
・SSHポートフォワーディングを使う
・中継サーバーをプロキシサーバーにする
※squidをいれてプロキシサーバーとする。作業者は中継サーバをプロキシに設定する形
これから先、サーバー名は以下とする
中継サーバー = relay
開発サーバー = dev
SSHポートフォワーディングを使う方法
ポートフォワーディング
$ ssh -N -L 2022:devのIP:devのポート relayのユーザ名@relayのIP # Ctrl + cで終了 # 2022は適当なポート番号(作業用PCで空いてる番号)
SFTPで接続
$ sftp -oPort=2022 devのユーザ名@localhost
SFTP接続はターミナルから接続する例なのでコマンドだが、FileZilla等のFTPソフトを使ってる場合も上記の情報を設定すれば接続できる。
中継サーバーをプロキシサーバーにする
こっちの方がsquidを入れる必要があるので少し手間。
あと、SSHポートをプロキシとして解放するのでIP制限等をしない場合は、SSHのポート番号を変更した方がよさそう。今回は60022とかで話を進める。開発サーバー(接続先)のsshd_configでsshのポート番号を変更できるのでこちらは設定済であるとします。
squidのセットアップ
squidのインストール
$ yum install -y squid
以下の項目をコメントアウト #http_access deny all
http://qiita.com/pcnikki/items/404329f9ad9cb6e235d4
ここら辺とか参考にして最低限の設定はしておいた方がよさそう。
今回はsquidの公開ポートはデフォルトの3128で。
Basic認証設定
# 以下を追加 auth_param basic program /usr/lib64/squid/ncsa_auth /etc/squid/passwd acl password proxy_auth REQUIRED http_access allow password
Basic認証用のユーザーを追加(更新、削除)
$ htpasswd -c /etc/squid/passwd user # 作成 $ htpasswd -b /etc/squid/passwd user pass # 追加 $ htpasswd -D /etc/squid/passwd user # 削除
SSHのポート番号をsquidで使えるようにする
・・・ acl SSL_ports port 443 acl SSH_ports port 60022 # ★ココを追加 acl Safe_ports port 60022 # ★ココを追加 ・・・ # ★ ココを書き換えてSSHもConnectメソッドを使えるように # http_access deny CONNECT !SSL_ports http_access deny CONNECT !SSL_ports !SSH_ports ・・・
squid起動
$ service squid start
SFTPでつなぐ
$ sftp -o "ProxyCommand connect -H basic認証のユーザ名@relayのIP:3128 %h %p" devのユーザー名@devのIP
とりあえず動いた。以上です
sftpコマンドでプロキシ経由で接続する方法メモ
squidでたてたプロキシサーバー経由でsftp使うときのメモ
$ sftp -o "ProxyCommand connect -H プロキシのIP:プロキシのポート %h %p" sftpユーザー名@sftpサーバーのIP
以上です
【squid】プロキシにパスワード認証を設定する
次回のために作業メモ
squidのプロキシにパスワード認証(Basic認証)追加
ユーザー作成
# 新規作成 $ htpasswd -c /etc/squid/passwd user # ユーザー追加 $ htpasswd -b /etc/squid/passwd user2 pass # ユーザー削除 $ htpasswd -D /etc/squid/passwd user2
# 追加 auth_param basic program /usr/lib64/squid/ncsa_auth /etc/squid/passwd acl password proxy_auth REQUIRED http_access allow password
再起動で設定反映
$ service squid restart
以上です
【android】Fragment上のListViewに置かれたボタンのonClickを処理する
はじめに
今回やりたかったのは、ListViewのセル上に削除ボタンとかをおいてクリックされたらListViewから削除するようなこと。
ListViewを作るのがActivityとFragmentとでやり方が違うみたい。
Activityの場合は以下みたいな形でボタンのイベントが取得できる。
<Button ・・・ android:id="@+id/myButton" android:onClick="myFunc" />
Adapter
public View getView(final int position, View convertView, ViewGroup parent) { ・・・ Button myButton = (Button)convertView.findViewById(R.id.myButton); myButton.setTag(position); ・・・ }
Activity
public void myFunc(View view) { // ListView上のボタンがおされたら呼ばれる // view.getTag()でどの行が押されたかわかる }
けど、Fragmentを使ってる場合はFragmentを呼び出してるActivityで実装されているmyFuncが呼ばれるためやりたいこととは違った。
Fragmentの場合
xmlのButtonにonClick属性はセットしない。
やり方わからなかったので、アダプターにインターフェースを定義して呼び出し元(Fragment)にメソッドを実装させる形で実装してみた。
<Button ・・・ android:id="@+id/myButton" />
Adapter
public class MyAdapter extends ArrayAdapter<MyData> { private MyAdapterListener listener; public interface MyAdapterListener { void myFunc(Object position); } public void setListener(MyAdapterListener listener) { this.listener = listener; } ・・・ @Override public View getView(final int position, View convertView, ViewGroup parent) { ・・・ Button myButton = (Button)convertView.findViewById(R.id.myButton); myButton.setTag(position); myButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.myFunc(v.getTag()); } }); return convertView; } }
Fragment
public class MyFragment extends Fragment implements MyAdapter.MyAdapterListener { ・・・ @Override public void onCreate(Bundle savedInstanceState) { ・・・ // アダプターで用意したsetListnerメソッドで関連づける mAdapter = new MyAdapter(getContext(), 0, ・・・); mAdapter.setListener(this); } public void myFunc(Object position) { // 呼ばれた!! } }
もっといいやり方ありそうだけど。。以上です
【android】ListViewひな型
試したりするときにとりあえずListView作ることが多いのでコピペ用にメモ
MainActivity.java
public class MainActivity extends AppCompatActivity { private ArrayList<Item> mItems; private ItemAdapter mAdapter; private ListView mListView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mItems = new ArrayList<>(); mItems.clear(); mAdapter = new ItemAdapter(this, 0, mItems); ListView listView = (ListView)findViewById(R.id.list_view); listView.setAdapter(mAdapter); setData(); } private void setData() { for (int i = 0; i < 10; i++) { Item item = new Item(); item.setTitle("タイトル " + String.valueOf(i+1)); mItems.add(item); } } } class Item { private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } class ItemAdapter extends ArrayAdapter<Item> { private LayoutInflater layoutInflater; public ItemAdapter(Context c, int id, ArrayList<Item> data) { super(c, id, data); this.layoutInflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = layoutInflater.inflate(R.layout.list_item,parent,false); } Item data = getItem(position); TextView title = (TextView)convertView.findViewById(R.id.title); title.setText(data.getTitle()); return convertView; } }
main_activity.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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> </RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5sp" android:paddingTop="25sp" android:paddingBottom="15sp" android:textSize="24sp"/> </LinearLayout> ||<