2017년 1월 8일 일요일

겔러리에서 모든 이미지 불러오기

-(void)getAllPhotos
{
    [[Util sharedInstance] showLoadingView];
    
    NSMutableArray *photos = [[NSMutableArray alloc] init];
    PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
    allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
    PHFetchResult *allPhotos = [PHAsset fetchAssetsWithOptions:allPhotosOptions];
    PHFetchResult *fetchResult = @[allPhotos][0];
    
    for (int x = 0; x < fetchResult.count; x ++) {
        
        PHAsset *asset = fetchResult[x];
        photos[x] = asset;
    }
    
    self.assets = photos;
    
    [[Util sharedInstance] hideLoadingView];
    [_collectionView reloadData];

}


- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.selectedAssets = [[NSMutableArray alloc] init];
    self.assets = [[NSMutableArray alloc] init];
    
    self.manager = [PHImageManager defaultManager];
    self.options = [[PHImageRequestOptions alloc] init];
    _options.resizeMode = PHImageRequestOptionsResizeModeFast;
    _options.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
    
    [self requestAuthorizationWithRedirectionToSettings];
    
    //[self performSelector:@selector(getAllPhotos) withObject:nil];

}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    BoardPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"BoardPhotoCell" forIndexPath:indexPath];
    
    cell.checkIndicator.hidden = NO;
    PHAsset *asset = [_assets objectAtIndex:indexPath.item];
    [_manager requestImageForAsset:asset
                       targetSize:CGSizeMake(1024.f,1024.f)
                      contentMode:PHImageContentModeDefault
                          options:_options
                    resultHandler:^void(UIImage *image, NSDictionary *info) {
                        cell.photo.image = image;
                    }];
    
    //update checkbox
    NSUInteger foundIndex = [_selectedAssets indexOfObject:asset];
    if (foundIndex != NSNotFound) {
        [cell setCheck:YES];
    } else {
        [cell setCheck:NO];
    }
    
    return cell;

}

갤러리 권한 요청

- (void)requestAuthorizationWithRedirectionToSettings {
    dispatch_async(dispatch_get_main_queue(), ^{
        PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
        if (status == PHAuthorizationStatusAuthorized)
        {
            //We have permission. Do whatever is needed
        }
        else
        {
            //No permission. Trying to normally request it
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (status != PHAuthorizationStatusAuthorized)
                {
                    //User don't give us permission. Showing alert with redirection to settings
                    //Getting description string from info.plist file
                    NSString *accessDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSPhotoLibraryUsageDescription"];
                    UIAlertController * alertController = [UIAlertController alertControllerWithTitle:accessDescription message:@"To give permissions tap on 'Change Settings' button" preferredStyle:UIAlertControllerStyleAlert];

                    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
                    [alertController addAction:cancelAction];

                    UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:@"Change Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
                    }];
                    [alertController addAction:settingsAction];

                    [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
                }
            }];
        }
    });
}

출처 : http://stackoverflow.com/questions/13572220/ask-permission-to-access-camera-roll


2015년 9월 4일 금요일

sqlite3에서 쿼리한결과 array로 리턴

+ (NSMutableArray *)doGetWordInfo:(NSString *)queryString
{
    NSMutableArray *entries=[[NSMutableArray alloc] init];
    const char *query_stmt = [queryString UTF8String];
    sqlite3_stmt    *statement;
    
    if (sqlite3_prepare_v2(gTheDb, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
        int columnCount = sqlite3_column_count(statement);
        
        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            NSMutableDictionary *entryDic = [[NSMutableDictionary alloc] init];
            
            for (int columnIndex=0; columnIndex<columnCount; columnIndex++) {
                NSNumber *tmpNumberValue=nil;
                NSString *tmpStringValue=@"";
                
                NSString *columnName = [NSString stringWithUTF8String:(const char *) sqlite3_column_name(statement, columnIndex)];
                
                int columnType = sqlite3_column_type(statement, columnIndex);
                if (columnType == SQLITE_INTEGER) {
                    tmpNumberValue =[NSNumber numberWithInt: sqlite3_column_int(statement, columnIndex)];
                    [entryDic setValue:tmpNumberValue forKey:columnName];
                } else if(columnType == SQLITE_TEXT) {
                    tmpStringValue = [NSString stringWithUTF8String:(const char *) sqlite3_column_text(statement, columnIndex)];
                    [entryDic setValue:tmpStringValue forKey:columnName];
                }
            }
            
            [entries addObject:entryDic];
            entryDic = nil;
        }
    }
    sqlite3_finalize(statement);
    return entries;

}

2015년 6월 8일 월요일

app설정의 notification 설정값 가져와서 업데이트 하기.

system setting에서 application의 notification 설정값을 변경하면,  application에서 그 값을 가져와 반영하는 방법.


1. uiviewcontroller에 notification 등록

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationEnteredForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification

                                               object:nil];


- (void)applicationEnteredForeground:(NSNotification *)notification {
    [self updateNotificationSound];
}



2. 설정값 가져오기 

- (void)updateNotificationSound
{
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")){
        UIUserNotificationType type = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
        if (type & UIUserNotificationTypeSound){
            _notificationSettingValue.text = @"소리";
        } else {
            _notificationSettingValue.text = @"무음";
        }
    } else {
        UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
        if (types & UIRemoteNotificationTypeSound) {
            _notificationSettingValue.text = @"소리";
        } else {
            _notificationSettingValue.text = @"무음";
        }
    }
}


3. 상수값의 의미:

UIUserNotificationTypeNone : Allow Notifications on/off
UIUserNotificationTypeBadge : Badge App Icon on/off
UIUserNotificationTypeSound : Sounds on/off







@ How to open application system notification setting view

- (void)launchSystemApplicationNotificationSettingView {
    if (&UIApplicationOpenSettingsURLString)
    { //only for ios8
        NSURL *appSettings = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:appSettings];
    }

}







2015년 5월 11일 월요일

objc_setAssociatedObject , objc_getAssociatedObject


#import <objc/runtime.h>


예제1)

// set
    {
        objc_setAssociatedObject(self, @"ShouldDismissModalViewLater", modalViewController, OBJC_ASSOCIATION_ASSIGN);
    }
    
    // get and using
    {
        UIViewController *modalVC = objc_getAssociatedObject(self, @"ShouldDismissModalViewLater");
        [modalVC dismissViewControllerAnimated:YES completion:nil];
    }



예제2)

// set
    {
        NSArray *gotArray;
        objc_setAssociatedObject(self, @"MyGotArray", gotArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    // get and using
    {
        NSArray *array = objc_getAssociatedObject(self, @"MyGotArray");
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            
        }];
    }


예제3)
Easier syntax
Alternatively you could use @selector(nameOfGetter) instead of creating a static pointer. Why? See http://stackoverflow.com/a/16020927/202451. Example:
- (NSArray *)laserUnicorns {
    return objc_getAssociatedObject(self, @selector(laserUnicorns));
}

- (void)setLaserUnicorns:(NSArray *)unicorns {
    objc_setAssociatedObject(self, @selector(laserUnicorns), unicorns, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
}

async download images

NSURLSession를 이용한 방법)

xxx.h
NSURLSession *mealNewsUrlSession;

xxx.m

// initialization
mealNewsUrlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];


// use
NSURL *imageURL = [NSURL URLWithString:imagePath];
            NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
            NSURLSessionDataTask *task = [mealNewsUrlSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                if (error)
                {
                    NSLog(@"ERROR: %@", error);
                }
                else
                {
                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                    
                    if (httpResponse.statusCode == 200)
                    {
                        UIImage *image = [UIImage imageWithData:data];
                        [mealNewsImageCache setObject:image forKey:imagePath];
                        
                        dispatch_async(dispatch_get_main_queue(), ^{
                            [cell.mealPhoto setImage:image];
                            [cell setNeedsLayout];
                            //[cell.activityIndicator stopAnimating];
                        });
                    }
                    else
                    {
                        NSLog(@"Couldn't load image at URL: %@", imageURL);
                        NSLog(@"HTTP %ld", (long)httpResponse.statusCode);
                    }
                }
            }];

            [task resume];


dispatch를 이용한 방법)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
        dispatch_async(queue, ^(void) {
            
            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:profilePath]];
            UIImage* image = [[UIImage alloc] initWithData:imageData];
            if (image) {
                [mealNewsImageCache setObject:image forKey:profilePath];
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.profilePhoto setImage:image forState:UIControlStateNormal];
                });
            }

        });

3. 한번에 모두 다운로드 한후에 이용하는 방법)

xxx.h
NSOperationQueue *_asyncQueue;

xxx.m
// initialization
{
_asyncQueue = [[NSOperationQueue alloc] init];
or
_asyncQueue = [NSOperationQueue mainQueue]
or
_asyncQueue = [NSOperationQueue currentQueue]
}

{
// use
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [NSURLConnection sendAsynchronousRequest:request queue:_asyncQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            
            UIImage *image = [[UIImage alloc] initWithData:data];
            [Utility saveImageToFS:UIImageJPEGRepresentation(image, 1.0) withUrl:request.URL];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                //update cell
            });
        }];
    }); //dispatch_async
}

+ (void) saveImageToFS:(NSData *)data withUrl:(NSURL *)url {
    NSString *dir = [[url absoluteString] stringByDeletingLastPathComponent];
    NSString *filename = [url.absoluteString lastPathComponent];
    
    //
    NSString *path = [NSString stringWithFormat:@"%@/%@",[Utility getMangaRootPath],dir];
    if(![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil])
        NSLog(@"fail to create directory ");
    
    
    NSString *fullpath = [path stringByAppendingFormat:@"/%@",filename];
    if(![data writeToFile:fullpath atomically:YES])
        NSLog(@"fail to write file");
}

+ (NSString *)getMangaRootPath {
    NSString *path = [NSString stringWithFormat:@"%@/%@",
                      [self getCachesPath],
                      kMangaEditionDirectory];
    // create directory
    [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
    return path;
}

+ (NSString*)getCachesPath {
    NSString *documentPath = nil;
    
    NSSearchPathDirectory directory;
    directory = NSCachesDirectory;
    
    NSArray* directories = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
if(directories != nil && [directories count] > 0)
        documentPath = [directories objectAtIndex:0];
    return documentPath;
}