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;
}

2015년 4월 5일 일요일

2015년 2월 13일 금요일

facebook 이미지들 가로 스크롤과 비슷한 기능 구현...



페이스북에서 여러 이미지들이 가로로 스크롤되면서 보여지는 UI를 구현하기 위해서는  UICollectionViewFlowLayout를 상속받아서 구현해야 한다.

구현 시나리오.
1. 우선 interface builder에서 collectionview의 paging 기능을 disable. 이때 collectionview의 frame의 가로 사이즈는 window의 가로 사이즈와 같게 설정.

2. UICollectionViewFlowLayout를 상속받아서 targetContentOffsetForProposedContentOffset 을 구현.
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)contentOffset
                                 withScrollingVelocity:(CGPoint)velocity
{
    NSArray* layoutAttributesArray = [self layoutAttributesForElementsInRect:self.collectionView.bounds];
   
    if(layoutAttributesArray.count == 0)
        return contentOffset;
   
    UICollectionViewLayoutAttributes* candidate = layoutAttributesArray.firstObject;
   
    for (UICollectionViewLayoutAttributes* layoutAttributes in layoutAttributesArray)
    {
        if (layoutAttributes.representedElementCategory != UICollectionElementCategoryCell)
            continue;
       
       
        if((velocity.x > 0.0 && layoutAttributes.center.x > candidate.center.x) ||
           (velocity.x <= 0.0 && layoutAttributes.center.x < candidate.center.x))
            candidate = layoutAttributes;
    }
   
    return CGPointMake(candidate.center.x - self.collectionView.bounds.size.width * 0.5f, contentOffset.y);

}

3. viewcontroller의 적절한 위치에서 layout을 설정
UICollectionViewFlowLayout *flowLayout = [[ArbitaryCollectionViewFlowLayout alloc] init];
[cell.collectionView setCollectionViewLayout:flowLayout animated:YES];


reference : http://stackoverflow.com/questions/15919457/uicollectionview-paging-like-safari-tabs-or-app-store-search

문장에서 검색어와 일치하는 모든 단어 볼드처리 하기

{
    UIFont *boldFont = [UIFont boldSystemFontOfSize:10];
    UILabel *sentenceLabel = [[UILabel alloc] init];
    sentenceLabel.text = @"If you still feel the need to clean your ear, anything you can easily see or touch with the pad of your finger is fair game. But if you want to snake into your ear with a narrow tool, just remember this advice from Chandrasekhar: Nothing smaller than your elbow.";
    NSString *sentence = sentenceLabel.text;
    NSString *keyword = @"your";
    [sentence enumerateSubstringsInRange:NSMakeRange(0, [sentence length])
                                   options:NSStringEnumerationByWords
                                usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                                    if ([substring isEqualToString:keyword]){
                                        NSLog(@"%@", substring);
                                        [attributedText addAttribute:NSFontAttributeName value:boldFont range:substringRange];
                                    }
                                }];
        [sentenceLabel setAttributedText:attributedText];
    }