Android とりあえずlog

2016/12/24 20:52 に masaki gadgetgeek が投稿

[新規アンドロイドプロジェクト] -  [Phone and tablet] -  [Empty Activity]
でActivity のコードに下記を貼り付け。
先頭のpackage を削除しないように
Activity名はダイアログで設定したものに置き換える。

コード



import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;


import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.widget.ListPopupWindow.WRAP_CONTENT;

public class [TemplateActivity ここを変更] extends Activity
        implements View.OnClickListener
{
    private TextView mTextArea;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout layout = new LinearLayout(this);
        layout.setBackgroundColor(Color.rgb(255, 255, 255));
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout);

        Button button = new Button(this);
        button.setText("Push");
        button.setTag("1");
        button.setOnClickListener(this);
        button.setLayoutParams(
                new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
        );
        layout.addView(button);

        mTextArea = new TextView(this);
        mTextArea.setText("", TextView.BufferType.NORMAL);
        mTextArea.setLayoutParams(
                new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
        );
        layout.addView(mTextArea);



    }

    @Override
    public void onClick(View v) {

        _printLog("aaaaaa\n");
    }

    ///TextAreaにログ出力
    private void _printLog( String log )
    {
        mTextArea.setText(mTextArea.getText() + log );
    }
}




[iOS XCode] Info.plist のローカライズ(多言語化)

2016/11/26 20:22 に masaki gadgetgeek が投稿   [ 2016/11/26 20:24 に更新しました ]

iOS 10 から カレンダーデータのアクセスには  Info.plist に理由を明記しなければ
リリースできなくなっています。
他のプライバシーの設定も同じだと思います。

カレンダーの場合は

"Privacy - Calendars Usage Description"

というキーを  Info.plist に追加して、 Value フィールドに "予定を表示したいので" みたいに理由を記入するのですが

多言語対応していると言語に応じて表示する文字列を変えたくなると思います。

Info.plist は他のリソースのようにローカライズできないと思いますが、Info.plist 内で使用する文字列は別ファイルに書くことができます。

InfoPlist.strings

というファイルをリソースに追加します。

そしてこのファイルをLocalizeします。

Info.plistのファイル名が別の名前になっていてもこのファイル名は固定のようです。(どこかで指定あるのかな?)

例えば、MonCalでは MonthViewCalendar-Info.plist という名前で .plist を使用して、Build Settings で MonCaliteと別ファイルにして

切り替えていますがその場合でも .plist のローカライズファイル名は

InfoPlist.strings

です。ちなみにローカライズした時に自動的に作成されていたようです。


Info.plist の一覧画面で右クリックして「Show Raw Keys/Values」を選択すると

Info.plist 上のキー名に切り替わるので、"Privacy - Calendars Usage Description" は

そのキー名に対してValueの値を各言語に対応した InfoPlist.strings に書けば 言語対応できます。

ja.lproj 以下の InfoPlist.strings には

"NSCalendarsUsageDescription" = "予定を表示したいので"


en.lproj 以下の InfoPlist.strings には
"NSCalendarsUsageDescription" = "To display the schedule"

という感じです。
また、プライバシー関連のテストは初回の起動時のみしか出ないのでシミュレータでやる方が便利です。

シミュレータのホーム画面で設定アプリを立ち上げて
「一般」→「リセット」→→「位置情報とプライバシーをリセット」
を行うとプライバシー設定がリセットされるので何度でも動作を確認できます。




Windows とりあえずログ

2016/06/03 19:28 に masaki gadgetgeek が投稿

C++ Win32コンソールアプリケーション

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <stdarg.h>

std::ofstream g_ost;
void LogOpen(void)
{
g_ost.open("c:\\vcplog.txt", std::ios::out);
g_ost.write("------------- start ------------------\n", 40);
}
void LogClose(void)
{
g_ost.write("-------------  end  ------------------\n", 40);
g_ost.close();
}


//
// Output a debug string
// 
void Log(
__in        LPSTR pszFormat, ...)
{
char buff[2048];
va_list argList;

va_start(argList, pszFormat);

int count = vsnprintf_s(buff, 2048, pszFormat, argList);

g_ost.write(buff, count);
g_ost.write("\n", 2);

va_end(argList);

}

//
// Output a debug string
// 
void Log(
__in        LPCWSTR pwszFormat, ...)
{
WCHAR wbuff[2048];
CHAR buff[2048];
va_list argList;

va_start(argList, pwszFormat);

int count;
count = _vsnwprintf_s(wbuff, 2048, pwszFormat, argList);
count = WideCharToMultiByte(CP_ACP, 0, wbuff, -1, buff, 2047, NULL, NULL);
g_ost.write(buff, count);
g_ost.write("\n", 2);

va_end(argList);

}


int main()
{
LogOpen();

Log("aaaa");


Log(L"abc%d%s", 5, L"xyz");


LogClose();
return 0;
}

iOS7 UITableViewCellを継承したカスタムセルで drawInRect drawRect の内容が表示されない。

2016/05/04 17:43 に masaki gadgetgeek が投稿

何度もハマるのでメモ。
セルを継承したカスタムセルでは、背景を透明にしないと drawRect で描画した内容が表示されない。
iOS8やiOS9では大丈夫。

テキスト ボックス

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

{

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self) {

        self.backgroundColor = [UIColor clearColor]; //背景を透明に

        self.opaque = NO; //これ無くてもいい


Objective-C WebDAVでファイルを取得する(NSURLConnection, NSURLRequest)

2016/01/30 6:11 に masaki gadgetgeek が投稿   [ 2016/01/30 17:41 に更新しました ]

box.net のファイルをWebDAVで取得する。

下記でフォルダを指定して取得したXMLを解析し、<href>のURL を別途 HTTP で GET すればファイル取得できる。

 <参考にしたサイト( ありがとうございます)>

 ・リクエストの生成

 http://oasynnoum.hatenablog.com/entry/2013/06/18/234351

 ・Basic認証 ユーザー名とパスワードをBase64 エンコーディングする

 http://d.hatena.ne.jp/white_silhouette/20080916/1221566535

・RFC-2518

http://webdav.todo.gr.jp/download/rfc2518j.txt

ソース

    //テストコード

    //ユーザー名

    NSString *username = @"nmnmnmnm";

    //パスワード

    NSString *password = @"pwpwpwpw";

    //フォルダのURL

    NSString *fileUrl = @"https://dav.box.com/dav/";


    //Basic認証 ユーザー名とパスワードをBase64 エンコーディングする

    // username:password

    NSString* usrPass = [NSString stringWithFormat:@"%@:%@",username,password];

    NSData* poolData = [usrPass dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];

    NSString* enc64Pass = [poolData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];


    //送信内容

//    NSData *bodyStr = [[NSString stringWithFormat:

//    @"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"

//    "<D:propfind xmlns:D=\"DAV:\">"

//    "  <D:prop xmlns:R=\"%@\">"

//    "    <R:bigbox/>"

//    "    <R:author/>"

//    "    <R:DingALing/>"

//    "    <R:Random/>"

//    "  </D:prop>"

//    "</D:propfind>",fileUrl] dataUsingEncoding:NSUTF8StringEncoding];

/////

    NSData *bodyStr = [@"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"

                       "<D:propfind xmlns:D=\"DAV:\">"

                       "  <D:allprop/>"

                       "</D:propfind>" dataUsingEncoding:NSUTF8StringEncoding];

    


    //リクエストの生成

    NSMutableURLRequest *request = [NSMutableURLRequest

                                    requestWithURL:[NSURL URLWithString:fileUrl]

                                    cachePolicy:NSURLRequestUseProtocolCachePolicy

                                    timeoutInterval:60.0];

    [request setHTTPMethod:@"PROPFIND"];

    [request setValue:@"application/xml;  charset=\"utf-8\"" forHTTPHeaderField:@"Content-Type"];

    [request setValue:[NSString stringWithFormat:@"%ld", [bodyStr length]] forHTTPHeaderField:@"Content-Length"];

    [request setValue:[NSString stringWithFormat:@"Basic %@", enc64Pass] forHTTPHeaderField:@"Authorization"];//Basic認証ヘッダ

    [request setValue:@"infinity" forHTTPHeaderField:@"Depth"];

    [request setHTTPBody:bodyStr];

    

    

    NSHTTPURLResponse *httpResponse;

    /* HTTP リクエスト送信 */

    NSData *contents = [NSURLConnection sendSynchronousRequest:request

                                             returningResponse:&httpResponse error:nil];

    NSString *contentsString = [[NSString alloc] initWithData:contents encoding:NSUTF8StringEncoding];

    [self logPrintf:@"*****contents*****\n%@\n\n", contentsString];

    

    /* HTTP レスポンスヘッダ取得 */

    [self logPrintf:@"*****HTTP Header(Response)*****\n\n"];

    NSDictionary *headers = httpResponse.allHeaderFields;

    for (id key in headers) {

        [self logPrintf:@"%@: %@\n", key, [headers objectForKey:key] ];

    }


何かテストするときの雛形

2016/01/30 3:13 に masaki gadgetgeek が投稿   [ 2016/01/30 3:34 に更新しました ]


新規プロジェクトで Single View Application を作成し、ViewControllerに下記の内容を貼り付ける

コード

//
// ViewController.m
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
{
    UITextView *textView;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    //実行ボタン
    UIButton *execButton = [UIButton    buttonWithType:UIButtonTypeRoundedRect];
    execButton.frame = CGRectMake(10,10, 60, 30);
    [execButton setTitle:@"実行" forState:UIControlStateNormal];
    [execButton addTarget:self action:@selector(exec) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:execButton];

    //ログのクリアボタン
    UIButton *clearButton = [UIButton    buttonWithType:UIButtonTypeRoundedRect];
    clearButton.frame = CGRectMake(self.view.frame.size.width - 90,10, 80, 30);
    [clearButton setTitle:@"ログクリア" forState:UIControlStateNormal];
    clearButton.tintColor = [UIColor redColor];
    [clearButton addTarget:self action:@selector(clearLog) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:clearButton];

    //ログ表示エリア
    textView = [[UITextView alloc] initWithFrame:
        CGRectMake(0, 40, self.view.frame.size.width, self.view.frame.size.height - 45)];
    textView.font = [UIFont systemFontOfSize:9.0f];
    textView.editable = NO;
    [self.view addSubview:textView];
    self.view.backgroundColor = [UIColor colorWithRed:0.95f green:0.95f blue:0.98f alpha:1.0f];

    //ログを初期化
    [self clearLog];

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}


//ログエリアの初期化
-(void) clearLog
{
    textView.text = @"";
}


//ログエリアにログを追加。
-(void) logPrintf:(NSString *)fmt,...
{
    va_list args;
    va_start(args, fmt);
    NSString *msg = [[NSString alloc] initWithFormat:fmt arguments:args];
    va_end(args);
    textView.text = [textView.text stringByAppendingString:msg];
}


#pragma mark - 以下を編集
//実行処理本体
- (void)exec
{
    //テストコード
    [self logPrintf:@"aaaaaaaa\n"];
}


@end

こんな感じ



UIColor を archive して unarchive すると少し変化している。(isEqal: でNO)

2014/05/16 18:25 に masaki gadgetgeek が投稿   [ 2014/05/16 18:26 に更新しました ]

32bit ビルドでは変化がないけど、64bit ビルドでは少し誤差が出るみたい。

とりあえずargbに分解して、0-255に変換して比較するようにして回避した

色の比較

- (BOOL) isEqualColor:(UIColor*)color1 withColor:(UIColor*)color2
{
    CGFloat r1,g1,b1,a1,r2,g2,b2,a2;
    [color1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
    [color2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
    
    NSLog(@"col1={%f %f %f %f}",r1,g1,g1,a1);
    NSLog(@"col2={%f %f %f %f}",r2,g2,g2,a2);

    if ( (NSInteger)(r1 * 255.0f) != (NSInteger)(r2 * 255.0f) ) {
        return NO;
    }
    if ( (NSInteger)(g1 * 255.0f) != (NSInteger)(g2 * 255.0f) ) {
        return NO;
    }
    if ( (NSInteger)(b1 * 255.0f) != (NSInteger)(b2 * 255.0f) ) {
        return NO;
    }
    if ( (NSInteger)(a1 * 255.0f) != (NSInteger)(a2 * 255.0f) ) {
        return NO;
    }
    return YES;
}


NSKeyedUnarchiver unarchiveObjectWithFile が nil を返す(ARC)

2013/12/29 17:47 に masaki gadgetgeek が投稿

あんまりハマることは無いかもしれませんが
NSKeyedUnarchiver unarchiveObjectWithFile で nil が返ってくる場合に気をつけること。

unarchveObj = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];

1) 初歩的ですが、意外に多い archivePath の値がアーカイブしたときと同じになっているか 
    [NSKeyedArchiver archiveRootObject:unarchveObj toFile:archivePath]
    
2) unarchveObj  がクラス変数の場合の宣言が weak になっていないか
@property(nonatomic, weak) UserClass *unarchveObj; //×

    unarchiveObjectWithFile を受け取る変数は、所有権を持たないといけないので strong である必要があります。
@property(nonatomicstrong) UserClass *unarchveObj; //◯
    

iOS WebView 実機で画像が表示されない。

2013/09/11 6:47 に masaki gadgetgeek が投稿   [ 2013/11/03 0:31 に更新しました ]

シミュレータでは問題なく表示するのに
実機で画像が出ない場合。

ファイルの大文字小文字(特に拡張子)が実際のファイルと一致しているかを疑う。

<img src="image.png" /> と
<img src="image.PNG" />

という違い。
意外にハマる。

iOS SDK Version のdefine (iOS 7, XCode5でのみビルド)

2013/07/05 23:08 に masaki gadgetgeek が投稿

MonCal/MonCalite の iOS 7 対応のためソースコードを修正していますが、
iOS 7 独自の修正を加えるとXCode5 でしかビルドが通りません。

しかしXCode 5 は現在(2013/7/6時点)は、β版なのでリリース用には使えません。

ということで、現在の正規版 XCode4.6ではiOS 7のソースをビルドしないように
コンパイルオプションで切り替えたくなります。

べつにこれはiOS 7 に限ったことではないのですが。。。

iOS 7 のSDKでは
usr/include  Availability.h に

#define __IPHONE_7_0     70000

という定義がありますので

#ifdef  __IPHONE_7_0

// XCode 5 以降でビルドされるコード

#endif

とすれば良いみたいです。

1-10 of 62