2011年12月1日 星期四

iOS MD5編碼

#import <CommonCrypto/CommonDigest.h>

@implementation NSString(MD5)

- (NSString*)MD5
{
// Create pointer to the string as UTF8
  const char *ptr = [self UTF8String];

  // Create byte array of unsigned chars
  unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];

// Create 16 bytes MD5 hash value, store in buffer
  CC_MD5(ptr, strlen(ptr), md5Buffer);

// Convert unsigned char buffer to NSString of hex values
  NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
  for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) 
[output appendFormat:@"%02x",md5Buffer[i]];

  return output;
}

@end

iOS 建立UUID

#import "CreateUUID.h"

@implementation CreateUUID

+ (NSString *)createUUID
{
    // Create universally unique identifier (object)
    CFUUIDRef uuidObject = CFUUIDCreate(kCFAllocatorDefault);
    
    // Get the string representation of CFUUID object.
    NSString *uuidStr = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuidObject) autorelease];
    
    // If needed, here is how to get a representation in bytes, returned as a structure
    // typedef struct {
    //   UInt8 byte0;
    //   UInt8 byte1;
    //   ...
    //   UInt8 byte15;
    // } CFUUIDBytes;
    CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuidObject);
    
    CFRelease(uuidObject);
    
    return uuidStr;
}

@end

iOS ThreeDESBase64

#import "ThreeDESBase64.h"
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"

@implementation ThreeDESBase64

+ (NSString*)TripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt key:(NSString*)key 
{    
    const void *vplainText;
    size_t plainTextBufferSize;
    
    if (encryptOrDecrypt == kCCDecrypt)
    {
        NSData *EncryptData = [GTMBase64 decodeData:[plainText dataUsingEncoding:NSUTF8StringEncoding]];
        plainTextBufferSize = [EncryptData length];
        vplainText = [EncryptData bytes];
    }
    else
    {
        NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        plainTextBufferSize = [data length];
        vplainText = (const void *)[data bytes];
    }
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    // uint8_t ivkCCBlockSize3DES;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    // memset((void *) iv, 0x0, (size_t) sizeof(iv));
    
    //    NSString *key = @"123456789012345678901234";
    NSString *initVec = @"init Vec";
    const void *vkey = (const void *) [key UTF8String];
    const void *vinitVec = (const void *) [initVec UTF8String];
    
    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey, //"123456789012345678901234", //key
                       kCCKeySize3DES,
                       vinitVec, //"init Vec", //iv,
                       vplainText, //"Your Name", //plainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    //if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
    /*else if (ccStatus == kCC ParamError) return @"PARAM ERROR";
     else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
     else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
     else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
     else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
     else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED"; */
    
    NSString *result;
    
    if (encryptOrDecrypt == kCCDecrypt)
    {
        result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr 
                                                                length:(NSUInteger)movedBytes] 
                                        encoding:NSUTF8StringEncoding
                  autorelease];
    }
    else
    {
        NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
        result = [GTMBase64 stringByEncodingData:myData];
    }
    
    return result;    

如何在 XCode 4.2 設定部分程式碼不使用 ARC 方式分享

1. 選擇專案,此時會出現專案設定畫面。
2. 選擇你的 Target,並切換到 Build Phases 畫面。
3. 找到 Compile Sources 這個畫面,然後選擇你要設定不使用 ARC 的程式碼
4. 按下 Enter 鍵後,會跳出一個視窗要你輸入東西,在裏面輸入 -fno-objc-arc 就可以了。

2011年8月16日 星期二

UITableView 新增下拉更新(Pull-refresh)


https://github.com/enormego/EGOTableViewPullRefresh

一、找到你的UITableView / UITableViewController 的.h 文件,結合以下代碼,添加相應的元素:

#import "EGORefreshTableHeaderView.h"

@interface RootViewController : UITableViewController  {

EGORefreshTableHeaderView *_refreshHeaderView;

//  Reloading var should really be your tableviews datasource
//  Putting it here for demo purposes
BOOL _reloading;
}

- (void)reloadTableViewDataSource;
- (void)doneLoadingTableViewData;
@end


二、切換到你的UITableView / UITableViewController 的.m 文件,結合以下代碼,添加相應的元素:

- (void)viewDidLoad {
[super viewDidLoad];

if (_refreshHeaderView == nil) {

EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
view.delegate = self;
[self.tableView addSubview:view];
_refreshHeaderView = view;
[view release];

}

//  update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
}

#pragma mark -
#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{

//  should be calling your tableviews data source model to reload
//  put here just for demo
_reloading = YES;

}

- (void)doneLoadingTableViewData{

//  model should call this when its done loading
_reloading = NO;
[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];

}

#pragma mark -
#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

[_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];



}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

[_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];

}

#pragma mark -
#pragma mark EGORefreshTableHeaderDelegate Methods

- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{

[self reloadTableViewDataSource];
[self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];

}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{

return _reloading; // should return if data source model is reloading

}

- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{

return [NSDate date]; // should return date data source was last changed

}


三、最後呢,為了彰顯你良好的內存管理習慣,別忘了釋放掉相應的UI 元素:

- (void)viewDidUnload {
_refreshHeaderView=nil;
}

- (void)dealloc {

_refreshHeaderView = nil;
[super dealloc];
}

四、編譯之前,別忘了將EGORefreshTableHeaderView.h、EGORefreshTableHeaderView.m兩個文件,以及Enormego提供的那一套圖片包拖進你的工程裡。

五、很抱歉沒有第五步了,編譯你的工程,打開simulator ,看看效果吧。包你滿意。
其實還沒完,這裡補充一點花絮。關於這個Pull & Refresh 功能的完整版來龍去脈。其實呢,最早出現這個Pull & Refresh 功能的app 是Tweetie 2 ,也就是現在大家每天都在用的Twitter for iPhone 的前身。因為這個小功能實在是很好用很貼心,所以就被Enormego 團隊發現了。但是Tweetie 2 是閉源的,於是很牛逼很強大的Enormego 就自己寫了一個,並且很大方的放到GitHub 上開源了。但是諸位如果仔細回憶一下,不難發現,真正讓這個Pull & Refresh 走紅的,是Facebook 旗下的Three20 開源框架。

2011年7月20日 星期三

iOS 的 App Life Cycle

Apple Dev 講 iOS app 生命週期的文章在此:
The Core Application Design
iOS 的 App Life Cycle 比 Android Activity Life Cycle 簡單一點。
iOS 4 之前不支援背景多工時超單純,application delegate function被呼叫的順序如下:
1. 點選 app icon 啓動 app時
application:didFinishLaunchingWithOptions:
applicationDidBecomeActive:
2. 按下 Home 鍵返回桌面時
applicationWillTerminate:
真是簡單到不行了。
iOS 4 支援背景之後,按下 Home 鍵並不會結束 app 而是放入背景,接著進入 suspended 狀態,先不論多工 app 如 voip 或 media player 之類的,ㄧ般的 app delegate function 的呼叫情形大致上是:
1.  點選 icon 啓動 app
application:didFinishLaunchingWithOptions:
applicationDidBecomeActive:
2. 按下 Home 鍵返回桌面時
applicationWillResignActive:
applicationDidEnterBackgroud:
3. 再由桌面按 icon 返回 app
applicationWillEnterForegroud:
applicationDidBecomeActive:
基本上如此循環。iOS 4 原則上不會呼叫 applicationWillTerminate,只有當 app 跑在背景(非 suspended) 又忽然被中止的時候才會 call。點兩下 Home 鍵把 suspended apps 清除的時候並不會呼叫這個 function。

2011年1月31日 星期一

Flex安全沙箱

1.網路訪問的swf檔,Security.sandboxType值為remote,這種情況下通過伺服器上的跨域檔crossdomain.xml判斷是否能夠跨域訪問。比如http://site1/flash1.swf需要訪問http://site2上的資源,則需要在site2伺服器上crossdomain.xml中添加site1的訪問許可。

2.本地訪問的swf檔,Security.sandboxType值為localTrustedlocalWithNetwork localWithFile三者之一。localWithNetwork僅允許訪問網路資源,localWithFile僅允許訪問本地資 源,localTrusted兩者均可。Flash9 Debug版本默認為localTrusted(?待確認),Flash10 Debug版本默認為localWithNetwork

因此在使用Flex進行編譯時,如果訪問本地資源將會產生安全沙箱錯誤。
  • 解決方法一:更改工程屬性,Flex Compiler - > Additional compiler argumentsFlex3),加上"-use-network=false",該選項強制Security.sandboxTypelocalWithFile,帶來的問題是無法訪問網路資源.
  • 解決方法二:更改工程屬性,Run/Debug Settings - > Main ->Url or path to lauch,改為通過Url載入Flash,這樣Security.sandboxTyperemote,本地資源的相對路徑也將作為網路相對路徑進行 訪問。
  • 解決方法三:通過設置Flash Player Trust directory,將swf檔所在目錄放入Flash Player Trust directory中,這樣該swf安全沙箱類型Security.sandboxTypelocalTrusted。(但該方法在Window Server 2003Flash 10 Debug環境下暫未通過)

2011年1月9日 星期日

AS3 Smooth Loaded Bitmaps

對用loader的content的bitmap做平滑化處理



//建立一個loader元件,並加到stage
var slideLoader:Loader=new Loader();
this.addChild(slideLoader);
//下載圖
slideLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, scaleContentForPicture);
slideLoader.load(new URLRequest("images/tree.jpg"));
//做平滑化處理
function scaleContentForPicture() {
var smoother_bm=Bitmap(slideLoader.content);
smoother_bm.smoothing=true;
}

AS3 快速產生整數數列和不重覆亂數

快速產生整數數列
trace(new Array(10).sort(Array.RETURNINDEXEDARRAY));
// 0,1,2,3,4,5,6,7,8,9


快速產生不重覆亂數
// 產生 0 到 (n - 1) 不重複亂數陣列
function genRandomArray(n:int):Array
 {
  var ary:Array = [];
  while (n--) ary.push(Math.random());
  return ary.sort(Array.NUMERIC | Array.RETURNINDEXEDARRAY);
}
// 產生 0-9999 不重複亂數陣列
var ra:Array = genRandomArray(10000);


源於TICORE' BLOG