2013年10月29日 星期二

網址可以直接get到json時的做法

NSURL* url = [NSURL URLWithString:@"http://www.marq.com.tw/ooxx"];
   
    //這個方法會卡住main thread造成不順,但這裡的json大小只有幾byte,所以剛好可以適用。
    NSData *jsonData = [NSData dataWithContentsOfURL:url];

    NSString *myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    NSLog(@"data = %@",myString);
   
    NSError* error = nil;
    if (jsonData) {
        id _jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData                                                 options:NSJSONReadingMutableContainers error:&error];
        if ([_jsonObject isKindOfClass:[NSDictionary class]]) {
            NSDictionary* jsonDictionary = (NSDictionary*)_jsonObject;
            NSLog(@"%@",jsonDictionary);
        }else if ([_jsonObject isKindOfClass:[NSMutableArray class]]) {
            NSArray* jsonArray = (NSArray*)_jsonObject;
            NSLog(@"%@",jsonArray);
        }
    }

把CAlayer轉成UIImage

- (UIImage *)imageFromLayer:(CALayer *)layer
{
  UIGraphicsBeginImageContext([layer frame].size);

  [layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

  UIGraphicsEndImageContext();

  return outputImage;
}

HttpRequest : get資料

-(void)asyncDownloadInfoForBookAtURL:(NSURL *)url
{
    // Download the info for this book
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
    [request setHTTPMethod:@"GET"];
   
    // Do not start the network operation immediately
    NSURLConnection *aConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
   
    // Use the run loop associated with the main thread
    [aConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
   
    // Start the network operation
    [aConnection start];
}

delegate (委派)有四個

// 開始接收資料,會呼叫此方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
當系統開始要接收資料的時候這個方法會被呼叫到
要把這 responseData 給清空,如果UI上有ProgressBar的話要將之歸零

// 接收新的資料時,會呼叫此方法
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
每次資料在下載的時候,會不停的呼叫這個方法
可以看到這個data傳入的參數,就是每一小塊一小塊的資料
我們只要把它累加起來即可,如果UI上有ProgressBar的話就可以慢慢累加1

// 下載完畢時,會呼叫此方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
最後跑完會呼叫這個方法,就是你需要做處理的部分
例如顯示到畫面上,存入SQLite....等等


// 連線錯誤時,會呼叫此方法
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
最後就是這個,中間若有網路錯誤等因素就會呼叫這個方法
你可以跳一個提示框或是印Log

2013年10月26日 星期六

把結構轉成物件型式以指標存放

有些資料結構無法像物件一樣,以指標存放,這時可以用nsvalue去包起來使用。
例如intfloatchar, pointers, structures, id 等等

NSRange myRange = {4, 10};
NSValue *theValue = [NSValue valueWithBytes:myRange objCType:@encode(NSRange)];

2013年10月24日 星期四

+imageNamed 會cache memory直到low memory才會釋放

  • The -initWithContentsOfFile: creates a new image without caching, it's an ordinary initialization method.
  • The +imageNamed: method uses cache. Here's a documentation from UIImage Reference:
    This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.
    UIImage will retain loaded image, keeping it alive until low memory condition will cause the cache to be purged.

iOS captureScreen

- (UIImage *) captureScreen {
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    CGRect rect = [keyWindow bounds];
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [keyWindow.layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

2013年10月21日 星期一

CGBitmapContextCreate後的圖會上下顛倒的問題

//所以在做CGBitmapContextCreatet前面先行上下反轉一次
UIImage *image = [UIImage imageNamed:@"testImage.png"];    
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);       

CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, imageRect, image.CGImage);

2013年10月8日 星期二

如何把UIImage轉成pixel data

截自http://stackoverflow.com/questions/448125/how-to-get-pixel-data-from-a-uiimage-cocoa-touch-or-cgimage-core-graphics

- (NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)xx andY:(int)yy count:(int)count
{
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
   
    // First get the image into your data buffer
    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
   
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);
   
    // Now your rawData contains the image data in the RGBA8888 pixel format.
    int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
    for (int ii = 0 ; ii < count ; ++ii)
    {
        CGFloat red   = (rawData[byteIndex]     * 1.0) / 255.0;
        CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0;
        CGFloat blue  = (rawData[byteIndex + 2] * 1.0) / 255.0;
        CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
        byteIndex += 4;
       
        UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
        [result addObject:acolor];
    }
   
    free(rawData);
   
    return result;
}