Translate

2016年9月19日 星期一

IAP 筆記

注意事項

1.購買者買 100 元 ,有30元會是給蘋果 ,70元是給你

2.只能在實機上測試,測試時,會是SandBox下測試,並且也需使用測試帳號測試

產品項目

1.消耗性:可以重覆購買,但不會記錄(也就是你的APP砍掉就無法找回來了,除非自已找個伺服器記下來),加速時間藥水,主角的生命...(蘋果驗證收據時,只有第一次購買才有返回,接下來就無返回)

2.非消耗性:不能重覆購買,只能購買一次。並且永遠有效,只要你使用這個蘋果帳戶登入,就算你砍了APP再重新購買也一樣有效(驗證收據時,會返回收據)

3.自動續訂型訂閱:一段時間會自動續訂的產品,過1個月,3個月後,就會開始自動續訂了,蘋果有記時間的。(驗證收據時,會返回收據)

4.非續訂型訂閱:一段時間就會過期的產品,不過這東西蘋果也不會記,感覺跟消耗性一樣,只是產品分類不一樣用來區別(驗證收據時,會返回收據)

流程

[商品列表]

1.APP向APP Store取得清單(Bundle Identifier要與iTunes Connect申請的ID一樣)

2.拿到商品資訊


[使用者購買]

1.使用者登入

2.使用者在蘋果處理付費要求並回傳交易記錄


3.APP拿到這個交易記錄在詢問驗證伺服器這個記錄是否正確/成功(這裡是做個二次驗證的動作,怕有人偽造購買成功收據,所以多了個驗證流程)

4.回傳結果,確定成功就記錄此筆記錄,並購買這項產品

ps。如果是訂閱類型的產品是可要被使用者回復使用的



2016年8月31日 星期三

Apple 續約 更新憑證

因為最近續約了,一些憑證到期
如果一直無法上傳更新你的app,可以參考以下方式

1.先檢查你的xcode 上架帳號憑證是否有更新

★先開啟你的專案>到首頁>選General標籤(會看到版本編號那一頁)
★找Team下拉選單>選add account選項(關掉)然後檢查你目前使用的帳號
★選最右下角有個view details
★它會列出你憑證到期日,按下左下角download All即可更新你的憑證


2.到蘋果開發者中心更新你的憑證
★https://developer.apple.com/
★右上角選Account登入
★左邊選單第4個>Cerificates,IDs &Profiles
★看Certificates的選項是否有過期,若過期,點選項目>Revoke它就可以
★再到你的鑰匙圈工具建立新的憑證

★工具程式>鑰匙圈存取
★Apple Application Integration Certification Authority→會跟你註冊的一樣
★再到上方選單>鑰匙圈存取>憑證輔助程式>從憑證授權要求憑證
★填email,跟隨便埴一般名稱,選【儲存到磁碟】

★再回到蘋果開發者網頁新增新的憑證,選第一個App Store and Ad Hoc
★下一步>下一步,選擇剛剛從鑰匙圈存取下來的檔案,再按下一步即可生成最新的憑證


3.重開機

4.重開你的xcode

再上傳應該就可以順利更新了

2016年8月8日 星期一

Xampp 寄google信件服務錯誤

openssl.dll設定問題

1.到php/ext目錄下 找有無php_openssl.dll檔案
2.開啟php.ini
3.找extension的位置 是否有;或沒有加一下 extension=php_openssl.dll
4.可以用php相面打<?php phpinfo() ?>查看openssl suppoort是否為 enalbe


如果為win8的話
1.將xampp\xampp\sendmail\sendmail.exe相容性改一下
2.改windows xp(sp3),再改使用管理員(adminstor)執行


開啟google pop設定→https://support.google.com/mail/answer/13273?hl=en&rd=2
1.到gmail右上的設定
2.選pop/imap
3.再選開啟pop 所有郵件
4.儲存



若以上方法還不行,建議透過以下方法來使用,
1.下載stunnel,stunnel-5.35-installer.exe   (透過它代理ssl連線)
位置在http://www.stunnel.org/downloads.html?extra=/stunnel/win32/stunnel-4.27-installer.exe

2.安裝時會輸入國碼tw,然後接著就輸入一些基本資料,亂打aa也可以安裝,然後開啟桌面捷徑,上方選單選Configuration>edit Configuration改一下下面tag

[ssmtp]
accept  = 465
connect = 25
cert = stunnel.pem

改好後,儲存,關閉,然後上方選單Configuration>Reload Configuration

這邊設定好之後再改原本的php設定
xamp\php\php.ini
[mail function]

SMTP=localhost
smtp_port=25
sendmail_from = googlename@gmail.com
sendmail_path = "\"C:\xampp\sendmail\sendmail.exe\" -t"
mail.add_x_header=Off

最後再改sendmail的設定
xamp\sendmail\senmail.ini


smtp_server=localhost
smtp_port=25
smtp_ssl=auto
default_domain=gmail.com

重新開啟apache

另外如果寄信google該會問一些較低安全性的問題,直接打開吧!就能收到信了
https://www.google.com/settings/u/1/security/lesssecureapps?rfn=27&rfnc=1&asae=2&anexp=lbe2-R1_C


測試php

<?php
  $to ="receiver@gmail.com"; //收件者
  $title= "test"; //信件標題
  $msg = "smtp發信測試";//信件內容
  $headers = "From:my@gmail.com"; //寄件者

  if(mail("$to", "$title", "$msg", "$headers")):
   echo "信件已經發送成功。";//寄信成功就會顯示的提示訊息
  else:
   echo "信件發送失敗!";//寄信失敗顯示的錯誤訊息
  endif;
?>

2016年7月29日 星期五

App Google API Calendar 教學 (note)


  
→建立一個新的授權,若您的使用者砍了你的授權,二次想加回去,直接使用這個就好了
[self presentViewController:[self createAuthController] animated:YES completion:nil];

★授權

Google教學一般只給
kGTLAuthScopeCalendarReadonly

要管理的話(能新增修改編輯)授權權限要改為這個
kGTLAuthScopeCalendar

→建立一個日曆 


    GTLCalendarCalendar*newCalendar=[GTLCalendarCalendar object];

 //新名字就是new Calendar
    newCalendar.summary=@"new Calendar";

    GTLQueryCalendar *queryInsertCalendarList = [GTLQueryCalendar queryForCalendarsInsertWithObject:newCalendar];
    [self.service executeQuery:queryInsertCalendarList
                      delegate:self
             didFinishSelector:nil];


→取得日曆列表



- (void)fetchCalendarList {
    GTLQueryCalendar *query = [GTLQueryCalendar queryForCalendarListList];
    [self.service executeQuery:query
                      delegate:self
             didFinishSelector:@selector(Result_CalendarList:finishedWithObject:error:)];
}

- (void)Result_CalendarList:(GTLServiceTicket *)ticket
   finishedWithObject:(GTLCalendarCalendarList *)list
                error:(NSError *)error {
    
    if (error == nil) {

        for(GTLCalendarCalendarListEntry *cal in list.items){
            //cal.identifier;//判定是否有過
            NSLog(@"%@",cal.summary);
        }
        
    } else {
        [self showAlert:@"Error" message:error.localizedDescription];
    }

}


→刪除授權

 [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];



→建立一個事件,此事件活動為一整天

[CalendarID]
need change

- (void)CreateEvent{

    GTLCalendarEvent *calEvent =[GTLCalendarEvent object];
    calEvent.summary= @"test";
    calEvent.descriptionProperty=@"i am test";
    
    calEvent.start = [GTLCalendarEventDateTime object];
    calEvent.end = [GTLCalendarEventDateTime object];
    
    calEvent.start.dateTime=[GTLDateTime dateTimeWithDate:[NSDate dateWithTimeIntervalSinceNow:60*60] timeZone:[NSTimeZone localTimeZone]];


    calEvent.end.dateTime=[GTLDateTime dateTimeWithDate:[NSDate dateWithTimeIntervalSinceNow:60*60+60*60] timeZone:[NSTimeZone localTimeZone]];

    GTLDateTime *startDateTime = [GTLDateTime dateTimeForAllDayWithDate:[NSDate date]
                                                     ];
    
    calEvent.start = [GTLCalendarEventDateTime object];
    calEvent.start.date = startDateTime;
    
    calEvent.end = [GTLCalendarEventDateTime object];
    calEvent.end.date=startDateTime;
    
    
    GTLQueryCalendar *query = [GTLQueryCalendar queryForEventsInsertWithObject:calEvent calendarId:@"[CalendarID]" ];//日曆id
    
    [self.service executeQuery:query
                      delegate:self
             didFinishSelector:@selector(Result_CreateEvent:finishedWithObject:error:)];
}

//結果顯示
- (void)Result_CreateEvent:(GTLServiceTicket *)ticket
           finishedWithObject:(GTLCalendarEvent *)events
                        error:(NSError *)error {
    if (error == nil) {
        //events.identifier; 新增事件iid
    } else {
        [self showAlert:@"Error" message:error.localizedDescription];
    }
}


→編輯一個事件,更新時間為目前時間1小時後的事件

[CalendarID]
[EventID]
need change

   GTLCalendarEvent *calEvent =[GTLCalendarEvent object];
    calEvent.summary= @"change test";
    calEvent.descriptionProperty=@"i am change test";
    
    calEvent.start = [GTLCalendarEventDateTime object];
    calEvent.end = [GTLCalendarEventDateTime object];
    
    calEvent.start.dateTime=[GTLDateTime dateTimeWithDate:[NSDate dateWithTimeIntervalSinceNow:60*60] timeZone:[NSTimeZone localTimeZone]];
    
    
    calEvent.end.dateTime=[GTLDateTime dateTimeWithDate:[NSDate dateWithTimeIntervalSinceNow:60*60+60*60] timeZone:[NSTimeZone localTimeZone]];
    
    NSDate *anHourFromNow = [NSDate dateWithTimeIntervalSinceNow:60*60];
    GTLDateTime *startDateTime = [GTLDateTime dateTimeWithDate:[NSDate date]
                                                      timeZone:[NSTimeZone systemTimeZone]];
    GTLDateTime *endDateTime = [GTLDateTime dateTimeWithDate:anHourFromNow
                                                    timeZone:[NSTimeZone systemTimeZone]];
    
    calEvent.start = [GTLCalendarEventDateTime object];
    calEvent.start.dateTime = startDateTime;
    
    calEvent.end = [GTLCalendarEventDateTime object];
    calEvent.end.dateTime = endDateTime;
    
    
    GTLQueryCalendar *query = [GTLQueryCalendar queryForEventsUpdateWithObject:calEvent
                                                                    calendarId:@"[CalendarID]"                                    eventId:@"[EventID]"];//日曆id
    
    
    [self.service executeQuery:query
                      delegate:self
             didFinishSelector:nil];
}

→刪除一個事件

[CalendarID]
[EventID]
need change

GTLQueryCalendar *query = [GTLQueryCalendar queryForEventsDeleteWithCalendarId:@"[CalendarID]"   eventId:@"[EventID]"];//日曆id

[self.service executeQuery:query delegate:selfdidFinishSelector:nil];

App Google API Calendar 教學


★Google官方教學~快速建立跟檢視(本篇主要照這個改)
https://developers.google.com/google-apps/calendar/quickstart/ios?hl=zh-tw

Google官方教學~指南(如果注意到的話,也跟上面其實是同一頁面)
https://developers.google.com/google-apps/calendar/v3/reference/?hl=zh-tw

中文的API介紹
https://jaygoo.hackpad.com/google-Calendar-API-E5pl6UbGOvN#:h=4.取得日曆活動


下面是補充用的...
Google官方熱門產品查詢
https://developers.google.com/products/?hl=zh-tw


看帳戶的授權
https://security.google.com/settings/security/permissions

API申請憑證
https://console.developers.google.com/apis?pli=1


主要是照著官方教學做的...


1.剛開始先去申請憑證https://console.developers.google.com/apis?pli=1
建立一個專案,建立好後,再選【資料庫】(在左邊工具列),找右邊選項你要開的API項目,日曆在最右邊第二個位置,點開連結後,按下上方的啟用,就可以了。

2.接下來啟用以後,要建立憑證,按下【前往憑證】,重點來了,接下來呼叫來源下拉選擇iOS裝置,然後下方的使用者資料也要勾選後,再按下【我需要哪些憑證】…

3.然後你可以進行名稱命名,聯繫ID你可以隨便打一組,不過如果你有APP的話,還是用APP 的 SKU ID為主…

4.然後建立好,其他就看你要怎麼顯示授權頁面了…最主的是最後顯示出來的Client ID很重要,要留著,等一下程式要用到,不然也可以下載下來,裡面的檔案用筆記本開啟,把ID拿出來也可以…


~~~~~~~~~~~~~~~~


1.開你的XCode吧,建立一個專案,單一頁面,然後再開你的終端機(這裡要先安裝過CocoaPods,不會裝的話看一下這裡http://bahole.blogspot.tw/2016/07/cocoapods_28.html

2.然後一樣終端機的檔案位置要在你的專案底下 ,用pwd指令看看你的目錄在哪,確認位置正確後,在終端機直接貼google給你的教學...(我先照copy,有可能未來會變)

ps
QuickstartApp→是google的專案名,如果你的專案名不一樣要記得改下面內文的文字,改成跟你的專案名稱一樣
cat << EOF > Podfile &&
platform :ios, '7.0'
target 'QuickstartApp' do
    pod 'GoogleAPIClient/Calendar', '~> 1.0.2'
    pod 'GTMOAuth2', '~> 1.1.0'
end
EOF
pod install &&
open QuickstartApp.xcworkspace


3.如果順利的話,他就會幫你裝好了Google的檔案

4.它會直接打開你的專案,接下來依然無腦照著檔案名稱copy下去,除了
Client ID你要換成你自已的,應該就能執行成功了,問你要不要授權~然後就可以顯示最近前10筆活動

~~~~~~~~~~~~~~~~



#import <UIKit/UIKit.h>
#import "GTMOAuth2ViewControllerTouch.h"
#import "GTLCalendar.h"
@interface ViewController : UIViewController
@property (nonatomic, strong) GTLServiceCalendar *service;
@property (nonatomic, strong) UITextView *output;
@end


#import <UIKit/UIKit.h>
#import "GTMOAuth2ViewControllerTouch.h"
#import "GTLCalendar.h"
@interface ViewController : UIViewController
@property (nonatomic, strong) GTLServiceCalendar *service;
@property (nonatomic, strong) UITextView *output;
@end



2016年7月28日 星期四

CocoaPods安裝

試完了整個流程,發現有些地方會莫名卡住,所以在此留下記錄

CocoaPods大部份都要用終端機輸入指令

所以請開終端機>(finder上方選單)>前往>工具程式>終端機

點開它就可以了



接著請直接輸入指令

ruby -v

這時後應該會顯示ruby版本,一般mac都會有版本

然後再輸入下面指令安裝

sudo gem install cocoapods

接著會請你輸入使用者密碼(你在登入畫面要輸入的密碼,若沒有設的話,請先設一組= =)

然後順利的話,就會開始安裝了…(要等一陣子~

上面就結束安裝了…




接著就開始用了,請先開啟你的XCode開一個專案,然後將專案的資料夾丟到桌面

接著終端機的位置請指到你專案的位置

下面指令可以確認你現在的位置

pwd

如果位置不對,就用cd \desktop 之類的DOS指令移過去

接著要開一個指令檔,用以下指令建立(或是最後用記事本更改裡面的指令)

vim Podfile

然後它會進入很難用的編輯模式 = =
然後輸入以下指令

可以參考這個網址給的

https://guides.cocoapods.org/using/the-podfile.html


target 'CocoaPodsDemo' do
  source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'
pod 'AFNetworking', '~> 2.5'
end

順帶一提 CocoaPodsDemo 是我專案的名字,你要改成專案的名字

要離開的話,按ESC鍵 然後此時如果游標在最下面就輸入:wq

你就會發現你專案資料夾多一個Podfile檔案,你可以滑鼠右鍵選擇開啟方式>記事本

再自已輸入要的指令就好了(終端機的輸入真的很難用,一直跳不出去)


到這邊,你已經完成指令檔了

接著輸入

pod install

會開始安裝指令檔的第三方庫,下方指令是更新,如果install失敗,先update,再install看看

pod update

到些你的專案下面應該會有Pod資料夾,有你要的東西了

未來開啟專案請開

CocoaPodsDemo.xcworkspace

而不是舊有的

CocoaPodsDemo.xcodeproj

就可以了



2016年7月25日 星期一

Mac 終端機學習

上方選單>[finder]>前往>工具程式>終端機

1.
顯示目前所在資料夾

輸入
pwd

2.
顯示檔案列表

輸入
ls

3.
移動目前所在資料夾位置
cd [資料夾名稱]

cd Documents

pwd

4.
回首頁

cd ~

5.
回上一頁
cd ..

6.
到資料夾也可以輸入路徑
cd ~/Documents

2016年5月6日 星期五

事件用字串來呼叫


#include <objc/message.h>

- (IBAction)buttonevent:(id)sender {

NSDictionary *itemDic = [[NSDictionary alloc]init];

  SEL s = NSSelectorFromString(@"eventname:");
        if ([self respondsToSelector:s]) {
            ((id (*)(id, SEL, NSDictionary*))objc_msgSend)(self, s, itemDic);
        }

}

- (void) eventname:(id)obj
{
    //do something...
}

nsarray有包含字串

 NSArray *ar=@[@"john",@"bally",@"bill"];
 NSString *check=@"john";
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", ar];

    BOOL result = [predicate evaluateWithObject:check];

2016年4月14日 星期四

IE11 在win10開啟的錯誤

裝了win10,但要試著開啟ie總是錯誤

試了很多方法,連重設都放了,最後找到解法了

在網際網路>進階>設定找尋為加強的受保護模式啟用64位元處理程序打勾

就可以正常開啟ie了


ref→http://answers.microsoft.com/zh-hant/ie/forum/ie11-iewindows8_1/internet-explorer-11/76b30f71-11db-4198-8a11-f9a1152ea62f?auth=1

2016年4月8日 星期五

webview scales frame

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    webView.scalesPageToFit = YES;
    webView.contentMode = UIViewContentModeScaleAspectFit;
    webView.scrollView.scrollEnabled = NO;
    
    CGSize contentSize = webView.scrollView.contentSize;
    CGSize viewSize = webView.bounds.size;
    
    float rw = viewSize.width / contentSize.width;

    webView.scrollView.minimumZoomScale = rw;
    webView.scrollView.maximumZoomScale = rw;
    webView.scrollView.zoomScale = rw;
    


}

2016年2月23日 星期二

post image


NSData *imageData = UIImageJPEGRepresentation(self.image.image,0);
NSString *url=@"http://test/postimage";

 NSURL *theURL = [NSURL URLWithString:url];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:8.0f];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [theRequest setValue:@"image/jpg" forHTTPHeaderField:@"Content-Type"];
    theRequest.timeoutInterval=10.0;
    [theRequest setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[imageData length]] forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPBody: imageData];
    
    NSString *result= [self HttpResult:theRequest];
    

字串只留下數字,或只留下文字

using System.Text.RegularExpressions;

string  inputStr = "abc123";

 var outputNum = Regex.Replace( inputStr, @"[\D-]", string.Empty); //只有數字被保留

 var outputStr = Regex.Replace( inputStr, @"[\d-]", string.Empty); //只有文字被保留

2016年2月2日 星期二

UIButton Title



UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

放置 set the button title by state


[rightButton setTitle:cid forState:UIControlStateNormal];

取得 get the button title by state


[rightButton titleForState: UIControlStateNormal]


狀態 state can change you want

 UIControlStateNormal       //正常
 UIControlStateHighlighted  
 UIControlStateDisabled    //無作用狀態
 UIControlStateSelected
 UIControlStateFocused 
 UIControlStateApplication  
 UIControlStateReserved