Skip to content
This repository
Newer
Older
100755 307 lines (247 sloc) 9.883 kb
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
1 //
2 // MKSKProduct.m
da4affc1 »
2012-09-17 Added support for hosted content
3 // MKStoreKit (Version 5.0)
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
4 //
da4affc1 »
2012-09-17 Added support for hosted content
5 // Created by Mugunth Kumar (@mugunthkumar) on 04/07/11.
6 // Copyright (C) 2011-2020 by Steinlogic Consulting And Training Pte Ltd.
7
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
14 //
da4affc1 »
2012-09-17 Added support for hosted content
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
17 //
da4affc1 »
2012-09-17 Added support for hosted content
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 // THE SOFTWARE.
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
25
26 // As a side note on using this code, you might consider giving some credit to me by
da4affc1 »
2012-09-17 Added support for hosted content
27 // 1) linking my website from your app's website
28 // 2) or crediting me inside the app's credits page
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
29 // 3) or a tweet mentioning @mugunthkumar
30 // 4) A paypal donation to mugunth.kumar@gmail.com
31
32 #import "MKSKProduct.h"
14b9a53b »
2012-09-17 Fixed iCloud bug
33
3a3667da »
2012-11-20 Renamed category to avoid conflict
34 #import "NSData+MKBase64.h"
14b9a53b »
2012-09-17 Fixed iCloud bug
35
d7240c74 »
2012-04-18 ARC Error flag added
36 #if ! __has_feature(objc_arc)
28d483e9 »
2012-05-11 Sending receipt data is now possible
37 #error MKStoreKit is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
d7240c74 »
2012-04-18 ARC Error flag added
38 #endif
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
39
da4affc1 »
2012-09-17 Added support for hosted content
40 #ifndef __IPHONE_5_0
41 #error "MKStoreKit uses features (NSJSONSerialization) only available in iOS SDK and later."
42 #endif
43
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
44 static void (^onReviewRequestVerificationSucceeded)();
45 static void (^onReviewRequestVerificationFailed)();
46 static NSURLConnection *sConnection;
47 static NSMutableData *sDataFromConnection;
48
49 @implementation MKSKProduct
50
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
51 +(NSString*) deviceId {
1c8700b5 »
2012-03-28 Fixed ARC warnings
52
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
53 #if TARGET_OS_IPHONE
1c8700b5 »
2012-03-28 Fixed ARC warnings
54 NSString *uniqueID;
55 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
56 id uuid = [defaults objectForKey:@"uniqueID"];
57 if (uuid)
58 uniqueID = (NSString *)uuid;
59 else {
7d2e94b7 »
2012-03-28 Leak fixes
60 CFUUIDRef cfUuid = CFUUIDCreate(NULL);
504433cb »
2012-03-28 Fixed compilation issue on iOS target
61 CFStringRef cfUuidString = CFUUIDCreateString(NULL, cfUuid);
1c8700b5 »
2012-03-28 Fixed ARC warnings
62 CFRelease(cfUuid);
504433cb »
2012-03-28 Fixed compilation issue on iOS target
63 uniqueID = (__bridge NSString *)cfUuidString;
1c8700b5 »
2012-03-28 Fixed ARC warnings
64 [defaults setObject:uniqueID forKey:@"uniqueID"];
d254aa43 »
2012-04-18 Fixed a memory issue
65 CFRelease(cfUuidString);
1c8700b5 »
2012-03-28 Fixed ARC warnings
66 }
67
68 return uniqueID;
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
69 #elif TARGET_OS_MAC
1c8700b5 »
2012-03-28 Fixed ARC warnings
70
71 kern_return_t kernResult;
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
72 mach_port_t master_port;
73 CFMutableDictionaryRef matchingDict;
74 io_iterator_t iterator;
75 io_object_t service;
76 CFDataRef macAddress = nil;
1c8700b5 »
2012-03-28 Fixed ARC warnings
77
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
78 kernResult = IOMasterPort(MACH_PORT_NULL, &master_port);
79 if (kernResult != KERN_SUCCESS) {
80 printf("IOMasterPort returned %d\n", kernResult);
81 return nil;
82 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
83
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
84 matchingDict = IOBSDNameMatching(master_port, 0, "en0");
85 if(!matchingDict) {
86 printf("IOBSDNameMatching returned empty dictionary\n");
87 return nil;
88 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
89
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
90 kernResult = IOServiceGetMatchingServices(master_port, matchingDict, &iterator);
91 if (kernResult != KERN_SUCCESS) {
92 printf("IOServiceGetMatchingServices returned %d\n", kernResult);
93 return nil;
94 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
95
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
96 while((service = IOIteratorNext(iterator)) != 0)
97 {
98 io_object_t parentService;
1c8700b5 »
2012-03-28 Fixed ARC warnings
99
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
100 kernResult = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parentService);
101 if(kernResult == KERN_SUCCESS)
102 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
103 if(macAddress)
104 CFRelease(macAddress);
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
105 macAddress = IORegistryEntryCreateCFProperty(parentService, CFSTR("IOMACAddress"), kCFAllocatorDefault, 0);
106 IOObjectRelease(parentService);
107 }
108 else {
109 printf("IORegistryEntryGetParentEntry returned %d\n", kernResult);
110 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
111
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
112 IOObjectRelease(service);
113 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
114
22347ae0 »
2011-12-07 Mac Compatibility warning fixed, receipt validation pending
115 return [[NSString alloc] initWithData:(__bridge NSData*) macAddress encoding:NSASCIIStringEncoding];
116 #endif
117 }
118
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
119 -(id) initWithProductId:(NSString*) aProductId receiptData:(NSData*) aReceipt
120 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
121 if((self = [super init]))
122 {
123 self.productId = aProductId;
124 self.receipt = aReceipt;
125 }
126 return self;
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
127 }
128
129 #pragma mark -
130 #pragma mark In-App purchases promo codes support
131 // This function is only used if you want to enable in-app purchases for free for reviewers
132 // Read my blog post http://mk.sg/31
133
134 +(void) verifyProductForReviewAccess:(NSString*) productId
135 onComplete:(void (^)(NSNumber*)) completionBlock
136 onError:(void (^)(NSError*)) errorBlock
137 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
138 if(REVIEW_ALLOWED)
139 {
140 onReviewRequestVerificationSucceeded = [completionBlock copy];
141 onReviewRequestVerificationFailed = [errorBlock copy];
142
143 NSString *uniqueID = [self deviceId];
144 // check udid and featureid with developer's server
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
145
1c8700b5 »
2012-03-28 Fixed ARC warnings
146 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", OWN_SERVER, @"featureCheck.php"]];
147
148 NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url
149 cachePolicy:NSURLRequestReloadIgnoringCacheData
150 timeoutInterval:60];
151
152 [theRequest setHTTPMethod:@"POST"];
153 [theRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
154
155 NSString *postData = [NSString stringWithFormat:@"productid=%@&udid=%@", productId, uniqueID];
156
157 NSString *length = [NSString stringWithFormat:@"%d", [postData length]];
158 [theRequest setValue:length forHTTPHeaderField:@"Content-Length"];
159
160 [theRequest setHTTPBody:[postData dataUsingEncoding:NSASCIIStringEncoding]];
161
162 sConnection = [NSURLConnection connectionWithRequest:theRequest delegate:self];
163 [sConnection start];
164 }
165 else
166 {
167 completionBlock([NSNumber numberWithBool:NO]);
168 }
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
169 }
170
171 - (void) verifyReceiptOnComplete:(void (^)(void)) completionBlock
172 onError:(void (^)(NSError*)) errorBlock
173 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
174 self.onReceiptVerificationSucceeded = completionBlock;
175 self.onReceiptVerificationFailed = errorBlock;
176
177 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", OWN_SERVER, @"verifyProduct.php"]];
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
178
179 NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url
1c8700b5 »
2012-03-28 Fixed ARC warnings
180 cachePolicy:NSURLRequestReloadIgnoringCacheData
181 timeoutInterval:60];
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
182
183 [theRequest setHTTPMethod:@"POST"];
184 [theRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
185
83ccb4aa » yas375
2012-09-09 encode receiptData before send it to our server
186 NSString *receiptDataString = [self.receipt base64EncodedString];
1c8700b5 »
2012-03-28 Fixed ARC warnings
187
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
188 NSString *postData = [NSString stringWithFormat:@"receiptdata=%@", receiptDataString];
189
190 NSString *length = [NSString stringWithFormat:@"%d", [postData length]];
191 [theRequest setValue:length forHTTPHeaderField:@"Content-Length"];
192
193 [theRequest setHTTPBody:[postData dataUsingEncoding:NSASCIIStringEncoding]];
194
1c8700b5 »
2012-03-28 Fixed ARC warnings
195 self.theConnection = [NSURLConnection connectionWithRequest:theRequest delegate:self];
196 [self.theConnection start];
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
197 }
198
199
200 #pragma mark -
201 #pragma mark NSURLConnection delegate
202
203 - (void)connection:(NSURLConnection *)connection
204 didReceiveResponse:(NSURLResponse *)response
205 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
206 self.dataFromConnection = [NSMutableData data];
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
207 }
208
209 - (void)connection:(NSURLConnection *)connection
210 didReceiveData:(NSData *)data
211 {
212 [self.dataFromConnection appendData:data];
213 }
214
215 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
216 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
217 NSString *responseString = [[NSString alloc] initWithData:self.dataFromConnection
218 encoding:NSASCIIStringEncoding];
b2893b72 » yas375
2012-09-09 trim server responce because it returns 'YES\n'
219 responseString = [responseString stringByTrimmingCharactersInSet:
220 [NSCharacterSet whitespaceAndNewlineCharacterSet]];
1c8700b5 »
2012-03-28 Fixed ARC warnings
221 self.dataFromConnection = nil;
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
222 if([responseString isEqualToString:@"YES"])
223 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
224 if(self.onReceiptVerificationSucceeded)
225 {
226 self.onReceiptVerificationSucceeded();
227 self.onReceiptVerificationSucceeded = nil;
228 }
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
229 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
230 else
231 {
232 if(self.onReceiptVerificationFailed)
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
233 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
234 self.onReceiptVerificationFailed(nil);
235 self.onReceiptVerificationFailed = nil;
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
236 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
237 }
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
238
1c8700b5 »
2012-03-28 Fixed ARC warnings
239
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
240 }
241
242
243 - (void)connection:(NSURLConnection *)connection
244 didFailWithError:(NSError *)error
245 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
246
247 self.dataFromConnection = nil;
248 if(self.onReceiptVerificationFailed)
249 {
250 self.onReceiptVerificationFailed(nil);
251 self.onReceiptVerificationFailed = nil;
252 }
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
253 }
254
255
256
257 + (void)connection:(NSURLConnection *)connection
258 didReceiveResponse:(NSURLResponse *)response
259 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
260 sDataFromConnection = [[NSMutableData alloc] init];
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
261 }
262
263 + (void)connection:(NSURLConnection *)connection
264 didReceiveData:(NSData *)data
265 {
266 [sDataFromConnection appendData:data];
267 }
268
269 + (void)connectionDidFinishLoading:(NSURLConnection *)connection
270 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
271 NSString *responseString = [[NSString alloc] initWithData:sDataFromConnection
272 encoding:NSASCIIStringEncoding];
b2893b72 » yas375
2012-09-09 trim server responce because it returns 'YES\n'
273 responseString = [responseString stringByTrimmingCharactersInSet:
274 [NSCharacterSet whitespaceAndNewlineCharacterSet]];
1c8700b5 »
2012-03-28 Fixed ARC warnings
275 sDataFromConnection = nil;
276
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
277 if([responseString isEqualToString:@"YES"])
278 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
279 if(onReviewRequestVerificationSucceeded)
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
280 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
281 onReviewRequestVerificationSucceeded();
282 onReviewRequestVerificationFailed = nil;
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
283 }
1c8700b5 »
2012-03-28 Fixed ARC warnings
284 }
285 else
286 {
287 if(onReviewRequestVerificationFailed)
288 onReviewRequestVerificationFailed(nil);
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
289
1c8700b5 »
2012-03-28 Fixed ARC warnings
290 onReviewRequestVerificationFailed = nil;
291 }
292
293
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
294 }
295
296 + (void)connection:(NSURLConnection *)connection
297 didFailWithError:(NSError *)error
298 {
1c8700b5 »
2012-03-28 Fixed ARC warnings
299 sDataFromConnection = nil;
300
301 if(onReviewRequestVerificationFailed)
302 {
303 onReviewRequestVerificationFailed(nil);
304 onReviewRequestVerificationFailed = nil;
305 }
7e25cdbb »
2011-07-08 Huge cleanup of Code bloat
306 }
307 @end
Something went wrong with that request. Please try again.