2013年7月23日 星期二

iOS write and read file to NSMutableArray

好用的兩個讀取寫入function

- (BOOL) writeToFile:(NSString *)filename writeData:(NSMutableArray *)data{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *fileName = [NSString stringWithFormat:@"%@/%@", documentsDirectory, filename];
    
    return [data writeToFile:fileName atomically:NO];
    
}
- (BOOL) loadFromFile:(NSString *)filename writeData:(NSMutableArray *)data{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *fileName = [NSString stringWithFormat:@"%@/%@", documentsDirectory, filename];
    
    [data addObjectsFromArray:[NSMutableArray arrayWithContentsOfFile:fileName]];
    return 0;
}

2013年7月22日 星期一

fail2ban

最近電腦Server不斷被從ssh攻擊測試密碼,讓我的log檔不堪其擾...

找到fail2ban的小工具來幫忙阻擋。

安裝:sudo apt-get install fail2ban

使用:修改/etc/fail2ban/jail.conf來開啟ssh的阻擋功能
  [ssh]
  enabled  = true
  port     = ssh
  filter   = sshd
  logpath  = /var/log/auth.log
  bantime  = -1
  maxretry = 3

重新開啟sudo /etc/init.d/fail2ban restart

....這個世界清靜了....(不過iptable越來越多規則了 ="=)

其他:sudo fail2ban-client status ssh  //查看ssh
      /etc/fail2ban/filter.d/    //過濾條件
      /etc/fail2ban/action.d/    //動作

修改Baker framework,變成書架功能

本篇主要的目的是希望修改Baker ebook framework,並套AQGridView framework。我們可以寫出類似雜誌櫃的APP來觀看電子書,而不需要全部重新篡寫。

Baker主要利用RootViewController來當作主要的控制,並透過自己客製的UIWindow來管理使用者的觸碰事件,所以在BakerAppDelegate裡有段程式碼:

self.window = [[[InterceptorWindow alloc] initWithTarget:self.rootViewController.scrollView eventsDelegate:self.rootViewController frame:[[UIScreen mainScreen]bounds]] autorelease];

利用自訂的InterceptorWindow來取代原本的UIWindow,

[window addSubview:rootViewController.view];

再將rootViewController加入window中,這行程式也可以使用 window.view.rootViewController = rootViewController  取代。

現在我們希望對Baker修改,並希望不需要動到太多它的程式碼,但是Baker設計的初衷是提供電子書一個簡單的APP套用環境。所以他Modulize的程度並不高,修改起來困難。我這邊會慢慢嘗試去做修改,並將我修改的過程寫下來。

1. 替換rootViewController
現在必須將Baker裡的第一頁View給置換掉,置換成書櫃的頁面,讓使用者可以先選擇書之後,在將書本內容丟給Baker去處理。

2012年11月28日 星期三

ios http post a file

使用NSMutableURLRequest以及NSURLConnection:
-(void) uploadBinary:(NSData * ) binary withURL:(NSString * ) urlAddress withAttName:(NSString *) attname andFilename:(NSString *) filename{
    
    NSURL *theURL = [NSURL URLWithString:urlAddress];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL 
                                                              cachePolicy:NSURLRequestReloadIgnoringCacheData 
                                                          timeoutInterval:20.0f];
    [theRequest setHTTPMethod:@"POST"];
    NSString *boundary = [[NSProcessInfo processInfo] globallyUniqueString];
    NSString *boundaryString = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [theRequest addValue:boundaryString forHTTPHeaderField:@"Content-Type"];
    
    // define boundary separator...
    NSString *boundarySeparator = [NSString stringWithFormat:@"--%@\r\n", boundary];
    
    //adding the body...
    NSMutableData *postBody = [NSMutableData data];

    [postBody appendData:[boundarySeparator dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",attname, filename] dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:binary];
    
    [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r \n",boundary]
                          dataUsingEncoding:NSUTF8StringEncoding]];
    [theRequest setHTTPBody:postBody];    
    
    
    [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];


另一種簡單的方式可以使用ASIFormDataRequest from ASIHTTPRequest lib:


ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@"POST"];
            
[request setFile:dataDir forKey:nil];

[request setDelegate:self];
[request startAsynchronous];

=========

- (void) requestFinished:(ASIHTTPRequest *)request {
    //NSString *responseString = [request responseString];
    NSLog(@"Response %d : %@", request.responseStatusCode, [request responseString]);
    
    //NSData *responseData = [request responseData];
}

- (void) requestStarted:(ASIHTTPRequest *) request {
    NSLog(@"request started...");
}

- (void) requestFailed:(ASIHTTPRequest *) request {
    NSError *error = [request error];
    NSLog(@"%@", error);
}

2012年10月4日 星期四

iOS與Facebook SDK連結,以及簡單貼文

第一步必須在AppDelegate的地方接住http近來之Handler,並將此url遞給Facebook物件:

//=====In appDelegate.m=======

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    // attempt to extract a token from the url
   
    //利用rootViewController來取得擁有Facebook物件之viewController
    UINavigationController* testing = (UINavigationController*)self.window.rootViewController;
    IndexViewController *controller = (IndexViewController*)[testing.viewControllers objectAtIndex:1];

    //將url遞給facebook物件,之後facebook之Delegate才會驅動fbDidLogin與fbDidLogout
    return [controller.facebook handleOpenURL:url];
}

接著在擁有Facebook物件之ViewController初始化facebook,並使用NSUserDefault來記錄登入的狀態:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Facebook物件初始化,並登入AppID
    facebook = [[Facebook alloc] initWithAppId:AppID andDelegate:self];

    //使用NSUserDefault來記錄登入狀態
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    //檢查是否有用過
    if ([defaults objectForKey:@"FBAccessToken"]
        &&[defaults objectForKey:@"FBExpirationDate"]) {
        //如果沒有重新開一個
        facebook.accessToken = [defaults objectForKey:@"FBAccessToken"];
        facebook.expirationDate = [defaults objectForKey:@"FBExpirationDate"];
    }
}


登入程序:

-(void)login
{
     //檢查Facebokk是否連線還在
     if (![facebook isSessionValid]) {

        //如果已經不再連線狀態,重新連線
        //定義需要的權限
        NSArray *permissions =  [NSArray arrayWithObjects:
                                 @"user_hometown", @"read_stream", @"user_birthday",
                                 @"user_about_me", @"publish_stream", @"offline_access", nil];
        //登入
        [facebook authorize:permissions];
    }else{
        //如果已經在登入狀態的話,擷取使用者資訊
        [facebook requestWithGraphPath:@"me" andDelegate:self];
    }

}

貼文程序:

-(void)postToWall
{
    NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   AppID, @"app_id",
                                   @"http://www.google.com.tw/", @"link",
                                   @"http://www.google.com.tw/pic.jpg", @"picture",
                                   @"Facebook test", @"name",
                                   @"caption", @"caption",
                                   @"", @"description",
                                   @""@"message",
                                   nil];
    [facebook dialog:@"stream.publish" andParams:params andDelegate:self];

}

剩下一些FB之Delegate:

#pragma mark - FBRequestDelegate

- (void)requestLoading:(FBRequest *)request
{
    
}

- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"received response:%@",response);
}

- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
    
}

- (void)request:(FBRequest *)request didLoad:(id)result
{
    //利用Facebook物件request之資訊會傳遞到result,可以從這邊去收資料
    if ([result isKindOfClass:[NSArray class]] && [result count]>0) {
        result = [result objectAtIndex:0];
    }
    if ([result objectForKey:@"name"]){
        userName = [result objectForKey:@"name"];
    }
}

- (void)request:(FBRequest *)request didLoadRawResponse:(NSData *)data
{
    
}

//如果登入成功會呼叫此function
- (void)fbDidLogin {

    //擷取個人資訊,回饋資訊回從- (void)request:(FBRequest *)request didLoad:(id)result接收
    [facebook requestWithGraphPath:@"me" andDelegate:self];

    //將成功登入之資訊傳到NSUserDefault
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessToken"];
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDate"];
    [defaults synchronize];
}
-(void)fbDidLogout
{
    //登出時,清除帳戶資訊
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FBAccessToken"]) {
        [defaults removeObjectForKey:@"FBAccessToken"];
        [defaults removeObjectForKey:@"FBExpirationDate"];
        [defaults synchronize];
    }
}










2012年10月1日 星期一

ios HTTP post and get


在ios使用http post方法:

      NSString *post = @"did=abc&uid=王大明&score=0.3,0.4,0.5,1.1,1.4";
        NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
        
        NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
        
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:@"http://greenevent2.sunlight.tw/putdata2.asp"]];
        [request setHTTPMethod:@"POST"];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setHTTPBody:postData];
        NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
        if (conn)
        {
            receivedData = [NSMutableData data];
        }
        else
        {    
        }


在ios使用http get方法:

NSMutableURLRequest *request = [[NSMutableURLRequest allocinit];
[request setURL: apiUrl];
[request setHTTPMethod:@"GET"];


NSURLConnection *conn=[[NSURLConnection allocinitWithRequest:request delegate:self];
if (conn)
{
   receivedData = [NSMutableData data];
}



Delegate方法:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"response");
    [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
    [receivedData appendData:d];
    NSLog(@"didReceiveData");
    NSString* newStr = [[NSString alloc] initWithData:receivedData
                                             encoding:NSUTF8StringEncoding];
    NSLog(@"returnData:%@",newStr);

    //NSLog(@"receivedData:%@",receivedData);
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"")
                                 message:[error localizedDescription]
                                delegate:nil
                       cancelButtonTitle:NSLocalizedString(@"OK", @"")
                       otherButtonTitles:nil] show];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"connectionDidFinishLoading");
    /*
    NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
    
    // Do anything you want with it
    
    [responseText release];
     */
}

// Handle basic authentication challenge if needed
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSString *username = @"username";
    NSString *password = @"password";
    
    NSURLCredential *credential = [NSURLCredential credentialWithUser:username
                                                             password:password
                                                          persistence:NSURLCredentialPersistenceForSession];
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

同步方式


  1. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];           

  2. [request setURL:[NSURL URLWithString:urlStr]];  

  3. [request setHTTPMethod:@"GET"];  

  4. NSData *returnData = [NSURLConnection sendSynchronousRequest:request   
  5.                                            returningResponse:nil error:nil];   
  6.   
  7. [request release];  









2012年6月21日 星期四

在iOS上使用html parser

這裡是使用libxml2與hpple來做html parser。

1. 必須先將libxml2加到專案裡,可參考以下連結教學
http://justcoding.iteye.com/blog/1474176

2. 將hpple framework加到專案裡,
   下载hpple from https://github.com/topfunky/hpple
   加入以下檔案:HTFpple.h HTFpple.m HTFppleElement.h HTFppleElement.m XPathQuery.h XPathQuery.m

   NSString *htmlString=[NSString stringWithContentsOfURL:[NSURL URLWithString: @"http://ebook.sunlight.tw/"] encoding: NSUTF8StringEncoding error:nil];          NSData *htmlData=[htmlString dataUsingEncoding:NSUTF8StringEncoding];      TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];   
    NSArray *elements  = [xpathParser searchWithXPathQuery:@"/html/body/pre/a"]; // get the title    
    TFHppleElement *element  = [xpathParser peekAtSearchWithXPathQuery:@"/html/body/pre/a"];
    TFHppleElement *element2  = [xpathParser peekAtSearchWithXPathQuery:@"/html/body/pre/a[2]"];
    NSString *elementContent = [element objectForKey:@"href"];
  
    NSLog(@"result = %@",element);
     NSLog(@"result = %@",element2);
    NSLog(@"result = %@",[element attributes]);
    NSLog(@"result = %@",[element2 attributes]);