[iOS] 上架App到Apple去review前會遇到的一些問題-- 使用 XCode Organizer 來遞交App到Store

聽從一些前輩的建議,決定還是把已經寫到一半卻累到半死的iOS App來上架 這裡記錄一下上架之前會遇到的一些問題:  首先要先連到 iTune Connect 去新增一個App(當然你需要開發者帳號,也就是付每年$99的費用) 詳細流程參考: http://www.minwt.com/ios/4726.html  關於新增資料上面有一些翻譯可以參考: http://www.csdtn.net/article/2011-01-07/289703 資料都新增完了,就會使用Application Loader 去上傳你寫好的App,不過這裡我發生幾次錯誤,分享給大家.  _NSSetlogCstringFunction error on Application loader 一開始我以為是NSLog的原因,不過主要的原因是因為跑到debug版本 記得到 [Product] —> [Edit Schema] —> Change run to release. 正確的包裝app方法為: device —> iOS device [Product] —> [Archive] Provisioning missing  iOS Apps must contain a provisioning profile in a file named embedded.mobileprovision. Provisioning bundle identifier not match 這三個問題出現的原因其實都一樣,一般而言讓App上架的方式有兩種: 透過Application Loading,然後自己把App包裝起來以後上傳到iTune Connect 透過Xcode Organizer 來做validate 與 上傳…  這也是我推薦的方式,因為比較容易看清楚所有的問題所在. 接下來我會把我上傳的流程寫清楚(原諒都是文字,放圖實在有點懶) 參考: http://stackoverflow.com/questions/5313537/bundle-identifier-and-provisioning-profile http://lamb-mei.com/10/ios-ios-provisioning-portal-certificates/ http://kenobiluh.blogspot.tw/2012/02/certificate-provisioning-file-code.html 使用 XCode Organizer 來遞交App到Store 詳細方式如下: 先到 Xcode 裏面Project Property —> [General] —> 把 Bundle Identifier 抄下來.記得把[team] 也先選擇到你的開發者帳號 ex: com.XXX.youAppName 到 iTune Connect 新增App申請,詳細流程可以參考這裡.注意 Bundle ID要跟XCode裡面的相同(就算寫錯了~可以之後修改) 到Apple iOS Developer 網站的相關處理: [Certificates, Identifiers & Profiles] —>[Identifiers]—> 新增一個 iOS App ID 記得這裡Bundle Identifier 要跟你Xcode設定裡面一樣 ex: com.XXX.youAppName [Certificates, Identifiers & Profiles] —> [Provisioning Profiles] —> 新增一個[Distribution]的 Provisioning 這裡的App ID要使用剛剛申請的,這裡最好是一對一的mapping 比較不會有問題. 下載 Provisioning 並且點兩下安裝 到Xcode 準備打包上傳 先到Project Property —>[Build Setting] 搜尋 [PROVISIONING PROFILE] —> 將它改成你剛剛下載的Provisioning 把device 從模擬器或是手機切換到 [iOS Device] [Product] —> [Archive] 如還是有出現問題請參照以上得問題解答 這時候就可以做App Validation 跟 Distribute ...
繼續閱讀

[iOS] 關於時間NSDate的相關處理

昨天把NSDate的一些處理稍微研究了一下,有一些處理方式可以整理一下: 1. 比較時間 (NSDate comparison)  <code style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;font-family:Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;white-space:inherit;"><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#00008b;" class="kwd">if</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">([</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pln">date1 compare</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">:</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pln">date2</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">]</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">==</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#2b91af;" class="typ">NSOrderedDescending</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">)<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">{<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#2b91af;" class="typ"> NSLog</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">(@</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#800000;" class="str">"date1 is later than date2"</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">);<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">}<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#00008b;" class="kwd">else</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#00008b;" class="kwd">if</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">([</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pln">date1 compare</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">:</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pln">date2</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">]</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">==</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#2b91af;" class="typ">NSOrderedAscending</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">)<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">{<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#2b91af;" class="typ"> NSLog</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">(@</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#800000;" class="str">"date1 is earlier than date2"</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">);<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">}<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#00008b;" class="kwd">else</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">{<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#2b91af;" class="typ"> NSLog</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">(@</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;color:#800000;" class="str">"dates are the same"</span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">);<br></br></span><span style="margin:0;padding:0;border:0;font-size:13.63636302948px;vertical-align:baseline;background-color:transparent;" class="pun">}</span></code> 可以拿來比較時間的先後,在NSDate大概算是最方便的. 參考: http://stackoverflow.com/questions/5965044/how-to-compare-two-nsdates-which-is-more-recent ** ** 2. 時區的轉換 使用NSDate拿來的時間都是GMT要顯示的時候得轉成當地時區(台灣是TST) -(NSString) transferGMT2TST: (NSDate)inGMT :(NSString*) newTZ {     NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];     dateFormatter.dateFormat = @”yyyy-MM-dd’T’HH:mm”;          NSTimeZone *nTZ = [NSTimeZonetimeZoneWithAbbreviation:newTZ];  ...
繼續閱讀

[iOS] 關於一些網路上SDK的學習整理心得

整理一下最近的關於iOS一些SDK學習心得 FGallery (https://github.com/gdavis/FGallery-iPhone) 自從換掉Three20與 Nimbus 之後,相簿處理的部分就換到這個SDK.其實不錯用只是對於新版本iOS相容性差了點. 優點: 其實整合相當的方便,而且完整相簿得捲動支援(Album scroll view) 缺點: iOS7 之後,完全一整個不穩定,Git上面也一堆使用者反應.不過作者看起來不maintain 了. 替代方案: iOS7之後可能還是換成iOS 預設提供的 UICollectionView功能相當的強大,不僅僅可以作為捲動處理,以後要做為更多的功能我想也不是問題. WWDC 介紹影片: https://developer.apple.com/devcenter/download.action?path=/videos/wwdc_2012__hd/session_219__advanced_collection_views_and_building_custom_layouts.mov 參考介紹文章: http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12 Nimbus (https://github.com/jverkoey/nimbus) 這個就不詳細介紹了,提供大部分所有app會使用到的相關功能.原開發就是知名的Facebok UI SDK Three20. 最近忽然開始積極更新版本,很久沒繼續使用了.看來會找時間用用看從頭來兜出一個App MagicalRecord (https://github.com/magicalpanda/MagicalRecord) 這個SDK主要是幫助你處理關於資料的相關處理.CoreData功能很強大,但是一開始的設置跟相關的處理卻相當的麻煩. 而這個不僅僅可以幫助你快速使用CoreData 而不用去管令人討厭的NSManagedObjectContext, NSManagedObjectModel, NSPersistentStoreCoordinator還可以操控不只是CoreData, Plist都可以使用. 如何加入: 把所有檔案加入專案 把這段加到 .pch   #import “CoreData+MagicalRecord.h” * 建立CoreData資料庫 * AppDelegate 加入   [MagicalRecordsetupCoreDataStackWithStoreNamed:@"CoreData.sqlite”]; * 搞定 * 詳細流程參考[這篇文章](http://www.cnblogs.com/mybkn/p/3328183.html) Inappsettingskit (http://www.inappsettingskit.com/) 設定App的設定通常都是使用Settings Bundle (參考: 這裡).如果要在app裡面更改設定就得自己都出整個頁面與設定控制,這個SDK可以快速的幫助你建制起來. 流程也簡單到不行: 把InAppSettingsKit資料夾加入你的專案 IASKAppSettingsViewController *IASKAppSettingView;  if(IASKAppSettingView == nil)     {         IASKAppSettingView = [[IASKAppSettingsViewControlleralloc] init];         IASKAppSettingView.delegate = self;     }     UINavigationController *aNavController = [[UINavigationControlleralloc] initWithRootViewController:IASKAppSettingView];     //[viewController setShowCreditsFooter:NO];   // Uncomment to not display InAppSettingsKit credits for creators.     // But we encourage you not to uncomment. Thank you!     IASKAppSettingView.showDoneButton = YES;     [self  presentViewController:aNavController animated:YEScompletion:nil];     //   [self SwitchPage:PAGE_SETTING]; * 中文的介紹文章: [在這裏](http://blog.csdn.net/artwebs/article/details/8295937)  我是參考這篇文章去找出相關的SDK,把這些SDK都玩過一次之後,又想去翻動我的程式了.一直改來改去~感覺很難上架了~~
繼續閱讀

[WindowsStore] 兩個產品共用同一份程式碼 (Shared source code with different store app with different name)

起因: 主要是因為在Windows Store 上面,需要產生兩個相同的內容的產品 但是版號與產品名稱卻不能相同. 做法: 原本做法 複製一個相同的目錄 (原本稱為ㄓ ProjA 複製出來為 ProjB) 修改 csproj 把每個檔案的鏈結改到原本的 檔案 在搬移的過程中,會出現以下的錯誤 Could not find **.xbf in target folder 查詢過後發現,XAML 的檔案無法去link具有上一層目錄的檔案架構 ( ….XXX) 但是卻可以去link “XXX “ 解決方法: 僅僅複製把ProjB 的需要的檔案到ProjA的目錄下 AssemblyInfo.cs (注意要改名) XXX.csproj XXX_StoreKey.pfx XXX_TemporaryKey.pfx Package_StoreAssociation.xml (注意要改名) Package.appxmanifest(注意要改名) 這樣下來是有點醜,因為 bin/obj 會共用~這個之後會再仔細觀察是否有任何問題 此外需要改兩個東西 在 csproj 裡面 在 Package.appxmanifest與Package_StoreAssociation.xml 內 這樣就可以產生兩個一樣內容的app 在你的桌面 參考: http://stackoverflow.com/questions/8162179/how-do-i-install-two-versions-of-my-metro-app
繼續閱讀

[VS2013][CI] 關於command line tool MSBuild.exe的筆記..

  這一些主要是為了想學習架設  Jenkins,不過還沒整理完~先把這部分的整理出來…. [問題] 利用command line 的 MSBuild.exe 會發生錯誤 “error MSB8020: The builds tools for v120 (Platform Toolset = ‘v120’) cannot be found.” 我也發現~就算你裝了 VS2013只要你有裝 VS2012 tool set你有可能會按倒 VS2012 command line tool,這時候的版本會出現   msbuild.exe /version 4.0.30319… 解法: 首先要確認你執行是VS2013 command line tool或是執行 msbuild.exe 在  c:Program Fies(X86)MSBuild12.0Bin 參考: http://public.kitware.com/Bug/view.php?id=14369 [問題]MSBuild去開始跑 *.sln 會出現 error MSB3779: The processor architecture of project being build “Any CPU” is not supported by referenced SDK …. 這個問題主要是因為在sln 裡面的設定 有加入當初建立project (專案)的時候的設定 Any CPU, Mixed Platform … etc. 所以解法有以下的方式: 解法:  [Build]->[Configuration Manager…] 去把沒需要build的platform 關閉,記得 “Build” 跟 “Deploy” 都要關閉.當然你真的都用不到~其實可以刪除…   參考:  http://stackoverflow.com/questions/1074654/how-do-i-force-msbuild-to-compile-for-32-bit-mode http://stackoverflow.com/questions/3155492/how-to-specify-platform-for-msbuild
繼續閱讀

[Android] 關於相機程式的學習整理(1)

這裡整理了一些關於在Android寫相機App會產生的一些疑問,並且把自己寫好的程式整理出來放在Github上面. 這裡產生的相機功能主要如下: 利用 Camera class產生相機的控制部分 預覽的視窗 拍照後可以讓Android系統預設的相簿觀看  讓相機產生preview 1.將需要授權的相關部分放在”AndroidManifest.xml” <uses-permissionandroid:name=”android.permission.CAMERA”/> <uses-featureandroid:name=”android.hardware.camera.autofocus”/> <uses-featureandroid:name=”android.hardware.camera”android:required=”false”/> <uses-permissionandroid:name=”android.permission.WRITE_EXTERNAL_STORAGE”/> 把需要的元件畫出來,需要一個SurfaceView跟一個Button,修改reslayoutactivity_main.xml     <SurfaceView         android:id=”@+id/surfaceView1”         android:layout_width=”fill_parent”         android:layout_height=”fill_parent”         android:layout_alignParentBottom=”true”         android:layout_alignParentLeft=”true”         android:layout_alignParentRight=”true”>     </SurfaceView>       <Button         android:id=”@+id/btn_capture”         android:layout_width=”wrap_content”         android:layout_height=”wrap_content”         android:layout_alignRight=”@+id/surfaceView1”         android:layout_below=”@+id/textView1”         android:layout_marginRight=”18dp”         android:layout_marginTop=”144dp”         android:text=”Capture”/> 讓preview可以動作,這裡的code比較多,儘量寫清楚點 3.1 建立 相關原件 //Camera object Camera mCamera; //Preview surface SurfaceView surfaceView; //Preview surface handle for callback SurfaceHolder surfaceHolder; //Camera button Button btnCapture; //Note if preview windows is on. booleanpreviewing; 3.2 連接原件修改原來的 OnCreate @Override   protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);     btnCapture = (Button) findViewById(R.id.btn_capture);     surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);  ...
繼續閱讀