ファイル出力(追記 append)

 

    
    NSString* folder = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)[0];
    NSString* filePath = [NSString stringWithFormat:@"%@/out.txt",folder ];


//ファイル名の取り出し NSString* folderName = [filePath lastPathComponent]; //ファル名の取り出し NSString* FileName = [filePath stringByDeletingLastPathComponent]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSError* error; //ファイルの有無の確認 BOOL result = [fileManager fileExistsAtPath:filePath]; if(!result){ BOOL success; //フォルダを作成 success = [fileManager createDirectoryAtPath:folderName withIntermediateDirectories:YES attributes:nil error:&error]; //ゼロバイトのファイルを作成 success = [fileManager createFileAtPath:filePath contents:nil attributes:nil]; } //ファイルの追記 NSString* rec = @"aaaaaaaaaaaaaaaa\n"; @synchronized (self) { NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:filePath]; [fh seekToEndOfFile]; NSData *data = [rec dataUsingEncoding:NSUTF8StringEncoding]; [fh writeData:data]; [fh closeFile]; }

 

参考

http://www.deftrash.com/blog/archives/2010/10/iphone_file_append.html

http://buchi.hatenablog.com/entry/2014/09/08/155919

 

UIAlertController 同期処理

UIAlertController を使用した際の同期処理がうまくできない。

セマホを使っても、元々メインスレッド上で処理されているらしく、wait待ちすると、ポップアップすら止まってしまう。

どうも VBでいうところの、DoEvents方式しかないようだ。

 

    ....
    [view presentViewController:alertController animated:YES completion:nil];

    while (! finished) {
        // 0.5秒間隔で、finishedしているか、確認しがなら待地合わせる。
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
    }

NSError の使い方

呼ばれる側

+ (BOOL)testMethod error:(NSError**)error{

    __block NSError*  responsError = nil;
    __block NSInteger httpStatus = 0;

    NSURLSessionDataTask* task = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    
        responsError =error;
        httpStatus = ((NSHTTPURLResponse* )response).statusCode;
    }];


    if (responsError){
        *error =responsError;
        return NO;
        
    }else  if (httpStatus == 200){
        error=nil;
        return YES;
    }else{
        NSDictionary *errorUserInfo = @{NSLocalizedDescriptionKey: @"upLoadで失敗しました",
                                        NSLocalizedFailureReasonErrorKey: @"HTTPコードが200以外"};
        
        *error = [[NSError alloc] initWithDomain:@"testMethod" code:httpStatus userInfo:errorUserInfo];
        return NO;
    }

}

呼ぶ側

   NSError* error = nil;
 
   BOOL rtn =  [testMethod error:&error];
   
    if (! rtn) {
        NSLog(@"%@",error);
        NSLog(@"%@",error.localizedDescription);
        NSLog(@"%@",error.localizedFailureReason);
    } 

 

NSLocalizedDescriptionKey で設定した内容は、error.localizedDescriptionで取得できる。

NSLocalizedFailureReasonErrorKey で設定した内容は、error.localizedFailureReason で取得できる。

 

アイコンバッチ

アイコンバッチを表示する方法を検索すると以下の用法が表示される 

[UIApplication sharedApplication].applicationIconBadgeNumber = 5;

 この通りやっても、表示されなかった。iOS9からは通知に関する設定を行わないといけなくなったようだ。


IOS9からは、ユーザーの認証が必要になったみただ。

下記のコードをAppDelegate.m 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 配下に実装する必要がある。

UIUserNotificationType types = UIUserNotificationTypeBadge;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:settings];

 初回実行時に、「〜( アプリ名)〜は通知を送信します

よろしいですか?」が表示されるようになる。許可する/しない の設定は、

後から変更できる。設定→通知→該当のアプリ。通知を許可をオン、Appアイコンにバッチを表示をオン。

これで、アイコンにバッチが表示されるようにはなったけど、

iOS10からは、非推奨のメソッドになっている!?


 iOS10でコンパイルエラーが出ないように書き直してみた。こんなのでいいのかなぁ?

AppDelegate.m

 

#import <UserNotifications/UserNotifications.h>   を冒頭で追加する必要あり



-
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted){ NSLog(@"承認された"); }else{ NSLog(@"承認されなかった"); } }]; return YES; }

この例の場合、アイコンバッチだけの確認になっています。

[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge + 

UNAuthorizationOptionAlert

)  とすれば、複数の条件が申請できるみたい。

 

granted には、許可に認否結果が渡ってくる。

初回許可しても、後々設定から不許可にした場合も、grantedには NOが渡ってくる。


バッチの数量はいつくまで、表示できるのか?

6桁まではそのまま表示される。

7桁以上の場合、中間の桁が ... 表示となり省略されるようだ。

f:id:nabe_shodai:20170619000247p:plain  f:id:nabe_shodai:20170619000300p:plain

 


参考

iOS9でバッジが表示されない時の対処法
https://trueman-developer.blogspot.jp/2015/12/ios9.html

 

iOS User Notifications framework」シリーズまとめhttp://dev.classmethod.jp/smartphone/iphone/user-notifications-framework-16/

 

iOS 10 User Notifications Framework実装まとめhttp://qiita.com/mshrwtnb/items/3135e931eedc97479bb5

アイコン

iOS用のアイコンを設定してみたい。

適当なサイズのものを当てはめると、

〜 Assets.xcassets: The app icon set named "AppIcon" did not have any applicable content.

ビルド実行で上記のようなメッセージ出てしまうので、正しいサイズのアイコンを適用する必要があるようだ。

 

異なるサイズのアイコンを用意するのに、便利なwebページがあった。

https://resizeappicon.com

アップした画像ファイルを、各種サイズに変換してくれる。

アップする画像ファイルは、PNG形式で、正方形でなければならないようだ。

 

2x  20pt は 40☓40px のファイル

3x  20pt は 60☓60px のファイル

2x  29pt は 58☓58px のファイル

3x  29pt は 87☓87px のファイル

・・・

をそれぞれ適用すれば良いようだ。

 

macのプレビューからもリサイズはできる。

[メニューバー]→[ツール]→[サイズを調整]

ピクセル指定で、縦、横を設定すればよい

f:id:nabe_shodai:20170622090639p:plain

 

 

クラスのサンプル

//

//  Person.h

//  クラスの基本

//

//  Created by shodai on 2017/06/15.

//  Copyright © 2017 Mycompany. All rights reserved.

//

 

#import <Foundation/Foundation.h>

 

@interface Person : NSObject

 

//この1行だけで、public なアクセサが生成されている(read/write)

@property NSString* name;

 

//この1行だけで、public なアクセサが生成されている(read)

@property (readonly) NSString* sex;

 

 

#pragma mark Protected Methods

-(NSInteger)coutup;

    

@end

 


//

//  Person.m

//  クラスの基本

//

//  Created by shodai on 2017/06/15.

//  Copyright © 2017 Mycompany. All rights reserved.

 

/*

 参考

 https://www.ecoop.net/memo/archives/objective-c-property-basics.html

 http://qiita.com/a_ishidaaa/items/6461f62a1a12208b0c50

 http://qiita.com/yuky_az/items/f2c3db2796d0a73dfde2

 http://adragoona.hatenablog.com/entry/2014/06/11/182527

 */

 

//

 

#import "Person.h"

 

 

 

@implementation Person{

    

    //完全にプライベートな扱いとなるインスタンス変数

    NSInteger count;

}

 

-(id)init{

    

    self = [super init];

 

    _sex = @"man";

    

    return self;

    

}

 

 

-(NSInteger)coutup{

    

    count++;

    

    return count;

    

}

    

 

 

@end


クラスを利用する側

    Person* person = [[Person alloc] init ];

 

    NSLog(@"%@",person.sex);

    NSLog(@"%@",[person sex]);

    

    //person.sex = @"woman"; コンパイルエラーになる

    

    person.name = @"aaa";

    

    NSLog(@"%@",person.name);

    NSLog(@"%@",[person name]);

 

    

    [person setName:@"bbb"];

 

    NSLog(@"%@",person.name);

    NSLog(@"%@",[person name]);

 

    NSLog(@"%ld",[person coutup]);

 

 

property ぷろぱてぃ


@property (nonatomic,copy) NSString* name;

———————
atomic
省略時のデフォルト。synchronizedでスレッドセーフにしたgetter,setterを生成します。

nonatomic
スレッドセーフでない単純なgetter,setterを生成します。iOSではパフォーマンスの問題からほとんどの場合nonatomicにすべきです。

———————

readwrite
デフォルト。getter/setter両方を生成します。


readonly
getterのみ生成します。

———————

geter=メソッド名
getterの名前を設定する。デフォルトはプロパティ名と同じ。BOOL 型のプロパティの名前を is〜とすると分かりやすくなります。

seter=メソッド名
setterの名前を設定する。デフォルトは「setプロパティ名」。あまり使われることはありません。

———————

assign
非オブジェクト型のデフォルト。NSIntegerなど値型、C由来の型など、メモリ管理が必要ないものに使用します。オブジェクト型の場合はassignでなくweakかunsafe_unretainedが推奨されます。

strong
オブジェクト型のARC環境デフォルト。setterで代入前のものをreleaseし、新たに代入するものをretainします。非オブジェクト型には使用できません。

retain
strongと全く同じです(参考:Transitioning to ARC Release Notes)

weak
オブジェクト型の非ARC環境デフォルト。代入時にretain/releaseを行いません。メモリアクセスエラーを避けるため参照先が解放された時はnilになります。strongと同様、非オブジェクト型には使用できません。

unsafe_unretained
weakと似ていますが、releaseされてもnilになりません。assignと同じですが、こちらはオブジェクト型を対象としています。

copy
retain/releaseする点はstrongと同じですが、代入時にsetterで引数のオブジェクトをretainせずに、新たなオブジェクトとしてコピー(_value = [value copy])してからretainします。用途としてはNSStringなどmutableな型(NSMutableString)が子クラスとして存在するものについて、代入後に外部からの値の変更を防ぐためにstrongの代わりにcopyを使用します。