This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func getProducts() | |
{ | |
if SKPaymentQueue.canMakePayments() | |
{ | |
//Get the productIds of each product your created in iTunes Connect | |
var idSet : Set = ["productId1", "productId2"] | |
let request = SKProductsRequest(productIdentifiers:idSet) | |
request.delegate = self | |
request.start() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Start by conforming to the SKPaymentTransactionObserver | |
//Restore button pressed | |
@IBAction func restorePurchasesBtnPressed(sender: AnyObject) | |
{ | |
SKPaymentQueue.defaultQueue().addTransactionObserver(self) | |
SKPaymentQueue.defaultQueue().restoreCompletedTransactions() | |
} | |
//MARK: SKPaymentTransactionObserver methods |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func validateReceipt() | |
{ | |
//Get the Path to the receipt | |
var receiptUrl = NSBundle.mainBundle().appStoreReceiptURL | |
//Check if it's actually there | |
if NSFileManager.defaultManager().fileExistsAtPath(receiptUrl!.path!) | |
{ | |
//Now lets do some validating | |
self.validateReceiptAtURL(receiptUrl!) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
environment = Sandbox; | |
receipt = { | |
"adam_id" = 0; | |
"app_item_id" = 0; | |
"application_version" = 1; | |
"bundle_id" = "com.yourcompany.yourapp"; | |
"download_id" = 0; | |
"in_app" = ( | |
{ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
char *pkcs7_d_char(PKCS7 *ptr); | |
ASN1_OCTET_STRING *pkcs7_d_data(PKCS7 *ptr); | |
PKCS7_SIGNED *pkcs7_d_sign(PKCS7 *ptr); | |
PKCS7_ENVELOPE *pkcs7_d_enveloped(PKCS7 *ptr); | |
PKCS7_SIGN_ENVELOPE *pkcs7_d_signed_and_enveloped(PKCS7 *ptr); | |
PKCS7_DIGEST *pkcs7_d_digest(PKCS7 *ptr); | |
PKCS7_ENCRYPT *pkcs7_d_encrypted(PKCS7 *ptr); | |
ASN1_TYPE *pkcs7_d_other(PKCS7 *ptr); | |
char *pkcs7_d_char(PKCS7 *ptr) { return ptr->d.ptr; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Load in the receipt | |
var receipt: NSData = NSData(contentsOfURL:receiptUrl!, options: nil, error: nil)! | |
var receiptBio = BIO_new(BIO_s_mem()) | |
BIO_write(receiptBio, receipt.bytes, Int32(receipt.length)) | |
var receiptPKCS7 = d2i_PKCS7_bio(receiptBio, nil) | |
//Read in Apple's Root CA | |
var appleRoot = NSBundle.mainBundle().URLForResource("AppleIncRootCertificate", withExtension: "cer") | |
var caData = NSData(contentsOfURL: appleRoot!) | |
var caBIO = BIO_new(BIO_s_mem()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let octets = pkcs7_d_data(pkcs7_d_sign(receiptPKCS7).memory.contents) | |
var ptr = UnsafePointer<UInt8>(octets.memory.data) | |
let end = ptr.advancedBy(Int(octets.memory.length)) | |
var type: Int32 = 0 | |
var xclass: Int32 = 0 | |
var length = 0 | |
ASN1_get_object(&ptr, &length, &type, &xclass, end - ptr) | |
if (type != V_ASN1_SET) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func getProductIdFromReceipt(data:NSData) -> String? | |
{ | |
var p = UnsafePointer<UInt8>(data.bytes) | |
var dataLength = data.length | |
var type:Int32 = 0 | |
var tag:Int32 = 0 | |
var length = 0 | |
var end = p + dataLength | |
ASN1_get_object(&p, &length, &type, &tag, end - p) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Don't forget to add the Security.framework to your project. | |
import Security | |
private let kSecClassValue = NSString(format: kSecClass) | |
private let kSecAttrAccountValue = NSString(format: kSecAttrAccount) | |
private let kSecValueDataValue = NSString(format: kSecValueData) | |
private let kSecClassGenericPasswordValue = NSString(format: kSecClassGenericPassword) | |
private let kSecAttrServiceValue = NSString(format: kSecAttrService) | |
private let kSecMatchLimitValue = NSString(format: kSecMatchLimit) | |
private let kSecReturnDataValue = NSString(format: kSecReturnData) | |
private let kSecMatchLimitOneValue = NSString(format: kSecMatchLimitOne) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func load(service: NSString, userName:String) -> NSString? | |
{ | |
//Create the query keychain | |
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userName, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue]) | |
var dataTypeRef :Unmanaged<AnyObject>? | |
// Search for the keychain items | |
let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef) | |
let opaque = dataTypeRef?.toOpaque() | |
var contentsOfKeychain: NSString? |
OlderNewer