2015年7月23日 星期四

ld: framework not found iCloud

下載了一個 iOS App 的範例程式: iRareMedia/iCloudDocumentSync, 作者寫:

/** iCloud Document Sync makes it easy for developers to integrate the iCloud document storage APIs into iOS applications. This is how iCloud document-storage and management should've been out of the box from Apple. Integrate iCloud into iOS (OS X coming soon) Objective-C document projects with one-line code methods. Sync, upload, manage, and remove documents to and from iCloud with only a few lines of code (compared to the hundreds of lines and hours that it usually takes). Get iCloud up and running in your iOS app in only a few minutes. Updates and more details on this project can be found on [GitHub](http://www.github.com/iRareMedia/iCloudDocumentSync). If you like the project, please star it on GitHub!  The `iCloud` class provides methods to integrate iCloud into document projects.  Adding iCloud Document Sync to your project is easy. Follow these steps below to get everything up and running.  1. Drag the iCloud Framework into your project 2. Add `#import <iCloud/iCloud.h>` to your header file(s) iCloud Document Sync 3. Subscribe to the `<iCloudDelegate>` delegate. 4. Call the following methods to setup iCloud when your app starts:  @warning Only available on iOS 6.0 and later on apps with valid code signing and entitlements. Requires Xcode 5.0.1 and later. Check the online documentation for more information on setting up iCloud in your app. */
試了很多次, 終於解決了2個問題:

  1. Build 會失敗: ld: framework not found iCloud
  2. <iCloud/iCloud.h> not found.


問題1解法:

把 "Search Paths" - "Freamework Search Paths" 加入該 framework 實際的 path.



問題2解法:

把 iCloud.h 加入project 裡, 然後把 source code 裡的  <iCloud/iCloud.h> 改為 "iCloud.h" 就OK了.


使用心得, 這個範例似乎不太穩定, 很容易掛掉, 在 debug 模式裡, 可以看到錯誤訊息, 但不知道該如何解.


相關文章:

iCloud and UIDocument: Beyond the Basics, Part 1/4
http://www.raywenderlich.com/12779/icloud-and-uidocument-beyond-the-basics-part-1






2015年7月20日 星期一

App Transport Security policy

在 iOS9 上面開發 App, 之前可以用的連線方式不能用了. 變成一定要改用 https, 或是加入例外, error messsage:
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.

App Transport Security Technote
https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/index.html


解法: Disable App Transport Security

Add this to the Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>


See Apple’s App Transport Security Technote for full details (thanks @gnasher729).
You can add exceptions for specific domains in your Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>testdomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <false/>
            <key>NSExceptionAllowInsecureHTTPSLoads</key>
            <false/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowInsecureHTTPSLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>

        ...

    </dict>
</dict>
All the keys for each excepted domain are optional. The speaker did not elaborate on any of the keys, but I think they’re all reasonably obvious.
You can also ignore all app transport security restrictions with a single key:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

from:
http://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9



2015年7月12日 星期日

太極刷機大師

由於需要測試 iOS 9.0 上面的新功能, 所以需要升級 iPad  到 9.0 beta 版, 試了半天, 在 Mac 上不知道怎麼弄, 也找不到工具. 後來是回到 Windows 裡安裝太極刷機大師來解決, 滿簡單的, 隨便點2下就做完了.

點 "一鍵刷機".


刷好後, 就變成 iOS 9.0 了.


檔案下載:
http://www.taigpro.com/

2015年7月9日 星期四

iOS keychain mechanism to increase password protection

從某些角度來看, 透過 keychain 並不是保護密碼的好方法.

Qfile HD 1.5.0 版本的新內容
https://itunes.apple.com/tw/app/qfile-hd/id597800201?l=zh&mt=8
Starting from this version, the password of the connected profile will use the built-in iOS keychain mechanism to increase password protection.
Please re-enter the connected profile's password before connecting to a NAS.



KeyChain優點:


  • 每個組( keychain-access-groups )之間資料存取隔離,沒有權限的app無法讀取他人資料,保證資料的安全.
  • 全域性統一儲存,即使刪除app,keychain中的資料依然存在,下次重新安裝app還能存取.
  • 存儲後的資料會加密.
  • 同一個組的app可以共享keychain中的資料.


KeyChain缺點:


  • 刪除app後不會清除keychain裡的資料,如果儲存密碼等敏感性資料有一定的風險。
  • iOS 越獄後keychain能被導出來,密碼的明碼即可被看到。



實作方法:

到GitHub下載SFHFKeychainUtils第三方套件,接著匯入到專案中。


使用範例:

#import "SFHFKeychainUtils.h"
 
// 取可以識別的名字
static NSString *const RLKeychainUserName = @"HTKeychainUserName";
static NSString *const RLKeychainServiceName = @"HTKeychainServiceName";
 
#pragma mark - Key Chain Methods
// 取得密碼
+(NSString *)loginToken
{
    return [SFHFKeychainUtils getPasswordForUsername:RLKeychainUserName andServiceName:RLKeychainServiceName error:nil];
}
 
// 設定密碼
+(void)setLoginToken:(NSString *)loginToken
{
    [SFHFKeychainUtils storeUsername:RLKeychainUserName andPassword:loginToken forServiceName:RLKeychainServiceName updateExisting:YES error:nil];
}
 
// 移除密碼
+(void)removeLoginToken
{
    [SFHFKeychainUtils deleteItemForUsername:RLKeychainUserName andServiceName:RLKeychainServiceName error:nil];
}




相關網站:





2015年6月11日 星期四

NSData , NSMutableData 互相轉換

由於是接別人的 code, 我也不知道 mutable 和 immutable 的差別, 目標就是把程式改到沒有 warning. 最後還是算了, warning 是一件正常的事情, 假裝沒看到.


NSData to NSMutableData:


NSData *_data = [[NSData alloc] init];
NSMutableData *_mdata = [NSMutableData dataWithData:_data];


NSMutableData to NSData:

NSMutableData *mutData = [[NSMutableData alloc] init];
//Giving some value to mutData
NSData *immutableData = [NSData dataWithData:mutData];
上面這樣子寫, 會有 warning, 因為 muData 是 NSMutableData, NSData input要的資料是 NSData.

這篇文章, 有講直接轉和使用 object copy 的差別, 差在 lifetime,
http://stackoverflow.com/questions/6835884/is-it-okay-to-call-nsdata-datawithdata-with-an-nsmutabledata-object

This is completely okay, and is in fact one of the primary uses of dataWithData: -- to create an immutable copy of a mutable object.*
NSData also conforms to the NSCopying protocol,** which means you could instead use [mutData copy]. The difference is that dataWithData: returns an object you do not own (it is autoreleased), whereas per memory management rulescopy creates an object for whose memory you areresponsible. dataWithData: is equivalent in effect to [[mutData copy] autorelease].
So you can choose either dataWithData: or copy, dependent upon your requirements for the lifetime of the resulting object.

*This also applies to similar methods in other classes which have a mutable subclass, e.g., +[NSArray arrayWithArray:].
**See also "Object Copying" in the Core Competencies Guide.




NSData的創建:實例與class方法


  • data:創建一個不包​​含任何數據的空的NSData對象
  • dataWithBytes:length:/initWithBytes:length::複製C數組所包含的數據來初始化NSData的數據
  • dataWithBytesNoCopy:length:/initWithBytesNoCopy:length:直接利用C數組所包含的數據來初始化NSData對象。當該對像被執行malloc方法銷毀自己時,程序會釋放該C數組
  • dataWithBytesNoCopy:length:freeWhenDone:/initWithBytesNoCopy:length:freeWhenDone::直接利用C數組所包含的數據來初始化NSData對象,只有當最後一個參數為YES,且該對像被執行malloc方法銷毀自己時,程序才會釋放該C數組
  • dataWithContentsOfFile:/initWithContentsOfFile::直接讀取文件內容,並利用文件內容來初始化NSData
  • dataWithContentsOfURL:/initWithContentsOfURL::直接讀取URL關聯內容,並利用該URL關聯的內容來初始化NSData
  • dataWithData:/initWithData::直接使用另一個NSData所包含的數據來初始化新創建的NSData


訪問NSData數據內容


  • bytes:返回該NSData所包含的數據
  • getBytes:length:獲取NSData所包含的指定長度的數據
  • getBytes:range::獲取NSData所包含的指定範圍的數據
  • subdataWithRange::獲取NSData所包含的指定範圍的數據組成的NSData對象
  • writeToFile:atomically::將NSData數據寫入文件
  • writeToURL:atomically::將NSData數據寫入指定URL的資源



ex:
#import <Foundation/Foundation.h>

int main(int argc , char * argv[])
{
@autoreleasepool{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString:@"http://tw.yahoo.com"]];
NSLog(@"%ld" , [data length]);
char buffer[100];
[data getBytes:buffer range: NSMakeRange(103, 100)];
NSLog(@"%s" , buffer);
NSString* content = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"----------輸出網頁內容---------");
NSLog(@"%@" , content);
}
}



2015年6月10日 星期三

Cenerate App Icons 產生App需要的圖示

這個  Makeappicon 網站真的很棒, 完全是寫給工程師用的, 省下了很多去 resize icon 的時間.

隨手選一張圖片上傳到網頁裡.


過幾秒後, 輸入 eMail 給他, 檔案就會寄到 email 裡了. 真的很貼心, 還把我們的icon 放到 apple watch 還有iphone 裡preview.


針對 Android 的用戶, 下面這個 tab 是做假的, 寄到 email 裡的 zip 檔, 有3個 folder, 分別是給  iOS/AppleWath 和 Android.


get the current version of my ios project in code?

You can try using the infoDictionary
NSDictionary *infoDictionary = [[NSBundle mainBundle]infoDictionary];

NSString *build = infoDictionary[(NSString*)kCFBundleVersionKey];
NSString *bundleName = infoDictionary[(NSString *)kCFBundleNameKey]; 

相關文章:

How to get app's product name at runtime


Facebook 留言