xuguohong

idfa

Showing 427 changed files with 3340 additions and 4099 deletions
No preview for this file type
...@@ -466,7 +466,7 @@ ...@@ -466,7 +466,7 @@
466 isa = XCBuildConfiguration; 466 isa = XCBuildConfiguration;
467 buildSettings = { 467 buildSettings = {
468 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 468 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
469 - CODE_SIGN_IDENTITY = "iPhone Developer: luo yuanyuan (82PEUDVHS9)"; 469 + CODE_SIGN_IDENTITY = "iPhone Developer: Yufeng Wang (N5VLW9NRUG)";
470 DEAD_CODE_STRIPPING = NO; 470 DEAD_CODE_STRIPPING = NO;
471 ENABLE_BITCODE = NO; 471 ENABLE_BITCODE = NO;
472 FRAMEWORK_SEARCH_PATHS = ( 472 FRAMEWORK_SEARCH_PATHS = (
...@@ -475,19 +475,20 @@ ...@@ -475,19 +475,20 @@
475 "$(PROJECT_DIR)/poolsdk_file/poolsdk", 475 "$(PROJECT_DIR)/poolsdk_file/poolsdk",
476 ); 476 );
477 INFOPLIST_FILE = poolsdk_file/poolsdk/Info.plist; 477 INFOPLIST_FILE = poolsdk_file/poolsdk/Info.plist;
478 - IPHONEOS_DEPLOYMENT_TARGET = 7.1; 478 + IPHONEOS_DEPLOYMENT_TARGET = 8.1;
479 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 479 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
480 LIBRARY_SEARCH_PATHS = ( 480 LIBRARY_SEARCH_PATHS = (
481 "$(inherited)", 481 "$(inherited)",
482 "$(PROJECT_DIR)/Demo", 482 "$(PROJECT_DIR)/Demo",
483 "$(PROJECT_DIR)/poolsdk_file/poolsdk", 483 "$(PROJECT_DIR)/poolsdk_file/poolsdk",
484 ); 484 );
485 - ONLY_ACTIVE_ARCH = YES; 485 + ONLY_ACTIVE_ARCH = NO;
486 OTHER_LDFLAGS = ""; 486 OTHER_LDFLAGS = "";
487 PRODUCT_BUNDLE_IDENTIFIER = com.jian.wuji; 487 PRODUCT_BUNDLE_IDENTIFIER = com.jian.wuji;
488 PRODUCT_NAME = "$(TARGET_NAME)"; 488 PRODUCT_NAME = "$(TARGET_NAME)";
489 - PROVISIONING_PROFILE = ""; 489 + PROVISIONING_PROFILE = "e6d180fd-5532-4218-bf56-0c1afa8ea0b4";
490 - VALID_ARCHS = "arm64 armv7"; 490 + TARGETED_DEVICE_FAMILY = 2;
491 + VALID_ARCHS = "arm64 armv7s";
491 }; 492 };
492 name = Debug; 493 name = Debug;
493 }; 494 };
...@@ -495,7 +496,7 @@ ...@@ -495,7 +496,7 @@
495 isa = XCBuildConfiguration; 496 isa = XCBuildConfiguration;
496 buildSettings = { 497 buildSettings = {
497 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 498 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
498 - CODE_SIGN_IDENTITY = "iPhone Developer: luo yuanyuan (82PEUDVHS9)"; 499 + CODE_SIGN_IDENTITY = "iPhone Developer: Yufeng Wang (N5VLW9NRUG)";
499 DEAD_CODE_STRIPPING = NO; 500 DEAD_CODE_STRIPPING = NO;
500 ENABLE_BITCODE = NO; 501 ENABLE_BITCODE = NO;
501 FRAMEWORK_SEARCH_PATHS = ( 502 FRAMEWORK_SEARCH_PATHS = (
...@@ -504,19 +505,20 @@ ...@@ -504,19 +505,20 @@
504 "$(PROJECT_DIR)/poolsdk_file/poolsdk", 505 "$(PROJECT_DIR)/poolsdk_file/poolsdk",
505 ); 506 );
506 INFOPLIST_FILE = poolsdk_file/poolsdk/Info.plist; 507 INFOPLIST_FILE = poolsdk_file/poolsdk/Info.plist;
507 - IPHONEOS_DEPLOYMENT_TARGET = 7.1; 508 + IPHONEOS_DEPLOYMENT_TARGET = 8.1;
508 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 509 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
509 LIBRARY_SEARCH_PATHS = ( 510 LIBRARY_SEARCH_PATHS = (
510 "$(inherited)", 511 "$(inherited)",
511 "$(PROJECT_DIR)/Demo", 512 "$(PROJECT_DIR)/Demo",
512 "$(PROJECT_DIR)/poolsdk_file/poolsdk", 513 "$(PROJECT_DIR)/poolsdk_file/poolsdk",
513 ); 514 );
514 - ONLY_ACTIVE_ARCH = YES; 515 + ONLY_ACTIVE_ARCH = NO;
515 OTHER_LDFLAGS = ""; 516 OTHER_LDFLAGS = "";
516 PRODUCT_BUNDLE_IDENTIFIER = com.jian.wuji; 517 PRODUCT_BUNDLE_IDENTIFIER = com.jian.wuji;
517 PRODUCT_NAME = "$(TARGET_NAME)"; 518 PRODUCT_NAME = "$(TARGET_NAME)";
518 - PROVISIONING_PROFILE = ""; 519 + PROVISIONING_PROFILE = "e6d180fd-5532-4218-bf56-0c1afa8ea0b4";
519 - VALID_ARCHS = "arm64 armv7"; 520 + TARGETED_DEVICE_FAMILY = 2;
521 + VALID_ARCHS = "arm64 armv7s";
520 }; 522 };
521 name = Release; 523 name = Release;
522 }; 524 };
......
...@@ -37,11 +37,7 @@ ...@@ -37,11 +37,7 @@
37 [[PoolSdk shareSDK]applicationDidEnterBackground:application]; 37 [[PoolSdk shareSDK]applicationDidEnterBackground:application];
38 } 38 }
39 39
40 -- (void)applicationWillEnterForeground:(UIApplication *)application { 40 +
41 - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
42 - NSLog(@"applicationWillEnterForeground1111111");
43 - [[PoolSdk shareSDK] applicationWillEnterForeground:application];
44 -}
45 41
46 - (void)applicationDidBecomeActive:(UIApplication *)application { 42 - (void)applicationDidBecomeActive:(UIApplication *)application {
47 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
...@@ -58,10 +54,22 @@ ...@@ -58,10 +54,22 @@
58 return true; 54 return true;
59 } 55 }
60 56
57 +-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
58 +{
59 + [[PoolSdk shareSDK]application:app openURL:url options:options];
60 + return YES;
61 +}
62 +
61 -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 63 -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
62 { 64 {
63 [[PoolSdk shareSDK] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; 65 [[PoolSdk shareSDK] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
64 return YES; 66 return YES;
65 } 67 }
66 68
69 +- (void)applicationWillEnterForeground:(UIApplication *)application {
70 + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
71 + [[PoolSdk shareSDK] applicationWillEnterForeground:application];
72 +}
73 +
74 +
67 @end 75 @end
......
...@@ -154,4 +154,36 @@ ...@@ -154,4 +154,36 @@
154 } 154 }
155 } 155 }
156 156
157 +
158 +
159 +#pragma mark - 截屏
160 +- (void)screenShot:(UIView *)view{
161 + UIImage* image = nil;
162 + UIGraphicsBeginImageContext(view.bounds.size);
163 + [view.layer renderInContext:UIGraphicsGetCurrentContext()];
164 + image = UIGraphicsGetImageFromCurrentImageContext();
165 + UIGraphicsEndImageContext();
166 + UIGraphicsEndImageContext();
167 + if (image != nil) {
168 + NSLog(@"截图成功!");
169 + UIImageWriteToSavedPhotosAlbum(image,self,@selector(image:didFinishSavingWithError:contextInfo:),NULL);
170 +
171 + }
172 +}
173 +
174 +
175 +#pragma mark - 保存到相册
176 +-(void)image:(UIImage *)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo
177 +{
178 + if(!error){
179 + NSLog(@"存到相册");
180 + }else{
181 + NSLog(@"存储失败");
182 +
183 + }
184 +}
185 +
186 +
187 +
188 +
157 @end 189 @end
......
No preview for this file type
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 9
10 #include "UnionInterface.h" 10 #include "UnionInterface.h"
11 #import <SafariServices/SafariServices.h> 11 #import <SafariServices/SafariServices.h>
12 -@interface Interface : NSObject <UnionInterface,SFSafariViewControllerDelegate> 12 +@interface Interface : NSObject <UnionInterface>
13 @property(nonatomic, strong)UIViewController *controller; 13 @property(nonatomic, strong)UIViewController *controller;
14 14
15 15
......
...@@ -29,5 +29,7 @@ ...@@ -29,5 +29,7 @@
29 29
30 - (void)httpPostAsyncOpen:(NSString*)postUrl :(NSDictionary*)postDict; 30 - (void)httpPostAsyncOpen:(NSString*)postUrl :(NSDictionary*)postDict;
31 31
32 -- (NSString *)dicToString:(NSDictionary *) dict; 32 +-(void)httpGetAsync:(NSString *)url completionHandler:(void (^ __nullable)(NSURLResponse* __nullable response, NSData* __nullable data, NSError* __nullable connectionError)) handler;
33 +
34 +- (NSString * __nullable)dicToString:(NSDictionary * __nullable) dict;
33 @end 35 @end
......
...@@ -30,7 +30,10 @@ ...@@ -30,7 +30,10 @@
30 30
31 @property(nonatomic, strong)NSString *openId; 31 @property(nonatomic, strong)NSString *openId;
32 32
33 -#define REPORT_URL @"https://statistic.public.sdk.gzyouai.com/sdk/statistic" //@http://public.sdk.gzyouai.com:9030/sdk/statistic"//@"http://10.200.201.230:9001/sdk/statistic"//@"https://statistic.public.sdk.gzyouai.com/sdk/statistic"// 33 +#define REPORT_URL @"https://statistic.public.sdk.gzyouai.com/sdk/statistic" //http://183.57.76.181:9030/sdk/statistic
34 +
35 +#define REPORT_IDFA_URL @"https://statistic.public.sdk.gzyouai.com/sdk/last_channel?idfa=" //@"http://183.57.76.181:9030/sdk/last_channel?idfa="//
36 +
34 #define REPORT_OPEN @"open" 37 #define REPORT_OPEN @"open"
35 #define REPORT_ENTER @"enter" 38 #define REPORT_ENTER @"enter"
36 #define REPORT_CREATEROLE @"createrole" 39 #define REPORT_CREATEROLE @"createrole"
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
36 36
37 -(void)viewDidAppear; 37 -(void)viewDidAppear;
38 38
39 +- (void)setViewController:(UIViewController *)viewController;
40 +
39 /** 41 /**
40 登录SDK 42 登录SDK
41 */ 43 */
...@@ -185,6 +187,8 @@ ...@@ -185,6 +187,8 @@
185 187
186 - (void)applicationWillResignActive:(UIApplication *)application; 188 - (void)applicationWillResignActive:(UIApplication *)application;
187 189
190 +-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options;
191 +
188 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; 192 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
189 193
190 @end 194 @end
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
19 19
20 - (void)SDKinit:(UIViewController *) control; 20 - (void)SDKinit:(UIViewController *) control;
21 21
22 +
23 +- (void)setViewController:(UIViewController *) viewController;
24 +
22 /** 25 /**
23 登录SDK 26 登录SDK
24 */ 27 */
...@@ -123,5 +126,7 @@ ...@@ -123,5 +126,7 @@
123 126
124 - (void)applicationWillResignActive:(UIApplication *)application; 127 - (void)applicationWillResignActive:(UIApplication *)application;
125 128
129 +-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options;
130 +
126 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; 131 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
127 @end 132 @end
...\ No newline at end of file ...\ No newline at end of file
......
1 +import shutil
2 +import os
3 +import plistlib
4 +
5 +import config
6 +import json
7 +import packageProj
8 +
9 +from mod_pbxproj import XcodeProject
10 +
11 +
12 +gameProjName = config.gameProjName
13 +channelName = "bingxue"
14 +#copy dir xcodeproj
15 +copyNewDirName = gameProjName + '_' + channelName + '.xcodeproj'
16 +currentPath = os.path.abspath('.')
17 +currentPath += '/' + copyNewDirName
18 +
19 +
20 +if os.path.exists(currentPath):
21 + shutil.rmtree(currentPath)
22 +
23 +shutil.copytree(gameProjName + '.xcodeproj',currentPath)
24 +
25 +project = XcodeProject.Load(copyNewDirName + '/project.pbxproj')
26 +
27 +project.add_other_ldflags('-ObjC')
28 +#frameworks = project.add_folder('poolsdk_file/poolsdk_itools')
29 +#print(frameworks);
30 +#add search path
31 +
32 +channelRootPath = config.channelRootPath#'poolsdk_file'
33 +
34 +frameworksPath = '$(PROJECT_DIR)/' + channelRootPath + '/poolsdk_' + channelName + '/SDK'
35 +print(frameworksPath);
36 +#add header search path
37 +project.add_header_search_paths(frameworksPath, recursive=False)
38 +#add framework search path
39 +project.add_framework_search_paths(frameworksPath, recursive=False)
40 +#add library search path
41 +project.add_library_search_paths(frameworksPath, recursive=False)
42 +
43 +#add poolsdk_xy dir all file into project
44 +project.remove_group_by_name('poolsdk')
45 +frameworkRelativePath = project.add_folder(channelRootPath + '/poolsdk_' + channelName + '/SDK')
46 +#add sdk lib framework
47 +#project.add_file_if_doesnt_exist('XYPlatform.framework',parent=frameworkRelativePath, weak=True)
48 +#project.add_file_if_doesnt_exist('XYPlatformResources.bundle',parent=frameworkRelativePath, weak=True)
49 +
50 +#remove demo file and replace sdk file
51 +#project.remove_file_by_path('poolsdk_file/Demo')
52 +#project.remove_group_by_name('poolsdk_file')
53 +#project.add_file_if_doesnt_exist('PoolSdk.h',parent=frameworkRelativePath, weak=True)
54 +#project.add_file_if_doesnt_exist('PoolSdk.m',parent=frameworkRelativePath, weak=True)
55 +#project.add_file_if_doesnt_exist('SDKInterface.h',parent=frameworkRelativePath, weak=True)
56 +#project.add_file_if_doesnt_exist('SDKInterface.m',parent=frameworkRelativePath, weak=True)
57 +#ignore_unknown_type
58 +project.add_file_if_doesnt_exist('pool_setting',parent=frameworkRelativePath, weak=True,ignore_unknown_type=True)
59 +
60 +
61 +systemFrameworks = project.get_or_create_group('Frameworks')
62 +#add system framework
63 +project.add_file_if_doesnt_exist('System/Library/Frameworks/CoreTelephony.framework',parent=systemFrameworks, weak=True, tree='SDKROOT')
64 +project.add_file_if_doesnt_exist('System/Library/Frameworks/SystemConfiguration.framework',parent=systemFrameworks, weak=True, tree='SDKROOT')
65 +
66 +
67 +#add system dylib
68 +systemLibs = project.get_or_create_group('Libraries')
69 +project.add_file_if_doesnt_exist('/usr/lib/libsqlite3.dylib',parent=systemLibs, weak=True, tree='<absolute>')#absolute path
70 +
71 +#modify info.plist reference path
72 +project.add_single_valued_flag('INFOPLIST_FILE',channelRootPath + '/poolsdk_' + channelName + '/Info.plist')
73 +
74 +project.add_single_valued_flag('ENABLE_BITCODE', 'NO')
75 +
76 +readInfoPlistFilePath = channelRootPath + '/poolsdk/Info.plist'
77 +writeInfoFilePath = channelRootPath + '/poolsdk_' + channelName + '/Info.plist'
78 +infoContent = plistlib.readPlist(readInfoPlistFilePath)
79 +
80 +xyInfoPath = channelRootPath + '/poolsdk_' + channelName + '/Info_' + channelName + '.plist'
81 +xyInfoContent = plistlib.readPlist(xyInfoPath)
82 +
83 +#read pool_setting file
84 +settingFile = open(channelRootPath + '/poolsdk_' + channelName + '/SDK/pool_setting','rw')
85 +try:
86 + settingFileContent = settingFile.read( )
87 +finally:
88 + settingFile.close( )
89 +#json op
90 +jsonStr = json.loads(settingFileContent)
91 +
92 +#modify bundle id
93 +project.add_single_valued_flag('PRODUCT_BUNDLE_IDENTIFIER',jsonStr["appScheme"])
94 +
95 +#update and add info.plist content
96 +infoContent.update(xyInfoContent)
97 +#write
98 +plistlib.writePlist(infoContent,writeInfoFilePath)
99 +
100 +project.save()
101 +
102 +
103 +packageProj.buildProjName = gameProjName + '_' + channelName
104 +packageProj.targetName = gameProjName
105 +packageProj.buildProj()
1 +channelRootPath = "poolsdk_file"
2 +gameProjName = 'Demo'
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 +# Copyright 2012 Calvin Rien
2 +#
3 +# Licensed under the Apache License, Version 2.0 (the "License");
4 +# you may not use this file except in compliance with the License.
5 +# You may obtain a copy of the License at
6 +#
7 +# http://www.apache.org/licenses/LICENSE-2.0
8 +#
9 +# Unless required by applicable law or agreed to in writing, software
10 +# distributed under the License is distributed on an "AS IS" BASIS,
11 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 +# See the License for the specific language governing permissions and
13 +# limitations under the License.
14 +
15 +# A pbxproj file is an OpenStep format plist
16 +# {} represents dictionary of key=value pairs delimited by ;
17 +# () represents list of values delimited by ,
18 +# file starts with a comment specifying the character type
19 +# // !$*UTF8*$!
20 +
21 +# when adding a file to a project, create the PBXFileReference
22 +# add the PBXFileReference's guid to a group
23 +# create a PBXBuildFile with the PBXFileReference's guid
24 +# add the PBXBuildFile to the appropriate build phase
25 +
26 +# when adding a header search path add
27 +# HEADER_SEARCH_PATHS = "path/**";
28 +# to each XCBuildConfiguration object
29 +
30 +# Xcode4 will read either a OpenStep or XML plist.
31 +# this script uses `plutil` to validate, read and write
32 +# the pbxproj file. Plutil is available in OS X 10.2 and higher
33 +# Plutil can't write OpenStep plists, so I save as XML
34 +
35 +import datetime
36 +import json
37 +import ntpath
38 +import os
39 +import plistlib
40 +import re
41 +import shutil
42 +import subprocess
43 +import uuid
44 +
45 +from UserDict import IterableUserDict
46 +from UserList import UserList
47 +
48 +regex = '[a-zA-Z0-9\\._/-]*'
49 +
50 +
51 +class PBXEncoder(json.JSONEncoder):
52 + def default(self, obj):
53 + """Tests the input object, obj, to encode as JSON."""
54 +
55 + if isinstance(obj, (PBXList, PBXDict)):
56 + return obj.data
57 +
58 + return json.JSONEncoder.default(self, obj)
59 +
60 +
61 +class PBXDict(IterableUserDict):
62 + def __init__(self, d=None):
63 + if d:
64 + d = dict([(PBXType.Convert(k), PBXType.Convert(v)) for k, v in d.items()])
65 +
66 + IterableUserDict.__init__(self, d)
67 +
68 + def __setitem__(self, key, value):
69 + IterableUserDict.__setitem__(self, PBXType.Convert(key), PBXType.Convert(value))
70 +
71 + def remove(self, key):
72 + self.data.pop(PBXType.Convert(key), None)
73 +
74 +
75 +class PBXList(UserList):
76 + def __init__(self, l=None):
77 + if isinstance(l, basestring):
78 + UserList.__init__(self)
79 + self.add(l)
80 + return
81 + elif l:
82 + l = [PBXType.Convert(v) for v in l]
83 +
84 + UserList.__init__(self, l)
85 +
86 + def add(self, value):
87 + value = PBXType.Convert(value)
88 +
89 + if value in self.data:
90 + return False
91 +
92 + self.data.append(value)
93 + return True
94 +
95 + def remove(self, value):
96 + value = PBXType.Convert(value)
97 +
98 + if value in self.data:
99 + self.data.remove(value)
100 + return True
101 + return False
102 +
103 + def __setitem__(self, key, value):
104 + UserList.__setitem__(self, PBXType.Convert(key), PBXType.Convert(value))
105 +
106 +
107 +class PBXType(PBXDict):
108 + def __init__(self, d=None):
109 + PBXDict.__init__(self, d)
110 +
111 + if 'isa' not in self:
112 + self['isa'] = self.__class__.__name__
113 + self.id = None
114 +
115 + @staticmethod
116 + def Convert(o):
117 + if isinstance(o, list):
118 + return PBXList(o)
119 + elif isinstance(o, dict):
120 + isa = o.get('isa')
121 +
122 + if not isa:
123 + return PBXDict(o)
124 +
125 + cls = globals().get(isa)
126 +
127 + if cls and issubclass(cls, PBXType):
128 + return cls(o)
129 +
130 + print 'warning: unknown PBX type: %s' % isa
131 + return PBXDict(o)
132 + else:
133 + return o
134 +
135 + @staticmethod
136 + def IsGuid(o):
137 + return re.match('^[A-F0-9]{24}$', str(o))
138 +
139 + @classmethod
140 + def GenerateId(cls):
141 + return ''.join(str(uuid.uuid4()).upper().split('-')[1:])
142 +
143 + @classmethod
144 + def Create(cls, *args, **kwargs):
145 + return cls(*args, **kwargs)
146 +
147 +
148 +class PBXFileReference(PBXType):
149 + def __init__(self, d=None):
150 + PBXType.__init__(self, d)
151 + self.build_phase = None
152 +
153 + types = {
154 + '.a': ('archive.ar', 'PBXFrameworksBuildPhase'),
155 + '.app': ('wrapper.application', None),
156 + '.s': ('sourcecode.asm', 'PBXSourcesBuildPhase'),
157 + '.c': ('sourcecode.c.c', 'PBXSourcesBuildPhase'),
158 + '.cpp': ('sourcecode.cpp.cpp', 'PBXSourcesBuildPhase'),
159 + '.framework': ('wrapper.framework', 'PBXFrameworksBuildPhase'),
160 + '.h': ('sourcecode.c.h', None),
161 + '.hpp': ('sourcecode.c.h', None),
162 + '.d': ('sourcecode.dtrace', 'PBXSourcesBuildPhase'),
163 + '.swift': ('sourcecode.swift', 'PBXSourcesBuildPhase'),
164 + '.icns': ('image.icns', 'PBXResourcesBuildPhase'),
165 + '.m': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'),
166 + '.j': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'),
167 + '.mm': ('sourcecode.cpp.objcpp', 'PBXSourcesBuildPhase'),
168 + '.nib': ('wrapper.nib', 'PBXResourcesBuildPhase'),
169 + '.plist': ('text.plist.xml', 'PBXResourcesBuildPhase'),
170 + '.json': ('text.json', 'PBXResourcesBuildPhase'),
171 + '.png': ('image.png', 'PBXResourcesBuildPhase'),
172 + '.rtf': ('text.rtf', 'PBXResourcesBuildPhase'),
173 + '.tiff': ('image.tiff', 'PBXResourcesBuildPhase'),
174 + '.txt': ('text', 'PBXResourcesBuildPhase'),
175 + '.xcodeproj': ('wrapper.pb-project', None),
176 + '.xib': ('file.xib', 'PBXResourcesBuildPhase'),
177 + '.strings': ('text.plist.strings', 'PBXResourcesBuildPhase'),
178 + '.bundle': ('wrapper.plug-in', 'PBXResourcesBuildPhase'),
179 + '.dylib': ('compiled.mach-o.dylib', 'PBXFrameworksBuildPhase'),
180 + '.xcdatamodeld': ('wrapper.xcdatamodel', 'PBXSourcesBuildPhase'),
181 + '.xcassets': ('folder.assetcatalog', 'PBXResourcesBuildPhase'),
182 + '.tbd': ('sourcecode.text-based-dylib-definition', 'PBXFrameworksBuildPhase'),
183 + }
184 +
185 + trees = [
186 + '<absolute>',
187 + '<group>',
188 + 'BUILT_PRODUCTS_DIR',
189 + 'DEVELOPER_DIR',
190 + 'SDKROOT',
191 + 'SOURCE_ROOT',
192 + ]
193 +
194 + def guess_file_type(self, ignore_unknown_type=False):
195 + self.remove('explicitFileType')
196 + self.remove('lastKnownFileType')
197 +
198 +
199 + ext = os.path.splitext(self.get('name', ''))[1]
200 + if os.path.isdir(self.get('path')) and ext not in XcodeProject.special_folders:
201 + f_type = 'folder'
202 + build_phase = None
203 + ext = ''
204 + else:
205 + f_type, build_phase = PBXFileReference.types.get(ext, ('?', 'PBXResourcesBuildPhase'))
206 +
207 + self['lastKnownFileType'] = f_type
208 + self.build_phase = build_phase
209 +
210 + if f_type == '?' and not ignore_unknown_type:
211 + print 'unknown file extension: %s' % ext
212 + print 'please add extension and Xcode type to PBXFileReference.types'
213 +
214 + return f_type
215 +
216 + def set_file_type(self, ft):
217 + self.remove('explicitFileType')
218 + self.remove('lastKnownFileType')
219 +
220 + self['explicitFileType'] = ft
221 +
222 + @classmethod
223 + def Create(cls, os_path, tree='SOURCE_ROOT', ignore_unknown_type=False):
224 + if tree not in cls.trees:
225 + print 'Not a valid sourceTree type: %s' % tree
226 + return None
227 +
228 + fr = cls()
229 + fr.id = cls.GenerateId()
230 + fr['path'] = os_path
231 + fr['name'] = os.path.split(os_path)[1]
232 + fr['sourceTree'] = '<absolute>' if os.path.isabs(os_path) else tree
233 + fr.guess_file_type(ignore_unknown_type=ignore_unknown_type)
234 +
235 + return fr
236 +
237 +
238 +class PBXBuildFile(PBXType):
239 + def set_weak_link(self, weak=False):
240 + k_settings = 'settings'
241 + k_attributes = 'ATTRIBUTES'
242 +
243 + s = self.get(k_settings)
244 +
245 + if not s:
246 + if weak:
247 + self[k_settings] = PBXDict({k_attributes: PBXList(['Weak'])})
248 +
249 + return True
250 +
251 + atr = s.get(k_attributes)
252 +
253 + if not atr:
254 + if weak:
255 + atr = PBXList()
256 + else:
257 + return False
258 +
259 + if weak:
260 + atr.add('Weak')
261 + else:
262 + atr.remove('Weak')
263 +
264 + self[k_settings][k_attributes] = atr
265 +
266 + return True
267 +
268 + def add_compiler_flag(self, flag):
269 + k_settings = 'settings'
270 + k_attributes = 'COMPILER_FLAGS'
271 +
272 + if k_settings not in self:
273 + self[k_settings] = PBXDict()
274 +
275 + if k_attributes not in self[k_settings]:
276 + self[k_settings][k_attributes] = flag
277 + return True
278 +
279 + flags = self[k_settings][k_attributes].split(' ')
280 +
281 + if flag in flags:
282 + return False
283 +
284 + flags.append(flag)
285 +
286 + self[k_settings][k_attributes] = ' '.join(flags)
287 +
288 + @classmethod
289 + def Create(cls, file_ref, weak=False):
290 + if isinstance(file_ref, PBXFileReference):
291 + file_ref = file_ref.id
292 +
293 + bf = cls()
294 + bf.id = cls.GenerateId()
295 + bf['fileRef'] = file_ref
296 +
297 + if weak:
298 + bf.set_weak_link(True)
299 +
300 + return bf
301 +
302 +
303 +class PBXGroup(PBXType):
304 + def add_child(self, ref):
305 + if not isinstance(ref, PBXDict):
306 + return None
307 +
308 + isa = ref.get('isa')
309 +
310 + if isa != 'PBXFileReference' and isa != 'PBXGroup':
311 + return None
312 +
313 + if 'children' not in self:
314 + self['children'] = PBXList()
315 +
316 + self['children'].add(ref.id)
317 +
318 + return ref.id
319 +
320 + def remove_child(self, id):
321 + if 'children' not in self:
322 + self['children'] = PBXList()
323 + return
324 +
325 + if not PBXType.IsGuid(id):
326 + id = id.id
327 +
328 + self['children'].remove(id)
329 +
330 + def has_child(self, id):
331 + if 'children' not in self:
332 + self['children'] = PBXList()
333 + return False
334 +
335 + if not PBXType.IsGuid(id):
336 + id = id.id
337 +
338 + return id in self['children']
339 +
340 + def get_name(self):
341 + path_name = os.path.split(self.get('path', ''))[1]
342 + return self.get('name', path_name)
343 +
344 + @classmethod
345 + def Create(cls, name, path=None, tree='SOURCE_ROOT'):
346 + grp = cls()
347 + grp.id = cls.GenerateId()
348 + grp['name'] = name
349 + grp['children'] = PBXList()
350 +
351 + if path:
352 + grp['path'] = path
353 + grp['sourceTree'] = tree
354 + else:
355 + grp['sourceTree'] = '<group>'
356 +
357 + return grp
358 +
359 +
360 +class PBXNativeTarget(PBXType):
361 + pass
362 +
363 +
364 +class PBXProject(PBXType):
365 + pass
366 +
367 +
368 +class PBXContainerItemProxy(PBXType):
369 + pass
370 +
371 +
372 +class PBXReferenceProxy(PBXType):
373 + pass
374 +
375 +
376 +class PBXVariantGroup(PBXType):
377 + pass
378 +
379 +
380 +class PBXTargetDependency(PBXType):
381 + pass
382 +
383 +
384 +class PBXAggregateTarget(PBXType):
385 + pass
386 +
387 +
388 +class PBXHeadersBuildPhase(PBXType):
389 + pass
390 +
391 +class XCVersionGroup(PBXType):
392 + pass
393 +
394 +class PBXBuildPhase(PBXType):
395 + def add_build_file(self, bf):
396 + if bf.get('isa') != 'PBXBuildFile':
397 + return False
398 +
399 + if 'files' not in self:
400 + self['files'] = PBXList()
401 +
402 + self['files'].add(bf.id)
403 +
404 + return True
405 +
406 + def remove_build_file(self, id):
407 + if 'files' not in self:
408 + self['files'] = PBXList()
409 + return
410 +
411 + self['files'].remove(id)
412 +
413 + def has_build_file(self, id):
414 + if 'files' not in self:
415 + self['files'] = PBXList()
416 + return False
417 +
418 + if not PBXType.IsGuid(id):
419 + id = id.id
420 +
421 + return id in self['files']
422 +
423 +
424 +class PBXFrameworksBuildPhase(PBXBuildPhase):
425 + pass
426 +
427 +
428 +class PBXResourcesBuildPhase(PBXBuildPhase):
429 + pass
430 +
431 +
432 +class PBXShellScriptBuildPhase(PBXBuildPhase):
433 + @classmethod
434 + def Create(cls, script, shell="/bin/sh", files=[], input_paths=[], output_paths=[], show_in_log = '0'):
435 + bf = cls()
436 + bf.id = cls.GenerateId()
437 + bf['files'] = files
438 + bf['inputPaths'] = input_paths
439 + bf['outputPaths'] = output_paths
440 + bf['runOnlyForDeploymentPostprocessing'] = '0';
441 + bf['shellPath'] = shell
442 + bf['shellScript'] = script
443 + bf['showEnvVarsInLog'] = show_in_log
444 +
445 + return bf
446 +
447 +
448 +class PBXSourcesBuildPhase(PBXBuildPhase):
449 + pass
450 +
451 +
452 +class PBXCopyFilesBuildPhase(PBXBuildPhase):
453 + pass
454 +
455 +
456 +class XCBuildConfiguration(PBXType):
457 + def add_search_paths(self, paths, base, key, recursive=True, escape=True):
458 + modified = False
459 +
460 + if not isinstance(paths, list):
461 + paths = [paths]
462 +
463 + if base not in self:
464 + self[base] = PBXDict()
465 +
466 + for path in paths:
467 + if recursive and not path.endswith('/**'):
468 + path = os.path.join(path, '**')
469 +
470 + if key not in self[base]:
471 + self[base][key] = PBXList()
472 + elif isinstance(self[base][key], basestring):
473 + self[base][key] = PBXList(self[base][key])
474 +
475 + if path == '$(inherited)':
476 + escape = False
477 +
478 + if escape:
479 + if self[base][key].add('"%s"' % path): # '\\"%s\\"' % path
480 + modified = True
481 + else:
482 + if self[base][key].add(path): # '\\"%s\\"' % path
483 + modified = True
484 +
485 + return modified
486 +
487 + def add_header_search_paths(self, paths, recursive=True):
488 + return self.add_search_paths(paths, 'buildSettings', 'HEADER_SEARCH_PATHS', recursive=recursive)
489 +
490 + def add_library_search_paths(self, paths, recursive=True):
491 + return self.add_search_paths(paths, 'buildSettings', 'LIBRARY_SEARCH_PATHS', recursive=recursive)
492 +
493 + def add_framework_search_paths(self, paths, recursive=True):
494 + return self.add_search_paths(paths, 'buildSettings', 'FRAMEWORK_SEARCH_PATHS', recursive=recursive)
495 +
496 + def add_other_cflags(self, flags):
497 + return self.add_flag('OTHER_CFLAGS', flags)
498 +
499 + def add_other_ldflags(self, flags):
500 + return self.add_flag('OTHER_LDFLAGS', flags)
501 +
502 + def add_flag(self, key, flags):
503 + modified = False
504 + base = 'buildSettings'
505 +
506 + if isinstance(flags, basestring):
507 + flags = PBXList(flags)
508 +
509 + if base not in self:
510 + self[base] = PBXDict()
511 +
512 + for flag in flags:
513 + if key not in self[base]:
514 + self[base][key] = PBXList()
515 + elif isinstance(self[base][key], basestring):
516 + self[base][key] = PBXList(self[base][key])
517 +
518 + if self[base][key].add(flag):
519 + self[base][key] = [e for e in self[base][key] if e]
520 + modified = True
521 +
522 + return modified
523 +
524 + def remove_flag(self, key, flags):
525 + modified = False
526 + base = 'buildSettings'
527 +
528 + if isinstance(flags, basestring):
529 + flags = PBXList(flags)
530 +
531 + if base in self: # there are flags, so we can "remove" something
532 + for flag in flags:
533 + if key not in self[base]:
534 + return False
535 + elif isinstance(self[base][key], basestring):
536 + self[base][key] = PBXList(self[base][key])
537 +
538 + if self[base][key].remove(flag):
539 + self[base][key] = [e for e in self[base][key] if e]
540 + modified = True
541 +
542 + if len(self[base][key]) == 0:
543 + self[base].pop(key, None)
544 +
545 + return modified
546 +
547 + def remove_other_ldflags(self, flags):
548 + return self.remove_flag('OTHER_LD_FLAGS', flags)
549 +
550 + # Set a single-valued flag under buildSettings
551 + def add_single_valued_flag(self, flag, value):
552 + modified = False
553 + base = 'buildSettings'
554 + key = flag
555 +
556 + if not self.has_key(base):
557 + self[base] = PBXDict()
558 + if self[base].has_key(key):
559 + if self[base][key] == value:
560 + return False
561 + self[base][key] = value
562 + modified = True
563 + return modified
564 +
565 + # Remove a single-valued flag under buildSettings
566 + def remove_single_valued_flag(self, flag):
567 + modified = False
568 + base = 'buildSettings'
569 + key = flag
570 +
571 + if self.has_key(base) and self[base].has_key(key):
572 + self[base].pop(key, None)
573 + modified = True
574 + return modified
575 +
576 +class XCConfigurationList(PBXType):
577 + pass
578 +
579 +
580 +class XcodeProject(PBXDict):
581 + plutil_path = 'plutil'
582 + special_folders = ['.bundle', '.framework', '.xcodeproj', '.xcassets', '.xcdatamodeld']
583 +
584 + def __init__(self, d=None, path=None):
585 + if not path:
586 + path = os.path.join(os.getcwd(), 'project.pbxproj')
587 +
588 + self.pbxproj_path = os.path.abspath(path)
589 + self.source_root = os.path.abspath(os.path.join(os.path.split(path)[0], '..'))
590 +
591 + IterableUserDict.__init__(self, d)
592 +
593 + self.data = PBXDict(self.data)
594 + self.objects = self.get('objects')
595 + self.modified = False
596 +
597 + root_id = self.get('rootObject')
598 +
599 + if root_id:
600 + self.root_object = self.objects[root_id]
601 + root_group_id = self.root_object.get('mainGroup')
602 + self.root_group = self.objects[root_group_id]
603 + else:
604 + print "error: project has no root object"
605 + self.root_object = None
606 + self.root_group = None
607 +
608 + for k, v in self.objects.iteritems():
609 + v.id = k
610 +
611 + def add_other_cflags(self, flags):
612 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
613 +
614 + for b in build_configs:
615 + if b.add_other_cflags(flags):
616 + self.modified = True
617 +
618 + def add_other_ldflags(self, flags):
619 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
620 +
621 + for b in build_configs:
622 + if b.add_other_ldflags(flags):
623 + self.modified = True
624 +
625 + def remove_other_ldflags(self, flags):
626 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
627 +
628 + for b in build_configs:
629 + if b.remove_other_ldflags(flags):
630 + self.modified = True
631 +
632 + def add_header_search_paths(self, paths, recursive=True):
633 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
634 +
635 + for b in build_configs:
636 + if b.add_header_search_paths(paths, recursive):
637 + self.modified = True
638 +
639 + def add_framework_search_paths(self, paths, recursive=True):
640 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
641 +
642 + for b in build_configs:
643 + if b.add_framework_search_paths(paths, recursive):
644 + self.modified = True
645 +
646 + def add_library_search_paths(self, paths, recursive=True):
647 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
648 +
649 + for b in build_configs:
650 + if b.add_library_search_paths(paths, recursive):
651 + self.modified = True
652 +
653 + def add_flags(self, pairs, configuration='All'):
654 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
655 +
656 + # iterate over all the pairs of configurations
657 + for b in build_configs:
658 + if configuration != "All" and b.get('name') != configuration :
659 + continue
660 +
661 + for k in pairs:
662 + if b.add_flag(k, pairs[k]):
663 + self.modified = True
664 +
665 + def remove_flags(self, pairs, configuration='All'):
666 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
667 +
668 + # iterate over all the pairs of configurations
669 + for b in build_configs:
670 + if configuration != "All" and b.get('name') != configuration :
671 + continue
672 + for k in pairs:
673 + if b.remove_flag(k, pairs[k]):
674 + self.modified = True
675 +
676 + # Set a single-valued flag (whereas add_flags adds a flag to a list of flags with a given key)
677 + def add_single_valued_flag(self, flag, value, configuration='All'):
678 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
679 +
680 + for b in build_configs:
681 + if configuration != "All" and b.get('name') != configuration :
682 + continue
683 +
684 + if b.add_single_valued_flag(flag, value):
685 + self.modified = True
686 +
687 + # Remove a single-valued flag (whereas remove_flags deletes a flag from a list of flags with a given key)
688 + def remove_single_valued_flag(self, flag, configuration='All'):
689 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
690 +
691 + for b in build_configs:
692 + if configuration != "All" and b.get('name') != configuration :
693 + continue
694 +
695 + if b.remove_single_valued_flag(flag):
696 + self.modified = True
697 +
698 + def get_obj(self, id):
699 + return self.objects.get(id)
700 +
701 + def get_ids(self):
702 + return self.objects.keys()
703 +
704 + def get_files_by_os_path(self, os_path, tree='SOURCE_ROOT'):
705 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference'
706 + and f.get('path') == os_path
707 + and f.get('sourceTree') == tree]
708 +
709 + return files
710 +
711 + def get_files_by_name(self, name, parent=None):
712 + if parent:
713 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference'
714 + and f.get('name') == name
715 + and parent.has_child(f)]
716 + else:
717 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference'
718 + and f.get('name') == name]
719 +
720 + return files
721 +
722 + def get_keys_for_files_by_name(self, name):
723 + keys = [key for key in self.objects if self.objects.data[key].get('name') == name
724 + and self.objects.data[key].get('isa') == 'PBXFileReference']
725 + return keys
726 +
727 +
728 + def get_build_files(self, id):
729 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXBuildFile'
730 + and f.get('fileRef') == id]
731 + return files
732 +
733 + def get_groups_by_name(self, name, parent=None):
734 + if parent:
735 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'
736 + and g.get_name() == name
737 + and parent.has_child(g)]
738 + else:
739 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'
740 + and g.get_name() == name]
741 +
742 + return groups
743 +
744 + def get_or_create_group(self, name, path=None, parent=None):
745 + if not name:
746 + return None
747 +
748 + if not parent:
749 + parent = self.root_group
750 + elif not isinstance(parent, PBXGroup):
751 + # assume it's an id
752 + parent = self.objects.get(parent, self.root_group)
753 +
754 + groups = self.get_groups_by_name(name)
755 +
756 + for grp in groups:
757 + if parent.has_child(grp.id):
758 + return grp
759 +
760 + grp = PBXGroup.Create(name, path)
761 + parent.add_child(grp)
762 +
763 + self.objects[grp.id] = grp
764 +
765 + self.modified = True
766 +
767 + return grp
768 +
769 + def get_groups_by_os_path(self, path):
770 + path = os.path.abspath(path)
771 +
772 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'
773 + and os.path.abspath(g.get('path', '/dev/null')) == path]
774 +
775 + return groups
776 +
777 + def get_build_phases(self, phase_name):
778 + phases = [p for p in self.objects.values() if p.get('isa') == phase_name]
779 +
780 + return phases
781 +
782 + def get_target_by_name(self, name):
783 + targets = self.get_build_phases('PBXNativeTarget')
784 + target = None
785 + for t in targets:
786 + if t.get("name") == name:
787 + target = t
788 + break
789 + return target
790 +
791 + def get_relative_path(self, os_path):
792 + return os.path.relpath(os_path, self.source_root)
793 +
794 + def verify_files(self, file_list, parent=None):
795 + # returns list of files not in the current project.
796 + if not file_list:
797 + return []
798 +
799 + if parent:
800 + exists_list = [f.get('name') for f in self.objects.values() if f.get('isa') == 'PBXFileReference' and f.get('name') in file_list and parent.has_child(f)]
801 + else:
802 + exists_list = [f.get('name') for f in self.objects.values() if f.get('isa') == 'PBXFileReference' and f.get('name') in file_list]
803 +
804 + return set(file_list).difference(exists_list)
805 +
806 + def add_run_script(self, target, script=None, insert_before_compile=False):
807 + result = []
808 + targets = [t for t in self.get_build_phases('PBXNativeTarget') + self.get_build_phases('PBXAggregateTarget') if t.get('name') == target]
809 + if len(targets) != 0 :
810 + script_phase = PBXShellScriptBuildPhase.Create(script)
811 + for t in targets:
812 + skip = False
813 + for buildPhase in t['buildPhases']:
814 + if self.objects[buildPhase].get('isa') == 'PBXShellScriptBuildPhase' and self.objects[buildPhase].get('shellScript') == script:
815 + skip = True
816 +
817 + if not skip:
818 + if insert_before_compile:
819 + t['buildPhases'].insert(0, script_phase.id)
820 + else:
821 + t['buildPhases'].add(script_phase.id)
822 + self.objects[script_phase.id] = script_phase
823 + result.append(script_phase)
824 +
825 + return result
826 +
827 + def add_run_script_all_targets(self, script=None):
828 + result = []
829 + targets = self.get_build_phases('PBXNativeTarget') + self.get_build_phases('PBXAggregateTarget')
830 + if len(targets) != 0 :
831 + script_phase = PBXShellScriptBuildPhase.Create(script)
832 + for t in targets:
833 + skip = False
834 + for buildPhase in t['buildPhases']:
835 + if self.objects[buildPhase].get('isa') == 'PBXShellScriptBuildPhase' and self.objects[buildPhase].get('shellScript') == script:
836 + skip = True
837 +
838 + if not skip:
839 + t['buildPhases'].add(script_phase.id)
840 + self.objects[script_phase.id] = script_phase
841 + result.append(script_phase)
842 +
843 + return result
844 +
845 + def add_folder(self, os_path, parent=None, excludes=None, recursive=True, create_build_files=True):
846 + if not os.path.isdir(os_path):
847 + return []
848 +
849 + if not excludes:
850 + excludes = []
851 +
852 + results = []
853 +
854 + if not parent:
855 + parent = self.root_group
856 + elif not isinstance(parent, PBXGroup):
857 + # assume it's an id
858 + parent = self.objects.get(parent, self.root_group)
859 +
860 + path_dict = {os.path.split(os_path)[0]: parent}
861 + special_list = []
862 +
863 + for (grp_path, subdirs, files) in os.walk(os_path):
864 + parent_folder, folder_name = os.path.split(grp_path)
865 + parent = path_dict.get(parent_folder, parent)
866 +
867 + if [sp for sp in special_list if parent_folder.startswith(sp)]:
868 + continue
869 +
870 + if folder_name.startswith('.'):
871 + special_list.append(grp_path)
872 + continue
873 +
874 + if os.path.splitext(grp_path)[1] in XcodeProject.special_folders:
875 + # if this file has a special extension (bundle or framework mainly) treat it as a file
876 + special_list.append(grp_path)
877 + new_files = self.verify_files([folder_name], parent=parent)
878 +
879 + # Ignore this file if it is in excludes
880 + if new_files and not [m for m in excludes if re.match(m, grp_path)]:
881 + results.extend(self.add_file(grp_path, parent, create_build_files=create_build_files))
882 +
883 + continue
884 +
885 + # create group
886 + grp = self.get_or_create_group(folder_name, path=self.get_relative_path(grp_path), parent=parent)
887 + path_dict[grp_path] = grp
888 +
889 + results.append(grp)
890 +
891 + file_dict = {}
892 +
893 + for f in files:
894 + if f[0] == '.' or [m for m in excludes if re.match(m, f)]:
895 + continue
896 +
897 + kwds = {
898 + 'create_build_files': create_build_files,
899 + 'parent': grp,
900 + 'name': f
901 + }
902 +
903 + f_path = os.path.join(grp_path, f)
904 + file_dict[f_path] = kwds
905 +
906 + new_files = self.verify_files([n.get('name') for n in file_dict.values()], parent=grp)
907 + add_files = [(k, v) for k, v in file_dict.items() if v.get('name') in new_files]
908 +
909 + for path, kwds in add_files:
910 + kwds.pop('name', None)
911 + self.add_file(path, **kwds)
912 +
913 + if not recursive:
914 + break
915 +
916 + for r in results:
917 + self.objects[r.id] = r
918 +
919 + return results
920 +
921 + def path_leaf(self, path):
922 + head, tail = ntpath.split(path)
923 + return tail or ntpath.basename(head)
924 +
925 + def add_file_if_doesnt_exist(self, f_path, parent=None, tree='SOURCE_ROOT', create_build_files=True, weak=False, ignore_unknown_type=False):
926 + for obj in self.objects.values():
927 + if 'path' in obj:
928 + if self.path_leaf(f_path) == self.path_leaf(obj.get('path')):
929 + return []
930 +
931 + return self.add_file(f_path, parent, tree, create_build_files, weak, ignore_unknown_type=ignore_unknown_type)
932 +
933 + def add_file(self, f_path, parent=None, tree='SOURCE_ROOT', create_build_files=True, weak=False, ignore_unknown_type=False, target=None):
934 + results = []
935 + abs_path = ''
936 +
937 + if os.path.isabs(f_path):
938 + abs_path = f_path
939 +
940 + if not os.path.exists(f_path):
941 + return results
942 + elif tree == 'SOURCE_ROOT':
943 + f_path = os.path.relpath(f_path, self.source_root)
944 + else:
945 + tree = '<absolute>'
946 +
947 + if not parent:
948 + parent = self.root_group
949 + elif not isinstance(parent, PBXGroup):
950 + # assume it's an id
951 + parent = self.objects.get(parent, self.root_group)
952 +
953 + file_ref = PBXFileReference.Create(f_path, tree, ignore_unknown_type=ignore_unknown_type)
954 + parent.add_child(file_ref)
955 + results.append(file_ref)
956 +
957 + # create a build file for the file ref
958 + if file_ref.build_phase and create_build_files:
959 + phases = self.get_build_phases(file_ref.build_phase)
960 + if target:
961 + target = self.get_target_by_name(target)
962 +
963 + for phase in phases:
964 + if (not target) or (phase.id in target.get('buildPhases')):
965 + build_file = PBXBuildFile.Create(file_ref, weak=weak)
966 + phase.add_build_file(build_file)
967 + results.append(build_file)
968 +
969 + if abs_path and tree == 'SOURCE_ROOT' \
970 + and os.path.isfile(abs_path) \
971 + and file_ref.build_phase == 'PBXFrameworksBuildPhase':
972 + library_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0])
973 + self.add_library_search_paths([library_path], recursive=False)
974 +
975 + if abs_path and tree == 'SOURCE_ROOT' \
976 + and not os.path.isfile(abs_path) \
977 + and file_ref.build_phase == 'PBXFrameworksBuildPhase':
978 + framework_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0])
979 + self.add_framework_search_paths([framework_path, '$(inherited)'], recursive=False)
980 +
981 + for r in results:
982 + self.objects[r.id] = r
983 +
984 + if results:
985 + self.modified = True
986 +
987 + return results
988 +
989 + def check_and_repair_framework(self, base):
990 + name = os.path.basename(base)
991 +
992 + if ".framework" in name:
993 + basename = name[:-len(".framework")]
994 +
995 + finalHeaders = os.path.join(base, "Headers")
996 + finalCurrent = os.path.join(base, "Versions/Current")
997 + finalLib = os.path.join(base, basename)
998 + srcHeaders = "Versions/A/Headers"
999 + srcCurrent = "A"
1000 + srcLib = "Versions/A/" + basename
1001 +
1002 + if not os.path.exists(finalHeaders):
1003 + os.symlink(srcHeaders, finalHeaders)
1004 + if not os.path.exists(finalCurrent):
1005 + os.symlink(srcCurrent, finalCurrent)
1006 + if not os.path.exists(finalLib):
1007 + os.symlink(srcLib, finalLib)
1008 +
1009 +
1010 + def get_file_id_by_path(self, f_path):
1011 + for k, v in self.objects.iteritems():
1012 + if str(v.get('path')) == f_path:
1013 + return k
1014 + return 0
1015 +
1016 +
1017 + def remove_file_by_path(self, f_path, recursive=True):
1018 + id = self.get_file_id_by_path(f_path)
1019 + if id != 0:
1020 + self.remove_file(id, recursive=recursive)
1021 + return
1022 +
1023 +
1024 + def remove_file(self, id, recursive=True):
1025 + if not PBXType.IsGuid(id):
1026 + id = id.id
1027 +
1028 + if id in self.objects:
1029 + self.objects.remove(id)
1030 + # Remove from PBXResourcesBuildPhase and PBXSourcesBuildPhase if necessary
1031 + buildFiles = [f for f in self.objects.values() if f.get('isa') == 'PBXBuildFile']
1032 + for buildFile in buildFiles:
1033 + if id == buildFile.get('fileRef'):
1034 + key = buildFile.id
1035 + PBXRBP = [f for f in self.objects.values() if f.get('isa') == 'PBXResourcesBuildPhase']
1036 + PBXSBP = [f for f in self.objects.values() if f.get('isa') == 'PBXSourcesBuildPhase']
1037 + self.objects.remove(key)
1038 + if len(PBXSBP) and PBXSBP[0].has_build_file(key):
1039 + PBXSBP[0].remove_build_file(key)
1040 + if len(PBXRBP) and PBXRBP[0].has_build_file(key):
1041 + PBXRBP[0].remove_build_file(key)
1042 + if recursive:
1043 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup']
1044 +
1045 + for group in groups:
1046 + if id in group['children']:
1047 + group.remove_child(id)
1048 +
1049 + self.modified = True
1050 +
1051 + def remove_group(self, id, recursive = True):
1052 + if not PBXType.IsGuid(id):
1053 + id = id.id
1054 + name = self.objects.get(id).get('path')
1055 + children = self.objects.get(id).get('children')
1056 + if name is None:
1057 + name = id
1058 + if id in self.objects:
1059 + if recursive:
1060 + for childKey in children:
1061 + childValue = self.objects.get(childKey)
1062 + if childValue.get('isa') == 'PBXGroup':
1063 + self.remove_group(childKey, True)
1064 + else:
1065 + self.remove_file(childKey, False)
1066 +
1067 + self.objects.remove(id);
1068 +
1069 + def remove_group_by_name(self, name, recursive = True):
1070 + groups = self.get_groups_by_name(name)
1071 + if len(groups):
1072 + for group in groups:
1073 + self.remove_group(group.id, recursive)
1074 +
1075 + def move_file(self, id, dest_grp=None):
1076 + pass
1077 +
1078 + def apply_patch(self, patch_path, xcode_path):
1079 + if not os.path.isfile(patch_path) or not os.path.isdir(xcode_path):
1080 + print 'ERROR: couldn\'t apply "%s" to "%s"' % (patch_path, xcode_path)
1081 + return
1082 +
1083 + print 'applying "%s" to "%s"' % (patch_path, xcode_path)
1084 +
1085 + return subprocess.call(['patch', '-p1', '--forward', '--directory=%s' % xcode_path, '--input=%s' % patch_path])
1086 +
1087 + def apply_mods(self, mod_dict, default_path=None):
1088 + if not default_path:
1089 + default_path = os.getcwd()
1090 +
1091 + keys = mod_dict.keys()
1092 +
1093 + for k in keys:
1094 + v = mod_dict.pop(k)
1095 + mod_dict[k.lower()] = v
1096 +
1097 + parent = mod_dict.pop('group', None)
1098 +
1099 + if parent:
1100 + parent = self.get_or_create_group(parent)
1101 +
1102 + excludes = mod_dict.pop('excludes', [])
1103 +
1104 + if excludes:
1105 + excludes = [re.compile(e) for e in excludes]
1106 +
1107 + compiler_flags = mod_dict.pop('compiler_flags', {})
1108 +
1109 + for k, v in mod_dict.items():
1110 + if k == 'patches':
1111 + for p in v:
1112 + if not os.path.isabs(p):
1113 + p = os.path.join(default_path, p)
1114 +
1115 + self.apply_patch(p, self.source_root)
1116 + elif k == 'folders':
1117 + # get and compile excludes list
1118 + # do each folder individually
1119 + for folder in v:
1120 + kwds = {}
1121 +
1122 + # if path contains ':' remove it and set recursive to False
1123 + if ':' in folder:
1124 + args = folder.split(':')
1125 + kwds['recursive'] = False
1126 + folder = args.pop(0)
1127 +
1128 + if os.path.isabs(folder) and os.path.isdir(folder):
1129 + pass
1130 + else:
1131 + folder = os.path.join(default_path, folder)
1132 + if not os.path.isdir(folder):
1133 + continue
1134 +
1135 + if parent:
1136 + kwds['parent'] = parent
1137 +
1138 + if excludes:
1139 + kwds['excludes'] = excludes
1140 +
1141 + self.add_folder(folder, **kwds)
1142 + elif k == 'headerpaths' or k == 'librarypaths':
1143 + paths = []
1144 +
1145 + for p in v:
1146 + if p.endswith('/**'):
1147 + p = os.path.split(p)[0]
1148 +
1149 + if not os.path.isabs(p):
1150 + p = os.path.join(default_path, p)
1151 +
1152 + if not os.path.exists(p):
1153 + continue
1154 +
1155 + p = self.get_relative_path(p)
1156 + paths.append(os.path.join('$(SRCROOT)', p, "**"))
1157 +
1158 + if k == 'headerpaths':
1159 + self.add_header_search_paths(paths)
1160 + else:
1161 + self.add_library_search_paths(paths)
1162 + elif k == 'other_cflags':
1163 + self.add_other_cflags(v)
1164 + elif k == 'other_ldflags':
1165 + self.add_other_ldflags(v)
1166 + elif k == 'libs' or k == 'frameworks' or k == 'files':
1167 + paths = {}
1168 +
1169 + for p in v:
1170 + kwds = {}
1171 +
1172 + if ':' in p:
1173 + args = p.split(':')
1174 + p = args.pop(0)
1175 +
1176 + if 'weak' in args:
1177 + kwds['weak'] = True
1178 +
1179 + file_path = os.path.join(default_path, p)
1180 + search_path, file_name = os.path.split(file_path)
1181 +
1182 + if [m for m in excludes if re.match(m, file_name)]:
1183 + continue
1184 +
1185 + try:
1186 + expr = re.compile(file_name)
1187 + except re.error:
1188 + expr = None
1189 +
1190 + if expr and os.path.isdir(search_path):
1191 + file_list = os.listdir(search_path)
1192 +
1193 + for f in file_list:
1194 + if [m for m in excludes if re.match(m, f)]:
1195 + continue
1196 +
1197 + if re.search(expr, f):
1198 + kwds['name'] = f
1199 + paths[os.path.join(search_path, f)] = kwds
1200 + p = None
1201 +
1202 + if k == 'libs':
1203 + kwds['parent'] = self.get_or_create_group('Libraries', parent=parent)
1204 + elif k == 'frameworks':
1205 + kwds['parent'] = self.get_or_create_group('Frameworks', parent=parent)
1206 +
1207 + if p:
1208 + kwds['name'] = file_name
1209 +
1210 + if k == 'libs':
1211 + p = os.path.join('usr', 'lib', p)
1212 + kwds['tree'] = 'SDKROOT'
1213 + elif k == 'frameworks':
1214 + p = os.path.join('System', 'Library', 'Frameworks', p)
1215 + kwds['tree'] = 'SDKROOT'
1216 + elif k == 'files' and not os.path.exists(file_path):
1217 + # don't add non-existent files to the project.
1218 + continue
1219 +
1220 + paths[p] = kwds
1221 +
1222 + new_files = self.verify_files([n.get('name') for n in paths.values()])
1223 + add_files = [(k, v) for k, v in paths.items() if v.get('name') in new_files]
1224 +
1225 + for path, kwds in add_files:
1226 + kwds.pop('name', None)
1227 +
1228 + if 'parent' not in kwds and parent:
1229 + kwds['parent'] = parent
1230 +
1231 + self.add_file(path, **kwds)
1232 +
1233 + if compiler_flags:
1234 + for k, v in compiler_flags.items():
1235 + filerefs = []
1236 +
1237 + for f in v:
1238 + filerefs.extend([fr.id for fr in self.objects.values() if fr.get('isa') == 'PBXFileReference'
1239 + and fr.get('name') == f])
1240 +
1241 + buildfiles = [bf for bf in self.objects.values() if bf.get('isa') == 'PBXBuildFile'
1242 + and bf.get('fileRef') in filerefs]
1243 +
1244 + for bf in buildfiles:
1245 + if bf.add_compiler_flag(k):
1246 + self.modified = True
1247 +
1248 + def backup(self, file_name=None, backup_name=None):
1249 + if not file_name:
1250 + file_name = self.pbxproj_path
1251 +
1252 + if not backup_name:
1253 + backup_name = "%s.%s.backup" % (file_name, datetime.datetime.now().strftime('%d%m%y-%H%M%S'))
1254 +
1255 + shutil.copy2(file_name, backup_name)
1256 + return backup_name
1257 +
1258 + def save(self, file_name=None, old_format=False, sort=False):
1259 + if old_format :
1260 + self.save_format_xml(file_name)
1261 + else:
1262 + self.save_new_format(file_name, sort)
1263 +
1264 + def save_format_xml(self, file_name=None):
1265 + """Saves in old (xml) format"""
1266 + if not file_name:
1267 + file_name = self.pbxproj_path
1268 +
1269 + # This code is adapted from plistlib.writePlist
1270 + with open(file_name, "w") as f:
1271 + writer = PBXWriter(f)
1272 + writer.writeln("<plist version=\"1.0\">")
1273 + writer.writeValue(self.data)
1274 + writer.writeln("</plist>")
1275 +
1276 + def save_new_format(self, file_name=None, sort=False):
1277 + """Save in Xcode 3.2 compatible (new) format"""
1278 + if not file_name:
1279 + file_name = self.pbxproj_path
1280 +
1281 + # process to get the section's info and names
1282 + objs = self.data.get('objects')
1283 + sections = dict()
1284 + uuids = dict()
1285 +
1286 + for key in objs:
1287 + l = list()
1288 +
1289 + if objs.get(key).get('isa') in sections:
1290 + l = sections.get(objs.get(key).get('isa'))
1291 +
1292 + l.append(tuple([key, objs.get(key)]))
1293 + sections[objs.get(key).get('isa')] = l
1294 +
1295 + if 'name' in objs.get(key):
1296 + uuids[key] = objs.get(key).get('name')
1297 + elif 'path' in objs.get(key):
1298 + uuids[key] = objs.get(key).get('path')
1299 + else:
1300 + if objs.get(key).get('isa') == 'PBXProject':
1301 + uuids[objs.get(key).get('buildConfigurationList')] = 'Build configuration list for PBXProject "Unity-iPhone"'
1302 + elif objs.get(key).get('isa')[0:3] == 'PBX':
1303 + uuids[key] = objs.get(key).get('isa')[3:-10]
1304 + else:
1305 + uuids[key] = 'Build configuration list for PBXNativeTarget "TARGET_NAME"'
1306 +
1307 + ro = self.data.get('rootObject')
1308 + uuids[ro] = 'Project object'
1309 +
1310 + for key in objs:
1311 + # transitive references (used in the BuildFile section)
1312 + if 'fileRef' in objs.get(key) and objs.get(key).get('fileRef') in uuids:
1313 + uuids[key] = uuids[objs.get(key).get('fileRef')]
1314 +
1315 + # transitive reference to the target name (used in the Native target section)
1316 + if objs.get(key).get('isa') == 'PBXNativeTarget':
1317 + uuids[objs.get(key).get('buildConfigurationList')] = uuids[objs.get(key).get('buildConfigurationList')].replace('TARGET_NAME', uuids[key])
1318 +
1319 + self.uuids = uuids
1320 + self.sections = sections
1321 +
1322 + out = open(file_name, 'w')
1323 + out.write('// !$*UTF8*$!\n')
1324 + self._printNewXCodeFormat(out, self.data, '', enters=True, sort=sort)
1325 + out.close()
1326 +
1327 + @classmethod
1328 + def addslashes(cls, s):
1329 + d = {'"': '\\"', "'": "\\'", "\0": "\\\0", "\\": "\\\\", "\n":"\\n"}
1330 + return ''.join(d.get(c, c) for c in s)
1331 +
1332 + def _printNewXCodeFormat(self, out, root, deep, enters=True, sort=False):
1333 + if isinstance(root, IterableUserDict):
1334 + out.write('{')
1335 +
1336 + if enters:
1337 + out.write('\n')
1338 +
1339 + isa = root.pop('isa', '')
1340 +
1341 + if isa != '': # keep the isa in the first spot
1342 + if enters:
1343 + out.write('\t' + deep)
1344 +
1345 + out.write('isa = ')
1346 + self._printNewXCodeFormat(out, isa, '\t' + deep, enters=enters)
1347 + out.write(';')
1348 +
1349 + if enters:
1350 + out.write('\n')
1351 + else:
1352 + out.write(' ')
1353 +
1354 + for key in sorted(root.iterkeys()): # keep the same order as Apple.
1355 + if enters:
1356 + out.write('\t' + deep)
1357 +
1358 + if re.match(regex, key).group(0) == key:
1359 + out.write(key.encode("utf-8") + ' = ')
1360 + else:
1361 + out.write('"' + key.encode("utf-8") + '" = ')
1362 +
1363 + if key == 'objects':
1364 + out.write('{') # open the objects section
1365 +
1366 + if enters:
1367 + out.write('\n')
1368 + #root.remove('objects') # remove it to avoid problems
1369 +
1370 + sections = [
1371 + ('PBXBuildFile', False),
1372 + ('PBXCopyFilesBuildPhase', True),
1373 + ('PBXFileReference', False),
1374 + ('PBXFrameworksBuildPhase', True),
1375 + ('PBXGroup', True),
1376 + ('PBXAggregateTarget', True),
1377 + ('PBXNativeTarget', True),
1378 + ('PBXProject', True),
1379 + ('PBXResourcesBuildPhase', True),
1380 + ('PBXShellScriptBuildPhase', True),
1381 + ('PBXSourcesBuildPhase', True),
1382 + ('XCBuildConfiguration', True),
1383 + ('XCConfigurationList', True),
1384 + ('PBXTargetDependency', True),
1385 + ('PBXVariantGroup', True),
1386 + ('PBXReferenceProxy', True),
1387 + ('PBXContainerItemProxy', True),
1388 + ('XCVersionGroup', True)]
1389 +
1390 + for section in sections: # iterate over the sections
1391 + if self.sections.get(section[0]) is None:
1392 + continue
1393 +
1394 + out.write('\n/* Begin %s section */' % section[0].encode("utf-8"))
1395 + self.sections.get(section[0]).sort(cmp=lambda x, y: cmp(x[0], y[0]))
1396 +
1397 + if sort and section[0] == 'PBXGroup':
1398 + for entry in self.sections.get(section[0]):
1399 + entry[1]['children'] = sorted(entry[1]['children'],
1400 + key=lambda x: self.uuids[x].encode("utf-8"))
1401 +
1402 + for pair in self.sections.get(section[0]):
1403 + key = pair[0]
1404 + value = pair[1]
1405 + out.write('\n')
1406 +
1407 + if enters:
1408 + out.write('\t\t' + deep)
1409 +
1410 + out.write(key.encode("utf-8"))
1411 +
1412 + if key in self.uuids:
1413 + out.write(" /* " + self.uuids[key].encode("utf-8") + " */")
1414 +
1415 + out.write(" = ")
1416 + self._printNewXCodeFormat(out, value, '\t\t' + deep, enters=section[1])
1417 + out.write(';')
1418 +
1419 + out.write('\n/* End %s section */\n' % section[0].encode("utf-8"))
1420 +
1421 + out.write(deep + '\t}') # close of the objects section
1422 + else:
1423 + self._printNewXCodeFormat(out, root[key], '\t' + deep, enters=enters)
1424 +
1425 + out.write(';')
1426 +
1427 + if enters:
1428 + out.write('\n')
1429 + else:
1430 + out.write(' ')
1431 +
1432 + root['isa'] = isa # restore the isa for further calls
1433 +
1434 + if enters:
1435 + out.write(deep)
1436 +
1437 + out.write('}')
1438 +
1439 + elif isinstance(root, UserList):
1440 + out.write('(')
1441 +
1442 + if enters:
1443 + out.write('\n')
1444 +
1445 + for value in root:
1446 + if enters:
1447 + out.write('\t' + deep)
1448 +
1449 + self._printNewXCodeFormat(out, value, '\t' + deep, enters=enters)
1450 + out.write(',')
1451 +
1452 + if enters:
1453 + out.write('\n')
1454 +
1455 + if enters:
1456 + out.write(deep)
1457 +
1458 + out.write(')')
1459 +
1460 + else:
1461 + if len(root) > 0 and re.match(regex, root).group(0) == root:
1462 + out.write(root.encode("utf-8"))
1463 + else:
1464 + out.write('"' + XcodeProject.addslashes(root.encode("utf-8")) + '"')
1465 +
1466 + if root in self.uuids:
1467 + out.write(" /* " + self.uuids[root].encode("utf-8") + " */")
1468 +
1469 + @classmethod
1470 + def Load(cls, path, pure_python=False):
1471 + if pure_python:
1472 + import openstep_parser as osp
1473 + tree = osp.OpenStepDecoder.ParseFromFile(open(path, 'r'))
1474 + else:
1475 + cls.plutil_path = os.path.join(os.path.split(__file__)[0], 'plutil')
1476 +
1477 + if not os.path.isfile(XcodeProject.plutil_path):
1478 + cls.plutil_path = 'plutil'
1479 +
1480 + # load project by converting to xml and then convert that using plistlib
1481 + p = subprocess.Popen([XcodeProject.plutil_path, '-convert', 'xml1', '-o', '-', path], stdout=subprocess.PIPE)
1482 + stdout, stderr = p.communicate()
1483 +
1484 + # If the plist was malformed, return code will be non-zero
1485 + if p.returncode != 0:
1486 + print stdout
1487 + return None
1488 +
1489 + tree = plistlib.readPlistFromString(stdout)
1490 +
1491 + return XcodeProject(tree, path)
1492 +
1493 + @classmethod
1494 + def LoadFromXML(cls, path):
1495 + tree = plistlib.readPlist(path)
1496 + return XcodeProject(tree, path)
1497 +
1498 +
1499 +# The code below was adapted from plistlib.py.
1500 +
1501 +class PBXWriter(plistlib.PlistWriter):
1502 + def writeValue(self, value):
1503 + if isinstance(value, (PBXList, PBXDict)):
1504 + plistlib.PlistWriter.writeValue(self, value.data)
1505 + else:
1506 + plistlib.PlistWriter.writeValue(self, value)
1507 +
1508 + def simpleElement(self, element, value=None):
1509 + """
1510 + We have to override this method to deal with Unicode text correctly.
1511 + Non-ascii characters have to get encoded as character references.
1512 + """
1513 + if value is not None:
1514 + value = _escapeAndEncode(value)
1515 + self.writeln("<%s>%s</%s>" % (element, value, element))
1516 + else:
1517 + self.writeln("<%s/>" % element)
1518 +
1519 +
1520 +# Regex to find any control chars, except for \t \n and \r
1521 +_controlCharPat = re.compile(
1522 + r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f"
1523 + r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]")
1524 +
1525 +
1526 +def _escapeAndEncode(text):
1527 + m = _controlCharPat.search(text)
1528 + if m is not None:
1529 + raise ValueError("strings can't contains control characters; "
1530 + "use plistlib.Data instead")
1531 + text = text.replace("\r\n", "\n") # convert DOS line endings
1532 + text = text.replace("\r", "\n") # convert Mac line endings
1533 + text = text.replace("&", "&amp;") # escape '&'
1534 + text = text.replace("<", "&lt;") # escape '<'
1535 + text = text.replace(">", "&gt;") # escape '>'
1536 + return text.encode("ascii", "xmlcharrefreplace") # encode as ascii with xml character references
No preview for this file type
1 +import os
2 +
3 +import commands
4 +
5 +
6 +buildProjName = ''
7 +targetName = ''
8 +import shutil
9 +import os
10 +
11 +def buildProj():
12 +
13 + if buildProjName == '':
14 + print('buildProjName is not define')
15 +
16 + else:
17 + #build project
18 + print('start build proj')
19 + commands.getstatusoutput('xcodebuild -project ' + buildProjName + '.xcodeproj')
20 + releaseDir = os.path.abspath('.') + '/Release'
21 + if not os.path.exists(releaseDir):
22 + os.mkdir(releaseDir)
23 +
24 + ipaPath = releaseDir + '/' + buildProjName + '-Release.ipa'
25 + buildPath = os.path.abspath('.') + '/build'
26 + if os.path.exists(ipaPath):
27 + os.remove(ipaPath)
28 +
29 + resultStr = commands.getstatusoutput('xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/' + targetName + '.app -o ' +ipaPath)
30 + #print(resultStr)
31 +
32 + if os.path.exists(buildPath):
33 + shutil.rmtree(buildPath)
34 +
No preview for this file type
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
33 <string>1</string> 33 <string>1</string>
34 <key>LSRequiresIPhoneOS</key> 34 <key>LSRequiresIPhoneOS</key>
35 <true/> 35 <true/>
36 + <key>NSAppTransportSecurity</key>
37 + <dict>
38 + <key>NSAllowsArbitraryLoads</key>
39 + <true/>
40 + </dict>
36 <key>UILaunchStoryboardName</key> 41 <key>UILaunchStoryboardName</key>
37 <string>LaunchScreen</string> 42 <string>LaunchScreen</string>
38 <key>UIMainStoryboardFile</key> 43 <key>UIMainStoryboardFile</key>
......
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>CFBundleDevelopmentRegion</key>
6 - <string>en</string>
7 - <key>CFBundleExecutable</key>
8 - <string>$(EXECUTABLE_NAME)</string>
9 - <key>CFBundleIdentifier</key>
10 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 - <key>CFBundleInfoDictionaryVersion</key>
12 - <string>6.0</string>
13 - <key>CFBundleName</key>
14 - <string>$(PRODUCT_NAME)</string>
15 - <key>CFBundlePackageType</key>
16 - <string>APPL</string>
17 - <key>CFBundleShortVersionString</key>
18 - <string>1.0</string>
19 - <key>CFBundleSignature</key>
20 - <string>????</string>
21 - <key>CFBundleURLTypes</key>
22 - <array>
23 - <dict>
24 - <key>CFBundleTypeRole</key>
25 - <string>Editor</string>
26 - <key>CFBundleURLSchemes</key>
27 - <array>
28 - <string>com.youai.sdk</string>
29 - </array>
30 - </dict>
31 - </array>
32 - <key>CFBundleVersion</key>
33 - <string>1</string>
34 - <key>LSApplicationQueriesSchemes</key>
35 - <array>
36 - <string>mqq</string>
37 - </array>
38 - <key>LSRequiresIPhoneOS</key>
39 - <true/>
40 - <key>NSAppTransportSecurity</key>
41 - <dict>
42 - <key>NSAllowsArbitraryLoads</key>
43 - <true/>
44 - </dict>
45 - <key>UILaunchStoryboardName</key>
46 - <string>LaunchScreen</string>
47 - <key>UIMainStoryboardFile</key>
48 - <string>Main</string>
49 - <key>UIRequiredDeviceCapabilities</key>
50 - <array>
51 - <string>armv7</string>
52 - </array>
53 - <key>UISupportedInterfaceOrientations</key>
54 - <array>
55 - <string>UIInterfaceOrientationLandscapeLeft</string>
56 - <string>UIInterfaceOrientationLandscapeRight</string>
57 - </array>
58 -</dict>
59 -</plist>
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>LSApplicationQueriesSchemes</key>
6 - <array>
7 - <string>mqq</string>
8 - </array>
9 -
10 - <key>NSAppTransportSecurity</key>
11 - <dict>
12 - <key>NSAllowsArbitraryLoads</key>
13 - <true/>
14 - </dict>
15 -
16 -</dict>
17 -</plist>
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>StringsTable</key>
6 - <string>Root</string>
7 - <key>PreferenceSpecifiers</key>
8 - <array>
9 - <dict>
10 - <key>Type</key>
11 - <string>PSGroupSpecifier</string>
12 - <key>Title</key>
13 - <string>Group</string>
14 - </dict>
15 - <dict>
16 - <key>Type</key>
17 - <string>PSTextFieldSpecifier</string>
18 - <key>Title</key>
19 - <string>Name</string>
20 - <key>Key</key>
21 - <string>name_preference</string>
22 - <key>DefaultValue</key>
23 - <string></string>
24 - <key>IsSecure</key>
25 - <false/>
26 - <key>KeyboardType</key>
27 - <string>Alphabet</string>
28 - <key>AutocapitalizationType</key>
29 - <string>None</string>
30 - <key>AutocorrectionType</key>
31 - <string>No</string>
32 - </dict>
33 - <dict>
34 - <key>Type</key>
35 - <string>PSToggleSwitchSpecifier</string>
36 - <key>Title</key>
37 - <string>Enabled</string>
38 - <key>Key</key>
39 - <string>enabled_preference</string>
40 - <key>DefaultValue</key>
41 - <true/>
42 - </dict>
43 - <dict>
44 - <key>Type</key>
45 - <string>PSSliderSpecifier</string>
46 - <key>Key</key>
47 - <string>slider_preference</string>
48 - <key>DefaultValue</key>
49 - <real>0.5</real>
50 - <key>MinimumValue</key>
51 - <integer>0</integer>
52 - <key>MaximumValue</key>
53 - <integer>1</integer>
54 - <key>MinimumValueImage</key>
55 - <string></string>
56 - <key>MaximumValueImage</key>
57 - <string></string>
58 - </dict>
59 - </array>
60 -</dict>
61 -</plist>
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_350/SDK/JWSDK.bundle/en.lproj/Root.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_350/SDK/JWSDK.bundle/en.lproj/Root.strings and /dev/null differ
......
1 -//
2 -// DYUserAccountModel.h
3 -// JWSDKDemo
4 -//
5 -// Created by DovYoung on 16/9/26.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -
11 -@interface DYExtraMessageModel : UIView
12 -
13 -@property (nonatomic, copy) NSString *serverid; //!< 服务器ID(非常重要)
14 -@property (nonatomic, copy) NSString *roleid; //!< 角色id
15 -@property (nonatomic, copy) NSString *rolename; //!< 角色名字
16 -@property (nonatomic, copy) NSString *rolelevel; //!< 角色等级
17 -@property (nonatomic, copy) NSString *scenetype; //!< 场景类型
18 -@property (nonatomic, copy) NSString *zonename; //!< 服务区名字
19 -@property (nonatomic, copy) NSString *balance; //!< 游戏币金额
20 -@property (nonatomic, copy) NSString *vip; //!< 玩家vip等级
21 -@property (nonatomic, copy) NSString *partyname; //!< 用户所属帮派
22 -
23 -/**
24 - * 根据字典创建模型
25 - *
26 - * @param dic 字典
27 - *
28 - * @return 模型
29 - */
30 -- (instancetype)initWithDic:(NSDictionary *)dic;
31 -
32 -@end
1 -//
2 -// DYInitModel.h
3 -// JWSDKDemo
4 -//
5 -// Created by DovYoung on 16/9/21.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface DYInitModel : NSObject
12 -
13 -@property (nonatomic, copy) NSString *url; //!< 应用更新地址
14 -@property (nonatomic, copy) NSString *ver; //!< 版本号
15 -@property (nonatomic, copy) NSString *isForce; //!< 是否强制更新
16 -@property (nonatomic, copy) NSString *msg; //!< 版本更新信息
17 -
18 -/**
19 - * 根据字典创建模型
20 - *
21 - * @param dic 字典
22 - *
23 - * @return 模型
24 - */
25 -- (instancetype)initWithDic:(NSDictionary *)dic;
26 -
27 -@end
1 -//
2 -// DYLoginModel.h
3 -// JWSDKDemo
4 -//
5 -// Created by DovYoung on 16/9/21.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface DYLoginDataModel : NSObject
12 -
13 -//@property (nonatomic, copy) NSString *username; //!< 用户名
14 -@property (nonatomic, copy) NSString *uid; //!< 用户id
15 -@property (nonatomic, copy) NSString *token; //!< 令牌
16 -@property (nonatomic, copy) NSString *timestamp; //!< 时间戳
17 -
18 -- (instancetype)initWithDic:(NSDictionary *)dic;
19 -
20 -+ (instancetype)loginDataModelWithDic:(NSDictionary *)dic;
21 -
22 -@end
1 -//
2 -// LoginViewController.h
3 -// JWSDKDemo
4 -//
5 -// Created by DovYoung on 16/9/19.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -#import "DYLoginDataModel.h"
11 -
12 -// 登录回调协议
13 -@protocol DYLoginViewControllerDelegate <NSObject>
14 -
15 -@required
16 -/**
17 - * 成功回调
18 - */
19 -- (void)loginSuccessData:(DYLoginDataModel *)dataModel;
20 -/**
21 - * 失败回调
22 - */
23 -- (void)loginFailStatus:(NSString *)status info:(NSString *)info;
24 -
25 -@end
26 -
27 -@interface DYLoginViewController : UIViewController
28 -
29 -@property(nonatomic,weak) id<DYLoginViewControllerDelegate> delegate; //!< 登录回调的代理
30 -
31 -@property (nonatomic, strong) UIViewController *viewController;
32 -
33 -/**
34 - * 自动登录
35 - */
36 -- (void)autoLogin;
37 -
38 -@end
1 -//
2 -// DYOrderModel.h
3 -// JWSDKDemo
4 -//
5 -// Created by DovYoung on 16/10/17.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface DYOrderModel : NSObject
12 -
13 -//需要传
14 -@property (nonatomic, copy) NSString *serverid; //!< 服务器id(非常重要)
15 -@property (nonatomic, copy) NSString *pmid; //!< 支付id
16 -@property (nonatomic, copy) NSString *gameorderid; //!< 订单id
17 -@property (nonatomic, copy) NSString *amount; //!< 金额
18 -@property (nonatomic, copy) NSString *gameextinfo; //!< 额外信息
19 -@property (nonatomic, copy) NSString *proname; //!< 商品名字
20 -
21 -@property (nonatomic, copy) NSString *roleid; //!< 角色id
22 -@property (nonatomic, copy) NSString *rolename; //!< 角色名字
23 -@property (nonatomic, copy) NSString *rolelevel; //!< 角色等级
24 -
25 -@property (nonatomic, copy) NSString *proID; //!< 商品id (ituns connect上注册的)
26 -@property (nonatomic, assign) NSInteger quantity; //!< 购买数量(扩展字段 目前为1)
27 -
28 -@end
1 -//
2 -// DYStoreKitController.h
3 -// StoreKit
4 -//
5 -// Created by DovYoung on 16/10/17.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -@class DYOrderModel,DYStoreKitController,DYSQLiteModel;
11 -
12 -@protocol DYStoreKitControllerDelegate <NSObject>
13 -
14 -//成功回调
15 -- (void)paymentHandler:(NSString *)info;
16 -//失败回调
17 -
18 -
19 -@end
20 -
21 -
22 -@interface DYStoreKitController : UIViewController
23 -
24 -@property(nonatomic,weak) id<DYStoreKitControllerDelegate> delegate;
25 -
26 -/**
27 - 单例方法
28 -
29 - @return 单例对象
30 - */
31 -+ (instancetype)sharedInstance;
32 -
33 -
34 -/**
35 - 开始内购
36 -
37 - @param order 内购订单信息
38 - */
39 -- (void)startProductRequestWithOrder:(DYOrderModel *)order;
40 -
41 -/**
42 - 重新验签
43 -
44 - @param model 验签模型
45 - */
46 -- (void)reveifyWithModel:(DYSQLiteModel *)model;
47 -
48 -@end
1 -//
2 -// JWApi.h
3 -// JWSDKDemo
4 -//
5 -// Created by DovYoung on 16/9/21.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -#import "DYInitModel.h"
11 -#import "DYExtraMessageModel.h"
12 -#import "DYOrderModel.h"
13 -
14 -@interface JWApi : NSObject
15 -
16 -/**
17 - * 闪屏
18 - */
19 -+ (void)splashScreen;
20 -
21 -/**
22 - * 初始化
23 - *
24 - * @param gid 游戏id 必须
25 - * @param appkey 游戏key 必须
26 - * @param agent 渠道号 可传固定值 appstore
27 - */
28 -+ (void)initializeWithGid:(NSString *)gid
29 - appkey:(NSString *)appkey
30 - agentid:(NSString *)agentid
31 - pmver:(NSString *)pmver
32 - handler:(void(^)(int status, NSString *info,DYInitModel *dataInit))handler;
33 -
34 -/**
35 - * 弹出登录
36 - *
37 - * @param delegate 代理
38 - * @param serverid 游戏区服id 游戏方调起登录时,如获取不到区服,则传空即可
39 - */
40 -+ (void)presentLoginViewControllerWithDelegate:(id)delegate serverid:(NSString *)serverid;
41 -
42 -
43 -/**
44 - * 额外信息收集
45 - *
46 - * @param message 信息模型
47 - * @param handler 收集回调
48 - */
49 -+ (void)collectUserExtraMessageWithExtraMessage:(DYExtraMessageModel *)message handler:(void(^)(NSString *status))handler;
50 -
51 -
52 -/**
53 - * 支付接口
54 - *
55 - * @param delegate 代理
56 - * @param model 含有支付所需信息的模型
57 - */
58 -+ (void)paymentWithDelegate:(id)delegate
59 - model:(DYOrderModel *)order;
60 -
61 -
62 -/**
63 - * 退出程序
64 - */
65 -+ (void)exitApplication;
66 -
67 -@end
1 -//
2 -// JWSDK.h
3 -// JWSDK
4 -//
5 -// Created by DovYoung on 16/9/23.
6 -// Copyright © 2016年 DovYoung. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -
11 -//! Project version number for JWSDK.
12 -FOUNDATION_EXPORT double JWSDKVersionNumber;
13 -
14 -//! Project version string for JWSDK.
15 -FOUNDATION_EXPORT const unsigned char JWSDKVersionString[];
16 -
17 -// In this header, you should import all the public headers of your framework using statements like #import <JWSDK/PublicHeader.h>
18 -
19 -#import <JWSDK/JWApi.h>
20 -
21 -//登录
22 -#import <JWSDK/DYLoginViewController.h>
23 -#import <JWSDK/DYLoginDataModel.h>
24 -//初始化
25 -#import <JWSDK/DYInitModel.h>
26 -//额外信息
27 -#import <JWSDK/DYExtraMessageModel.h>
28 -//内购
29 -#import <JWSDK/DYStoreKitController.h>
30 -#import <JWSDK/DYOrderModel.h>
1 -framework module JWSDK {
2 - umbrella header "JWSDK.h"
3 -
4 - export *
5 - module * { export * }
6 -}
1 -
2 -//
3 -// PPInterface.h
4 -// PoolSdk
5 -//
6 -// Created by winFan on 11/23/15.
7 -// Copyright (c) 2015 winFan. All rights reserved.
8 -//
9 -
10 -#import <PoolSdk/PoolSdk2.h>
11 -#import <JWSDK/JWSDK.h>
12 -@interface SDKInterface : Interface<DYLoginViewControllerDelegate, DYStoreKitControllerDelegate>
13 -
14 -@end
1 -//
2 -// UnionInterface.m
3 -// PoolSdk
4 -//
5 -// Created by winFan on 11/23/15.
6 -// Copyright (c) 2015 winFan. All rights reserved.
7 -//
8 -#include "SDKInterface.h"
9 -#import <UIKit/UIKit.h>
10 -#import <JWSDK/JWSDK.h>
11 -
12 -@implementation SDKInterface : Interface
13 -
14 -/**
15 - 初始化SDK
16 -*/
17 -- (void)SDKinit:(UIViewController *) control
18 -{
19 - //必须继承
20 - [super SDKinit:control];
21 -
22 - [PoolConfig getInstance];
23 -
24 -
25 - //在需要闪屏的地方调用闪屏接口
26 - [JWApi splashScreen];
27 -
28 - NSString* gid = [[PoolConfig getInstance]getValueByKey:@"sdkGid"];
29 - NSString* appkey = [[PoolConfig getInstance]getValueByKey:@"sdkAppkey"];
30 - NSString* agentid = [[PoolConfig getInstance]getValueByKey:@"sdkAgentid"];
31 - NSString* pmver = [[PoolConfig getInstance]getValueByKey:@"sdkPmver"];
32 -
33 -// gid = @"104";
34 -// appkey = @"0694e5d5ab2e4864aa1f1c48d0d31cf1";
35 -// agentid = @"appstore";
36 -// pmver = @"101";
37 -
38 - //请在程序加载完毕的时候调用如下接口初始化
39 - [JWApi initializeWithGid:gid
40 - appkey:appkey
41 - agentid:agentid
42 - pmver:pmver
43 - handler:^(int status, NSString *info, DYInitModel *dataInit) {
44 - NSLog(@"status = %d, info = %@",status, info);
45 - }];
46 -
47 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationInitSDK notiName:@"InitSuccess" statusCode:POOLSDK_NO_ERROR description:@"initSuccess" extendData:nil];
48 -}
49 -
50 -/**
51 - 登录SDK
52 - */
53 -- (void)SDKloginSDK
54 -{
55 - NSLog(@"调用了LoginSDK");
56 - //显示登录界面
57 - [JWApi presentLoginViewControllerWithDelegate:self serverid:@""];
58 -}
59 -
60 -//实现如下的代理方法
61 -/**
62 - * 登录成功的回调
63 - *
64 - * @param dataModel 回到模型
65 - */
66 -- (void)loginSuccessData:(DYLoginDataModel *)dataModel {
67 -
68 - NSLog(@"sdk loginSuccessData");
69 - NSLog(@"uid = %@",dataModel.uid);
70 - NSLog(@"token = %@",dataModel.token);
71 - NSLog(@"time = %@",dataModel.timestamp);
72 -
73 - PoolLoginInfo *loginInfo = [[PoolLoginInfo alloc]init];
74 - loginInfo.openId = dataModel.uid;//渠道userId
75 - loginInfo.timestamp = dataModel.timestamp;
76 - loginInfo.sign = dataModel.token;//渠道SDK的token
77 - dispatch_async(dispatch_get_global_queue(0, 0), ^{
78 - [[PoolChecker getInstance]startCheck:loginInfo];//登录验证请求
79 - });
80 -}
81 -
82 -/**
83 - * 登录失败的回调
84 - *
85 - * @param status 失败状态码
86 - * @param info 失败的描述
87 - */
88 -- (void)loginFailStatus:(NSString *)status info:(NSString *)info {
89 - NSLog(@"sdk loginFailStatus failInfo = %@",info);
90 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationLogin notiName:@"loginFail" statusCode:POOLSDK_ERROR_LOGIN_FAILED description:@"loginFail" extendData:info];
91 -}
92 -
93 -- (void)SDKreport:(PoolReportInfo *)reportInfo
94 -{
95 - NSLog(@"reportInfo");
96 - if ([REPORT_CREATEROLE isEqualToString:[reportInfo reportType]]) {
97 - DYExtraMessageModel *model = [[DYExtraMessageModel alloc] init];
98 - model.serverid = [reportInfo serverId];
99 - model.rolelevel = [reportInfo playerLevel];
100 - model.rolename = [reportInfo playerName];
101 - model.zonename = [reportInfo serverName];
102 - model.balance = [NSString stringWithFormat:@"%@", [reportInfo diamond]];
103 - model.vip = [reportInfo vipLevel];
104 - model.scenetype = @"createRole";
105 - model.partyname = [reportInfo partyName];//@"无帮派";
106 - model.roleid = [reportInfo playerId];
107 -
108 - //调用接口,将模型数据传入,通过status查看回调信息
109 - [JWApi collectUserExtraMessageWithExtraMessage:model handler:^(NSString *status) {
110 - NSLog(@"%@",status);
111 - }];
112 -
113 - }else if ([[reportInfo reportType] isEqualToString:REPORT_ENTER]) {
114 - DYExtraMessageModel *model = [[DYExtraMessageModel alloc] init];
115 - model.serverid = [reportInfo serverId];
116 - model.rolelevel = [reportInfo playerLevel];
117 - model.rolename = [reportInfo playerName];
118 - model.zonename = [reportInfo serverName];
119 - model.balance = [NSString stringWithFormat:@"%@", [reportInfo diamond]];
120 - model.vip = [reportInfo vipLevel];
121 - model.scenetype = @"enterServer";
122 - model.partyname = [reportInfo partyName];//@"无帮派";
123 - model.roleid = [reportInfo playerId];
124 -
125 - //调用接口,将模型数据传入,通过status查看回调信息
126 - [JWApi collectUserExtraMessageWithExtraMessage:model handler:^(NSString *status) {
127 - NSLog(@"%@",status);
128 - }];
129 - }else if ([[reportInfo reportType] isEqualToString:REPORT_ROLEUPGRADE]) {
130 - DYExtraMessageModel *model = [[DYExtraMessageModel alloc] init];
131 - model.serverid = [reportInfo serverId];
132 - model.rolelevel = [reportInfo playerLevel];
133 - model.rolename = [reportInfo playerName];
134 - model.zonename = [reportInfo serverName];
135 - model.balance = [NSString stringWithFormat:@"%@", [reportInfo diamond]];
136 - model.vip = [reportInfo vipLevel];
137 - model.scenetype = @"levelUp";
138 - model.partyname = [reportInfo partyName];//@"无帮派";
139 - model.roleid = [reportInfo playerId];
140 -
141 - //调用接口,将模型数据传入,通过status查看回调信息
142 - [JWApi collectUserExtraMessageWithExtraMessage:model handler:^(NSString *status) {
143 - NSLog(@"%@",status);
144 - }];
145 - }
146 -}
147 -
148 -
149 -/**
150 - SDK
151 - */
152 -- (void)SDKexitSDK
153 -{
154 - [JWApi exitApplication];
155 -}
156 -
157 -- (void)receivePayMessage : (NSNotification *)notification;
158 -{
159 - NSString *order_id = [notification object];
160 - NSLog(@"订单ID:%@", order_id);
161 -}
162 -
163 -/**
164 - @return 商品名称
165 - */
166 -- (NSString*)getProductNameByAmount:(NSString*)products amount:(NSString*)amount
167 -{
168 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
169 - if(jsonData){
170 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
171 - if(productList){
172 - NSEnumerator* keysList = [productList keyEnumerator];
173 - id keyValue;
174 - while (keyValue = [keysList nextObject])
175 - {
176 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
177 - if(appleAmount.intValue == amount.intValue){
178 - NSString* productName = [[productList objectForKey:keyValue] objectForKey:@"name"];
179 - return productName;
180 - }
181 - }
182 - }
183 - }
184 - NSLog(@"get product name error amount:%@",amount);
185 - return @"元宝";
186 -}
187 -
188 -/**
189 - @return 商品ID
190 - */
191 -- (NSString*)getProductIdByAmount:(NSString*)products amount:(NSString*)amount
192 -{
193 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
194 - if(jsonData){
195 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
196 - if(productList){
197 - NSEnumerator* keysList = [productList keyEnumerator];
198 - id keyValue;
199 - while (keyValue = [keysList nextObject])
200 - {
201 - NSLog(@"i found %@",keyValue);
202 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
203 - NSLog(@"appleAmount:%@ amount:%@",appleAmount,amount);
204 - if(appleAmount.intValue == amount.intValue){
205 - return keyValue;
206 - }
207 - }
208 - }
209 - }
210 - return @"unknow";
211 -}
212 -
213 -- (void)receiveCreateOrder:(NSNotification *)notification
214 -{
215 - NSLog(@"创建订单成功");
216 - PoolPayInfo *payInfo = [notification object];
217 -
218 - NSString *openId = [payInfo playerId];
219 - NSString *myamount = [payInfo postAmount];
220 - NSString *queryId = [payInfo queryId];
221 - NSString *productId = [self getProductIdByAmount:payInfo.products amount:myamount];
222 -
223 - NSLog(@"receiveCreateOrder openid %@ amount %@ queryId %@, product@d %@", openId, myamount, queryId, productId);
224 -
225 -
226 - DYOrderModel *order = [[DYOrderModel alloc] init];
227 - //将proID设置为制定的ProID
228 - order.serverid = [payInfo serverId]; //服务器id(必传)
229 - //order.pmid; //!< 支付id
230 - order.gameorderid = [payInfo queryId]; //游戏方订单id (必填)
231 - order.amount = [payInfo postAmount]; //金额 (必填)
232 - order.gameextinfo = [payInfo queryId]; //额外信息
233 - order.proname = [payInfo productName]; //商品名称
234 -
235 - order.roleid = [payInfo playerId]; //角色id (必填)
236 - order.rolename = [payInfo playerName]; //角色名称
237 - order.rolelevel = [payInfo playerLevel]; //角色等级
238 -
239 - order.proID = productId; //商品id (必填)
240 - //order.quantity = 1;
241 -
242 - [JWApi paymentWithDelegate:self model:order];
243 -}
244 -
245 -#pragma mark - DYStoreKitControllerDelegate
246 -//内购支付回调
247 --(void)paymentHandler:(NSString *)info {
248 - NSLog(@"payment info = %@",info);
249 -}
250 -
251 --(NSString*)getCurrentTimestamp{
252 - // 时间戳转时间
253 - NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
254 - NSString* timeStr = [[NSString alloc]initWithFormat:@"%.f",interval];
255 - return timeStr;
256 -}
257 -
258 -@end
1 -{"sdkAgentid": "appstore", "sdkAppkey": "0694e5d5ab2e4864aa1f1c48d0d31cf1", "payorderurl": "http://183.57.76.181:9020/paycheck/create", "usertype": 190, "sdkSimpleName": "sanwuling_ios", "gamechannelid": "", "custom": "{}", "sdkVersionCode": "V1_8", "sdkGid": "104", "sdkPmver": "101", "loginCheckUrl": "http://183.57.76.181:9010/logincheck/check", "appScheme": "com.yuping.qyt", "c2": "", "c1": "", "paycheckurl": "http://183.57.76.181:9020/paycheck/confirm", "gameSimpleName": "fytx_test"}
...\ No newline at end of file ...\ No newline at end of file
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>CFBundleDevelopmentRegion</key>
6 - <string>en</string>
7 - <key>CFBundleExecutable</key>
8 - <string>$(EXECUTABLE_NAME)</string>
9 - <key>CFBundleIdentifier</key>
10 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 - <key>CFBundleInfoDictionaryVersion</key>
12 - <string>6.0</string>
13 - <key>CFBundleName</key>
14 - <string>$(PRODUCT_NAME)</string>
15 - <key>CFBundlePackageType</key>
16 - <string>APPL</string>
17 - <key>CFBundleShortVersionString</key>
18 - <string>1.0</string>
19 - <key>CFBundleSignature</key>
20 - <string>????</string>
21 - <key>CFBundleURLTypes</key>
22 - <array>
23 - <dict>
24 - <key>CFBundleTypeRole</key>
25 - <string>Editor</string>
26 - <key>CFBundleURLName</key>
27 - <string>xf_game_alipay</string>
28 - <key>CFBundleURLSchemes</key>
29 - <array>
30 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
31 - </array>
32 - </dict>
33 - <dict>
34 - <key>CFBundleTypeRole</key>
35 - <string>Editor</string>
36 - <key>CFBundleURLName</key>
37 - <string>xf_game_wechat</string>
38 - <key>CFBundleURLSchemes</key>
39 - <array>
40 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
41 - </array>
42 - </dict>
43 - <dict>
44 - <key>CFBundleTypeRole</key>
45 - <string>Editor</string>
46 - <key>CFBundleURLName</key>
47 - <string>xf_game_union</string>
48 - <key>CFBundleURLSchemes</key>
49 - <array>
50 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
51 - </array>
52 - </dict>
53 - </array>
54 - <key>CFBundleVersion</key>
55 - <string>1</string>
56 - <key>LSApplicationQueriesSchemes</key>
57 - <array>
58 - <string>alipay</string>
59 - <string>safepay</string>
60 - <string>weixin</string>
61 - <string>wechat</string>
62 - <string>uppaysdk</string>
63 - <string>uppaywallet</string>
64 - <string>uppayx1</string>
65 - <string>uppayx2</string>
66 - <string>uppayx3</string>
67 - </array>
68 - <key>LSRequiresIPhoneOS</key>
69 - <true/>
70 - <key>NSAppTransportSecurity</key>
71 - <dict>
72 - <key>NSAllowsArbitraryLoads</key>
73 - <true/>
74 - </dict>
75 - <key>UILaunchStoryboardName</key>
76 - <string>LaunchScreen</string>
77 - <key>UIMainStoryboardFile</key>
78 - <string>Main</string>
79 - <key>UIRequiredDeviceCapabilities</key>
80 - <array>
81 - <string>armv7</string>
82 - </array>
83 - <key>UISupportedInterfaceOrientations</key>
84 - <array>
85 - <string>UIInterfaceOrientationLandscapeLeft</string>
86 - <string>UIInterfaceOrientationLandscapeRight</string>
87 - </array>
88 -</dict>
89 -</plist>
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>LSApplicationQueriesSchemes</key>
6 - <array>
7 - <string>alipay</string>
8 - <string>safepay</string>
9 - <string>weixin</string>
10 - <string>wechat</string>
11 - <string>uppaysdk</string>
12 - <string>uppaywallet</string>
13 - <string>uppayx1</string>
14 - <string>uppayx2</string>
15 - <string>uppayx3</string>
16 - </array>
17 - <key>CFBundleURLTypes</key>
18 - <array>
19 - <dict>
20 - <key>CFBundleTypeRole</key>
21 - <string>Editor</string>
22 - <key>CFBundleURLName</key>
23 - <string>xf_game_alipay</string>
24 - <key>CFBundleURLSchemes</key>
25 - <array>
26 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
27 - </array>
28 - </dict>
29 - <dict>
30 - <key>CFBundleTypeRole</key>
31 - <string>Editor</string>
32 - <key>CFBundleURLName</key>
33 - <string>xf_game_wechat</string>
34 - <key>CFBundleURLSchemes</key>
35 - <array>
36 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
37 - </array>
38 - </dict>
39 - <dict>
40 - <key>CFBundleTypeRole</key>
41 - <string>Editor</string>
42 - <key>CFBundleURLName</key>
43 - <string>xf_game_union</string>
44 - <key>CFBundleURLSchemes</key>
45 - <array>
46 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
47 - </array>
48 - </dict>
49 - </array>
50 - <key>NSAppTransportSecurity</key>
51 - <dict>
52 - <key>NSAllowsArbitraryLoads</key>
53 - <true/>
54 - </dict>
55 -</dict>
56 -</plist>
1 -//
2 -// XFPayment.h
3 -// XFPayment
4 -//
5 -// Created by zhou on 2017/3/7.
6 -// Copyright © 2017年 jett.yu. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -#import <UIKit/UIKit.h>
11 -
12 -typedef enum : NSUInteger {
13 - /**
14 - * 支付结果
15 - */
16 - PayResultNumSuccess,//支付成功
17 - PayResultNumFailed,//支付失败
18 - PayResultNumCancel,//支付取消
19 - PayResultNumRestart,//重新发起支付
20 -
21 -
22 -} PayResultNum;
23 -
24 -
25 -@protocol XFPayDelegate <NSObject>
26 -
27 -@optional
28 -/**
29 - 支付回调
30 -
31 - @param result 支付结果
32 - @param data 支付回调参数
33 - */
34 --(void)ApplePayResult:(PayResultNum)result resultData:(NSDictionary *)data;
35 -
36 -@end
37 -
38 -@interface XFPayment : NSObject
39 -
40 -+(XFPayment *)sharedInstance;
41 -
42 -
43 -@property (nonatomic, weak) id<XFPayDelegate> XFpayDelegate;
44 -
45 -
46 -/**
47 - 支付SDK初始化
48 -
49 - @param appid appid
50 - @param packageid packageid
51 - @param appkey 通用key
52 - */
53 --(void)initWithAppid:(NSString *)appid andPackageId:(NSString *)packageid andAppKey:(NSString *)appkey;
54 -
55 -/**
56 - 发起支付方法
57 -
58 - @param dict 支付参数
59 -
60 - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
61 - [dict setValue:@"123456" forKey:@"openId"]; //游戏内唯一ID
62 - [dict setValue:@"6" forKey:@"money"]; //支付金额
63 - [dict setValue:@"xfpay" forKey:@"extra"]; //额外参数
64 - [dict setValue:@"com.xfpay.test.6" forKey:@"orderid"]; //苹果支付id
65 - [dict setValue:@"100元宝" forKey:@"pro_info"]; //商品描述
66 -
67 -
68 - */
69 --(void)payWithOrderInfo:(NSDictionary *)dict;
70 -
71 -
72 -
73 -/**
74 - AppDelegate.mm中实现此协议支付回调
75 -
76 - (用于检测支付宝,银联支付状态,务必实现)
77 -
78 - @param application application
79 - @param url url
80 - */
81 --(void)application:(UIApplication *)application openUrl:(NSURL *)url;
82 -
83 -
84 -@end
1 -
2 -//
3 -// PPInterface.h
4 -// PoolSdk
5 -//
6 -// Created by winFan on 11/23/15.
7 -// Copyright (c) 2015 winFan. All rights reserved.
8 -//
9 -
10 -#import <PoolSdk/PoolSdk2.h>
11 -#import <XFLoginSDK/XFLoginViewSDK.h>
12 -#import <PaymentSDK/XFPayment.h>
13 -
14 -@interface SDKInterface : Interface<XFLoginViewSDKDelegate, XFPayDelegate>
15 -
16 -@end
1 -//
2 -// UnionInterface.m
3 -// PoolSdk
4 -//
5 -// Created by winFan on 11/23/15.
6 -// Copyright (c) 2015 winFan. All rights reserved.
7 -//
8 -#include "SDKInterface.h"
9 -#import <UIKit/UIKit.h>
10 -#import <XFLoginSDK/XFLoginViewSDK.h>
11 -#import <PaymentSDK/XFPayment.h>
12 -#import <XFTrackIO/XFTrackIO.h>
13 -
14 -@implementation SDKInterface : Interface
15 -
16 -NSString *_openId;
17 -NSString *_serverId;
18 -NSString *_serverName;
19 -NSString *_roleId;
20 -NSString *_roleName;
21 -
22 -/**
23 - 初始化SDK
24 -*/
25 -- (void)SDKinit:(UIViewController *) control
26 -{
27 - //必须继承
28 - [super SDKinit:control];
29 -
30 - [PoolConfig getInstance];
31 -
32 -
33 - _openId = nil;
34 - _serverId = nil;
35 - _serverName = nil;
36 - _roleId = nil;
37 - _roleName = nil;
38 -
39 - NSString* appId = [[PoolConfig getInstance]getValueByKey:@"sdkAppId"];
40 - NSString* packageId = [[PoolConfig getInstance]getValueByKey:@"sdkPackageId"];
41 - NSString* appKey = [[PoolConfig getInstance]getValueByKey:@"sdkAppKey"];
42 - NSString* reyunKey = [[PoolConfig getInstance]getValueByKey:@"sdkReyunKey"];
43 -
44 - [[XFPayment sharedInstance]
45 - initWithAppid:appId //应用id(三端通用)
46 - andPackageId:packageId //包id(三端通用)
47 - andAppKey:appKey];//应用key(三端通用)
48 -
49 - [[XFLoginViewSDK sharedInstance]
50 - initWithAPPId:appId //应用id(三端通用)
51 - andPackageId:packageId //包id(三端通用)
52 - andAppKey:appKey];//应用key(三端通用)
53 -
54 - [[XFTrackIO sharedInstance]
55 - initWithAppid:appId //应用id(三端通用)
56 - andPackageId:packageId //包id(三端通用)
57 - andAppKey:appKey //应用key(三端通用)
58 - andReyunKey:reyunKey];//热云key
59 -
60 - [[XFTrackIO sharedInstance] setLogPrint:YES];//是否显示日志,默认NO
61 -
62 - [[XFLoginViewSDK sharedInstance] setXFLoginDelegate:self];
63 -
64 - [[XFPayment sharedInstance] setXFpayDelegate:self];
65 -
66 -
67 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationInitSDK notiName:@"InitSuccess" statusCode:POOLSDK_NO_ERROR description:@"initSuccess" extendData:nil];
68 -
69 -}
70 -
71 --(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
72 - [[XFPayment sharedInstance] application:application openUrl:url];
73 - return YES;
74 -}
75 -
76 -//#ifdef __IPHONE_9_0
77 -//-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
78 -// [[XFPayment sharedInstance] application:app openUrl:url];
79 -// return YES;
80 -//}
81 -//#else
82 -- (BOOL)application:(UIApplication *)application
83 - openURL:(NSURL *)url
84 - sourceApplication:(NSString *)sourceApplication
85 - annotation:(id)annotation {
86 - [[XFPayment sharedInstance] application:application openUrl:url];
87 - return YES;
88 -}
89 -
90 -//#endif
91 -
92 --(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
93 -
94 -{
95 - return UIInterfaceOrientationMaskAll;
96 -
97 -}
98 -
99 -/**
100 - 登录SDK
101 - */
102 -- (void)SDKloginSDK
103 -{
104 - NSLog(@"调用了LoginSDK");
105 - [[XFLoginViewSDK sharedInstance] OnLogin];
106 -}
107 -
108 -#pragma mark - Login Delegate//返回登录ID和登录标识
109 --(void)SDKLoginSuccessWithData:(NSDictionary *)dic{
110 - NSLog(@"登录成功:%@",dic);//返回openId和token
111 -
112 - PoolLoginInfo *loginInfo = [[PoolLoginInfo alloc]init];
113 - loginInfo.openId = [dic objectForKey:@"openId"];//渠道userId
114 - loginInfo.timestamp = [self getCurrentTimestamp];
115 - loginInfo.sign = [dic objectForKey:@"token"];//渠道SDK的token
116 - dispatch_async(dispatch_get_global_queue(0, 0), ^{
117 - [[PoolChecker getInstance]startCheck:loginInfo];//登录验证请求
118 - });
119 -
120 - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
121 - [dict setValue:[dic objectForKey:@"openId"] forKey:@"openId"]; //帐号唯一ID
122 -
123 - [[XFTrackIO sharedInstance]
124 - startTrackWithType:XFTrackIOTypeAccountLogin
125 - andTrackData:dict];
126 -}
127 -
128 -
129 -- (void)SDKreport:(PoolReportInfo *)reportInfo
130 -{
131 - NSLog(@"reportInfo");
132 - if ([REPORT_CREATEROLE isEqualToString:[reportInfo reportType]]) {
133 -
134 - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
135 - [dict setValue:[reportInfo openId] forKey:@"openId"];//登录ID
136 - [dict setValue:[reportInfo serverId] forKey:@"serverId"];//服务器ID
137 - [dict setValue:[reportInfo serverName] forKey:@"serverName"];//服务器名称
138 - [dict setValue:[reportInfo playerId] forKey:@"roleId"];//角色ID
139 - [dict setValue:[reportInfo playerName] forKey:@"roleName"];//角色名称
140 -
141 - [[XFTrackIO sharedInstance]
142 - startTrackWithType:XFTrackIOTypeEnterGame
143 - andTrackData:dict];
144 - }else if ([[reportInfo reportType] isEqualToString:REPORT_ENTER]) {
145 -#if ! __has_feature(objc_arc)
146 - if (_openId) {
147 - [_openId release];
148 - }
149 - _openId = [reportInfo openId];
150 - [_openId retain];
151 -#else
152 - _openId = [reportInfo openId];
153 -#endif
154 -
155 -#if ! __has_feature(objc_arc)
156 - if (_serverId) {
157 - [_serverId release];
158 - }
159 - _serverId = [reportInfo openId];
160 - [_serverId retain];
161 -#else
162 - _serverId = [reportInfo openId];
163 -#endif
164 -
165 -#if ! __has_feature(objc_arc)
166 - if (_serverName) {
167 - [_serverName release];
168 - }
169 - _serverName = [reportInfo openId];
170 - [_serverName retain];
171 -#else
172 - _serverName = [reportInfo openId];
173 -#endif
174 -
175 -#if ! __has_feature(objc_arc)
176 - if (_roleId) {
177 - [_roleId release];
178 - }
179 - _roleId = [reportInfo openId];
180 - [_roleId retain];
181 -#else
182 - _roleId = [reportInfo openId];
183 -#endif
184 -
185 -#if ! __has_feature(objc_arc)
186 - if (_roleName) {
187 - [_roleName release];
188 - }
189 - _roleName = [reportInfo openId];
190 - [_roleName retain];
191 -#else
192 - _roleName = [reportInfo openId];
193 -#endif
194 -
195 - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
196 - [dict setValue:[reportInfo openId] forKey:@"openId"];//登录ID
197 - [dict setValue:[reportInfo serverId] forKey:@"serverId"];//服务器ID
198 - [dict setValue:[reportInfo serverName] forKey:@"serverName"];//服务器名称
199 - [dict setValue:[reportInfo playerId] forKey:@"roleId"];//角色ID
200 - [dict setValue:[reportInfo playerName] forKey:@"roleName"];//角色名称
201 -
202 - [[XFTrackIO sharedInstance]
203 - startTrackWithType:XFTrackIOTypeEnterGame
204 - andTrackData:dict];
205 - }
206 -}
207 -
208 -/**
209 - @return 商品名称
210 - */
211 -- (NSString*)getProductNameByAmount:(NSString*)products amount:(NSString*)amount
212 -{
213 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
214 - if(jsonData){
215 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
216 - if(productList){
217 - NSEnumerator* keysList = [productList keyEnumerator];
218 - id keyValue;
219 - while (keyValue = [keysList nextObject])
220 - {
221 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
222 - if(appleAmount.intValue == amount.intValue){
223 - NSString* productName = [[productList objectForKey:keyValue] objectForKey:@"name"];
224 - return productName;
225 - }
226 - }
227 - }
228 - }
229 - NSLog(@"get product name error amount:%@",amount);
230 - return @"元宝";
231 -}
232 -
233 -/**
234 - @return 商品ID
235 - */
236 -- (NSString*)getProductIdByAmount:(NSString*)products amount:(NSString*)amount
237 -{
238 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
239 - if(jsonData){
240 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
241 - if(productList){
242 - NSEnumerator* keysList = [productList keyEnumerator];
243 - id keyValue;
244 - while (keyValue = [keysList nextObject])
245 - {
246 - NSLog(@"i found %@",keyValue);
247 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
248 - NSLog(@"appleAmount:%@ amount:%@",appleAmount,amount);
249 - if(appleAmount.intValue == amount.intValue){
250 - return keyValue;
251 - }
252 - }
253 - }
254 - }
255 - return @"unknow";
256 -}
257 -
258 -- (void)receiveCreateOrder:(NSNotification *)notification
259 -{
260 - NSLog(@"创建订单成功");
261 - PoolPayInfo *payInfo = [notification object];
262 -
263 - NSString *openId = [payInfo playerId];
264 - NSString *myamount = [payInfo postAmount];
265 - NSString *queryId = [payInfo queryId];
266 - NSString *productId = [self getProductIdByAmount:payInfo.products amount:myamount];
267 -
268 -
269 - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
270 - [dict setValue:openId forKey:@"openId"];
271 - [dict setValue:myamount forKey:@"money"];
272 - [dict setValue:[payInfo productDesc] forKey:@"pro_info"];
273 - [dict setValue:queryId forKey:@"extra"];
274 - [dict setValue:productId forKey:@"orderid"];
275 -
276 - [[XFPayment sharedInstance] payWithOrderInfo:dict];
277 -
278 -}
279 -
280 -#pragma mark - Pay Delegate //支付返回订单号和金额
281 --(void)ApplePayResult:(PayResultNum)result resultData:(NSDictionary *)data{
282 -
283 - if (result == PayResultNumSuccess) {
284 -
285 - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
286 - [dict setValue:_openId forKey:@"openId"];//登录ID
287 - [dict setValue:_serverId forKey:@"serverId"];//服务器ID
288 - [dict setValue:_serverName forKey:@"serverName"]; //服务器名称
289 - [dict setValue:_roleId forKey:@"roleId"];//角色ID
290 - [dict setValue:_roleName forKey:@"roleName"];//角色名称
291 - [dict setValue:[data objectForKey:@"money"] forKey:@"money"];// 支付金额
292 - [dict setValue:[data objectForKey:@"orderId"] forKey:@"orderId"]; // 支付订单ID
293 -
294 - [[XFTrackIO sharedInstance]
295 - startTrackWithType:XFTrackIOTypePay
296 - andTrackData:dict];
297 - }
298 -}
299 -
300 --(NSString*)getCurrentTimestamp{
301 - // 时间戳转时间
302 - NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
303 - NSString* timeStr = [[NSString alloc]initWithFormat:@"%.f",interval];
304 - return timeStr;
305 -}
306 -
307 -@end
1 -//
2 -// ShowViewTest.h
3 -// XFLoginViewSDK
4 -//
5 -// Created by mac-mini on 16/10/18.
6 -// Copyright © 2016年 Jett.yu. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -#import <UIKit/UIKit.h>
11 -
12 -
13 -@protocol XFLoginViewSDKDelegate <NSObject>
14 -@optional
15 -
16 -
17 -/**
18 - 代理回调方法
19 -
20 - @param dic 回调参数
21 -
22 - openId 登录id
23 - token 登录token
24 -
25 - */
26 --(void)SDKLoginSuccessWithData:(NSDictionary *)dic;
27 -
28 -@end
29 -
30 -
31 -@interface XFLoginViewSDK : NSObject
32 -
33 -/**
34 - 登录代理
35 - */
36 -@property (nonatomic, weak) id<XFLoginViewSDKDelegate> XFLoginDelegate;
37 -
38 -/**
39 - 实例化
40 -
41 - @return XFLoginViewSDK 实例
42 - */
43 -+(id)sharedInstance;
44 -
45 -/**
46 - 登录初始化
47 -
48 - @param appid 平台使用appid
49 - @param packageid 平台使用packageid
50 - @param appkey 通用appkey
51 - */
52 --(void)initWithAPPId:(NSString *)appid andPackageId:(NSString *)packageid andAppKey:(NSString *)appkey;
53 -
54 -
55 -/**
56 - 开始登陆
57 - */
58 --(void)OnLogin;
59 -
60 -
61 -
62 -@end
1 -//
2 -// XFTrackIO.h
3 -// XFTrackIO
4 -//
5 -// Created by yu on 2017/6/9.
6 -// Copyright © 2017年 jett. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -
12 -/**
13 - 数据监控类型
14 -
15 -
16 - - XFTrackIOTypeCreate: 角色创建
17 - - XFTrackIOTypeEnterGame: 进入游戏
18 - - XFTrackIOTypePay: 开始支付
19 - - XFTrackIOTypeAccountRegist: 账号注册
20 - - XFTrackIOTypeAccountLogin: 账号登录
21 - */
22 -typedef NS_ENUM(NSUInteger, XFTrackIOType) {
23 - XFTrackIOTypeActivate = 0,
24 - XFTrackIOTypeBoot,
25 - XFTrackIOTypeCrash,
26 - XFTrackIOTypeCreate,
27 - XFTrackIOTypeEnterGame,
28 - XFTrackIOTypePay,
29 - XFTrackIOTypeAccountRegist,
30 - XFTrackIOTypeAccountLogin,
31 -};
32 -
33 -
34 -@interface XFTrackIO : NSObject
35 -
36 -
37 -/**
38 - 实例化
39 -
40 - @return 实例化
41 - */
42 -+(id)sharedInstance;
43 -
44 -
45 -/**
46 - 追踪初始化
47 -
48 - @param appid 通用appid
49 - @param packageid 通用packageid
50 - @param appkey 通用appkey
51 - @param reyunKey 热云key(不接入则传空)
52 - */
53 --(void)initWithAppid:(NSString *)appid andPackageId:(NSString *)packageid andAppKey:(NSString *)appkey andReyunKey:(NSString *)reyunKey;
54 -
55 -
56 -/**
57 - 开始监控
58 -
59 - @param type 数据监控的类型
60 - @param data 数据监控的参数(具体传参,请参考文档)
61 - */
62 --(void)startTrackWithType:(XFTrackIOType)type andTrackData:(NSDictionary *)data;
63 -
64 -
65 -
66 -/**
67 - 是否显示日志
68 -
69 - @param print true or false
70 - */
71 --(void)setLogPrint:(BOOL)print;
72 -
73 -@end
1 -{"sdkAppKey": "11a85d38b8f63be0", "payorderurl": "http://183.57.76.181:9020/paycheck/create", "usertype": 183, "sdkReyunKey": "50ac4b354e94640078075444b5971a3c", "sdkSimpleName": "xianfeng_ios", "sdkPackageId": "1000059", "gamechannelid": "", "custom": "{}", "sdkVersionCode": "V1_0_0", "loginCheckUrl": "http://183.57.76.181:9010/logincheck/check", "sdkAppId": "10002", "appScheme": "com.twapp65gdm.qjfy1", "c2": "", "c1": "", "paycheckurl": "http://183.57.76.181:9020/paycheck/confirm", "gameSimpleName": "fytx_test"}
...\ No newline at end of file ...\ No newline at end of file
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>CFBundleDevelopmentRegion</key>
6 - <string>en</string>
7 - <key>CFBundleExecutable</key>
8 - <string>$(EXECUTABLE_NAME)</string>
9 - <key>CFBundleIdentifier</key>
10 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 - <key>CFBundleInfoDictionaryVersion</key>
12 - <string>6.0</string>
13 - <key>CFBundleName</key>
14 - <string>$(PRODUCT_NAME)</string>
15 - <key>CFBundlePackageType</key>
16 - <string>APPL</string>
17 - <key>CFBundleShortVersionString</key>
18 - <string>1.0</string>
19 - <key>CFBundleSignature</key>
20 - <string>????</string>
21 - <key>CFBundleURLTypes</key>
22 - <array>
23 - <dict>
24 - <key>CFBundleTypeRole</key>
25 - <string>Editor</string>
26 - <key>CFBundleURLSchemes</key>
27 - <array>
28 - <string>i9133public</string>
29 - </array>
30 - </dict>
31 - <dict>
32 - <key>CFBundleTypeRole</key>
33 - <string>Editor</string>
34 - <key>CFBundleURLSchemes</key>
35 - <array>
36 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
37 - </array>
38 - </dict>
39 - </array>
40 - <key>CFBundleVersion</key>
41 - <string>1</string>
42 - <key>LSRequiresIPhoneOS</key>
43 - <true/>
44 - <key>NSAppTransportSecurity</key>
45 - <dict>
46 - <key>NSAllowsArbitraryLoads</key>
47 - <true/>
48 - <key>public.sdk.gzyouai.com</key>
49 - <dict>
50 - <key>NSExceptionMinimumTLSVersion</key>
51 - <string>TLSv1.0</string>
52 - </dict>
53 - <key>sdk.shxingwan.com</key>
54 - <dict>
55 - <key>NSExceptionMinimumTLSVersion</key>
56 - <string>TLSv1.0</string>
57 - </dict>
58 - <key>statistic.public.sdk.gzyouai.com</key>
59 - <dict>
60 - <key>NSExceptionMinimumTLSVersion</key>
61 - <string>TLSv1.0</string>
62 - </dict>
63 - </dict>
64 - <key>UILaunchStoryboardName</key>
65 - <string>LaunchScreen</string>
66 - <key>UIMainStoryboardFile</key>
67 - <string>Main</string>
68 - <key>UIRequiredDeviceCapabilities</key>
69 - <array>
70 - <string>armv7</string>
71 - </array>
72 - <key>UISupportedInterfaceOrientations</key>
73 - <array>
74 - <string>UIInterfaceOrientationLandscapeLeft</string>
75 - <string>UIInterfaceOrientationLandscapeRight</string>
76 - </array>
77 -</dict>
78 -</plist>
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>CFBundleURLTypes</key>
6 - <array>
7 - <dict>
8 - <key>CFBundleTypeRole</key>
9 - <string>Editor</string>
10 - <key>CFBundleURLSchemes</key>
11 - <array>
12 - <string>i9133public</string>
13 - </array>
14 - </dict>
15 - <dict>
16 - <key>CFBundleTypeRole</key>
17 - <string>Editor</string>
18 - <key>CFBundleURLSchemes</key>
19 - <array>
20 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
21 - </array>
22 - </dict>
23 - </array>
24 - <key>NSAppTransportSecurity</key>
25 - <dict>
26 - <key>NSAllowsArbitraryLoads</key>
27 - <true/>
28 - <key>public.sdk.gzyouai.com</key>
29 - <dict>
30 - <key>NSExceptionMinimumTLSVersion</key>
31 - <string>TLSv1.0</string>
32 - </dict>
33 - <key>sdk.shxingwan.com</key>
34 - <dict>
35 - <key>NSExceptionMinimumTLSVersion</key>
36 - <string>TLSv1.0</string>
37 - </dict>
38 - <key>statistic.public.sdk.gzyouai.com</key>
39 - <dict>
40 - <key>NSExceptionMinimumTLSVersion</key>
41 - <string>TLSv1.0</string>
42 - </dict>
43 - </dict>
44 -</dict>
45 -</plist>
...\ No newline at end of file ...\ No newline at end of file
1 -//
2 -// DCSdk.h
3 -// DCSdk
4 -//
5 -// Created by xqwang on 13-7-8.
6 -// Copyright (c) 2013年 digitcube. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -//这里提供静态方法
12 -@interface DCTrackingAgent : NSObject
13 -
14 -/**
15 - * @brief 初始化接口,程序启动时调用
16 - *
17 - * 一般在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions内调用一次即可
18 - * !!!一定要调用,否则后面无法上报,只能调用一次
19 - * @param appId 在我们网站上创建游戏时分配的appId,用于标识这款游戏. 注意保密!
20 - * @param channelId 渠道id , 方便统计分析你在各渠道的推广效果
21 - */
22 -+ (void)initWithAppId:(NSString *)appId andChannelId:(NSString*)channelId;
23 -
24 -
25 -/**
26 - * @brief 设置数据上报间隔时间,该接口需要在onStart接口之前调用,否则无效。如果不调用该接口,SDK默认以1分钟的间隔上报数据
27 - *
28 - **/
29 -+(void)setUploadInterval:(unsigned int)time;
30 -
31 -
32 -/**
33 - * @brief 设置应用版本号,不调用该接口时SDK默认从配置文件中读取应用版本号
34 - *
35 - * @param version:应用版本号
36 - */
37 -+(void)setVersion:(NSString*)version;
38 -
39 -/**
40 - * @brief 立即上报数据
41 - **/
42 -+(void)uploadNow;
43 -
44 -/**
45 - * @brief 获取设备ID
46 - **/
47 -+(NSString*)getUID;
48 -
49 -@end
50 -
51 -
52 -@interface DCTrackingPoint : NSObject
53 -
54 -/**
55 - @brief 广告效果追踪设置有效的效果点
56 - @param pointId 广告效果点
57 - @param propDictionary 触发时希望传入的属性字典
58 - **/
59 -+(void)setEffectPoint:(NSString*)pointId propDictionary:(NSDictionary*)dictionary;
60 -
61 -/**
62 - @brief 玩家登陆事件
63 - @param accountId 玩家账户ID
64 - **/
65 -+(void)login:(NSString*)accountId;
66 -
67 -
68 -/**
69 - @brief 玩家注册事件
70 - @param accountId 玩家账户ID
71 - **/
72 -+(void)createAccount:(NSString*)accountId;
73 -
74 -/**
75 - @brief 玩家付费事件
76 - @param orderId 订单ID
77 - @param currencyAmount 付费总额
78 - @param currencyType 货币类型
79 - @param paymentType 支付途径
80 - **/
81 -+(void)paymentSuccess:(NSString*)orderId currencyAmount:(double)currencyAmount currencyType:(NSString*)currencyType paymentType:(NSString*)paymentType;
82 -
83 -@end
1 -//
2 -// NewTtack.h
3 -// NewTtack
4 -//
5 -// Created by yun on 16/1/11.
6 -// Copyright © 2016年 yun. All rights reserved.
7 -//
8 -#define TRACK_VERSION @"3.0.1"
9 -
10 -#import <Foundation/Foundation.h>
11 -#import <UIKit/UIKit.h>
12 -
13 -
14 -/*
15 - 热云移动广告效果监测 平台 api 请选择对应的api进行使用
16 - */
17 -NS_ASSUME_NONNULL_BEGIN
18 -@interface ReYunChannel : NSObject
19 -//开启打印日志 正式上线包请关掉
20 -+(void) setPrintLog :(BOOL)print;
21 -// 开启数据统计
22 -+ (void)initWithappKey:(NSString *)appKey withChannelId:(NSString *)channelId;
23 -//注册成功后调用
24 -+ (void)setRegisterWithAccountID:(NSString *)account;
25 -//登陆成功后调用
26 -+ (void)setLoginWithAccountID:(NSString *)account;
27 -//开始付费时 调用(人民币单位是元)
28 -+(void)setPaymentStart:(NSString *)transactionId paymentType:(NSString*)paymentType currentType:(NSString*)currencyType currencyAmount:(float)currencyAmount;
29 -// 支付完成,付费分析,记录玩家充值的金额(人民币单位是元)
30 -+(void)setPayment:(NSString *)transactionId paymentType:(NSString*)paymentType currentType:(NSString*)currencyType currencyAmount:(float)currencyAmount;
31 -//自定义事件
32 -+(void)setEvent:(NSString *)eventName;
33 -//获取设备信息
34 -+(NSString*)getDeviceId;
35 -
36 -+(BOOL)RYApplication:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options;
37 -@end
38 -NS_ASSUME_NONNULL_END
...\ No newline at end of file ...\ No newline at end of file
1 -
2 -//
3 -// PPInterface.h
4 -// PoolSdk
5 -//
6 -// Created by winFan on 11/23/15.
7 -// Copyright (c) 2015 winFan. All rights reserved.
8 -//
9 -
10 -#import <PoolSdk/PoolSdk2.h>
11 -@interface SDKInterface : Interface
12 -
13 -
14 -@end
1 -//
2 -// UnionInterface.m
3 -// PoolSdk
4 -//
5 -// Created by winFan on 11/23/15.
6 -// Copyright (c) 2015 winFan. All rights reserved.
7 -//
8 -#include "SDKInterface.h"
9 -#import <UIKit/UIKit.h>
10 -
11 -#import "YouaiSDK/YouaiSDKMgr.h"
12 -#import "YouaiSDK/YouaiNotifications.h"
13 -#import "YouaiSDK/YouaiLoginInfo.h"
14 -#import "ReYunTrack.h"
15 -#import "DCTrackingAgent.h"
16 -
17 -//SDK
18 -
19 -
20 -@implementation SDKInterface : Interface
21 -
22 -
23 -int mExchange;
24 -
25 -
26 -/**
27 - 初始化SDK
28 -*/
29 -- (void)SDKinit:(UIViewController *) control
30 -{
31 - //必须继承
32 - [super SDKinit:control];
33 -
34 - [PoolConfig getInstance];
35 - [[YouaiSDKMgr getInstance]initSDK];
36 - [[YouaiSDKMgr getInstance]setStyleName:@"sdk"];
37 - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveLoginMessage:) name:youaiLoginNotification object:nil];
38 - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applePayCallBack:) name:@"applePayCallBack" object:nil];
39 -
40 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationInitSDK notiName:@"InitSuccess" statusCode:POOLSDK_NO_ERROR description:@"initSuccess" extendData:nil];
41 -
42 -
43 - NSString* channelId = [[PoolConfig getInstance] getValueByKey:@"sdkSimpleName"];
44 - [ReYunChannel initWithappKey:[[PoolConfig getInstance] getValueByKey:@"renyunAppKey"] withChannelId:channelId];
45 -
46 - NSString* dateEyeAppId = [[PoolConfig getInstance] getValueByKey:@"dateEyeAppId"];
47 -
48 - [DCTrackingAgent initWithAppId:dateEyeAppId andChannelId:channelId];
49 -}
50 -
51 -/**
52 - 登录SDK
53 - */
54 -- (void)SDKloginSDK
55 -{
56 - NSLog(@"no parames login");
57 - [self SDKloginSDK:self.controller];
58 -}
59 -
60 -- (void)SDKloginSDK:(UIViewController *)control
61 -{
62 - NSLog(@"调用了LoginSDK");
63 - NSString *appId = [[PoolConfig getInstance] getValueByKey:@"APP_ID"];
64 - NSString *appKey =[[PoolConfig getInstance] getValueByKey:@"APP_KEY"];
65 - [[YouaiSDKMgr getInstance]openLogin:appId :appKey :control];
66 -}
67 -
68 -/**
69 - loginCheck
70 - */
71 -- (void)receiveLoginMessage:(NSNotification *)notification
72 -{
73 - NSLog(@"loginchek");
74 - PoolLoginInfo *loginInfo = [PoolLoginInfo alloc];
75 - loginInfo.openId = [[YouaiLoginInfo getInstance]openId];
76 - loginInfo.sign = [[YouaiLoginInfo getInstance] token];
77 - loginInfo.timestamp = [YouaiLoginInfo getInstance].timestamp;
78 - [[PoolChecker getInstance] startCheck:loginInfo];
79 -}
80 -
81 -
82 --(NSString*)DataTojsonString:(id)object
83 -{
84 - NSString *jsonString = nil;
85 - NSError *error;
86 - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object
87 - options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
88 - error:&error];
89 - jsonString = [jsonData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
90 - return jsonString;
91 -}
92 -
93 -/**
94 - 苹果支付结果回调
95 - */
96 -
97 -- (void)applePayCallBack:(NSNotification *)notification
98 -{
99 - NSDictionary* payResultDic = notification.object;
100 -
101 - NSString* receiptStr = [payResultDic objectForKey:@"payResult"];
102 - NSString* queryId = [payResultDic objectForKey:@"query_id"];
103 -
104 - NSDictionary* receiptDic = [NSDictionary dictionaryWithObjectsAndKeys:receiptStr,@"receipt",queryId,@"query_id", nil];
105 - NSString* result = [[NetCenter getInstance] httpPostSyn:[PoolUtils createPayUrl] :receiptDic];
106 -
107 -
108 - if([@"success" isEqualToString:result]){//确认订单成功
109 - }else{//失败
110 - NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
111 - NSMutableArray* queryIdArray = [userDefaults objectForKey:@"queryIds"];
112 -
113 - NSMutableArray* tempQueryIdArray = [[NSMutableArray alloc] initWithCapacity:10];
114 -
115 - if (queryIdArray) {
116 - }else{
117 - queryIdArray = [[NSMutableArray alloc]initWithCapacity:10];
118 - }
119 -
120 - for (NSString* arrayQueryId in queryIdArray) {
121 - [tempQueryIdArray addObject:arrayQueryId];
122 - }
123 -
124 - [tempQueryIdArray addObject:queryId];
125 - [userDefaults setObject:tempQueryIdArray forKey:@"queryIds"];
126 - [userDefaults setObject:receiptStr forKey:queryId];
127 - [userDefaults synchronize];
128 - }
129 -}
130 -
131 -/**
132 - 支付 创建订单
133 - */
134 -- (void)SDKpayWithPaymentInfo:(PoolCreateOrderInfo *)payInfo
135 -{
136 - mExchange = [payInfo exchange].intValue;
137 - [super SDKpayWithPaymentInfo:payInfo];
138 -}
139 -
140 -/**
141 - SDK
142 - */
143 -- (void)SDKgotoUserCenter
144 -{
145 -}
146 -
147 -- (void)SDKreport:(PoolReportInfo *)reportInfo
148 -{
149 - NSLog(@"reportInfo");
150 - NSString* reportType = [reportInfo reportType];
151 - if (reportInfo) {
152 - if ([reportType isEqualToString:REPORT_ENTER]) {
153 - [ReYunChannel setLoginWithAccountID:[reportInfo playerId]];//reyun login
154 - [DCTrackingPoint login:[reportInfo playerId]];//dateeye login
155 -
156 - dispatch_async(dispatch_get_global_queue(0, 0), ^{
157 - [self handlerLeakOrder];
158 - });
159 - }else if([reportType isEqualToString:REPORT_CREATEROLE]){
160 - [ReYunChannel setRegisterWithAccountID:[reportInfo playerId]];//reyun reg
161 - [DCTrackingPoint createAccount:[reportInfo playerId]];//reyun reg
162 - }
163 - }
164 -}
165 -
166 -/**
167 - SDK
168 - */
169 -- (void)SDKexitSDK
170 -{
171 -
172 -}
173 -
174 -- (void)SDKlogoutSDK
175 -{
176 - NSLog(@"切换账号");
177 -}
178 -
179 -- (void)handleOpenurl:(NSURL *)url
180 -{
181 -}
182 -
183 -- (void)receivePayMessage : (NSNotification *)notification;
184 -{
185 - NSString *order_id = [notification object];
186 - NSLog(@"订单ID:%@", order_id);
187 -}
188 -
189 -//补单处理
190 -- (void) handlerLeakOrder{
191 - NSUserDefaults* userDefaults2 = [NSUserDefaults standardUserDefaults];
192 - NSMutableArray* queryIdArray = [userDefaults2 objectForKey:@"queryIds"];
193 -
194 - NSLog(@"orderDic%@",queryIdArray);
195 - NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
196 - NSMutableArray* failQueryIdArray = [[NSMutableArray alloc]initWithCapacity:10];//补单失败的queryid集合
197 -
198 - if(queryIdArray){
199 - for (NSString* queryId in queryIdArray) {
200 - NSString* receiptStr = [userDefaults valueForKey:queryId];
201 - NSDictionary* receiptDic = [NSDictionary dictionaryWithObjectsAndKeys:receiptStr,@"receipt",queryId,@"query_id", nil];
202 - NSString* result = [[NetCenter getInstance] httpPostSyn:[PoolUtils createPayUrl] :receiptDic];
203 - if([@"success" isEqualToString:result]){//成功
204 - [userDefaults removeObjectForKey:queryId];
205 - }else{//补单失败
206 - [failQueryIdArray addObject:queryId];
207 - }
208 - }
209 -
210 - NSLog(@"order count:%lu",(unsigned long)[failQueryIdArray count]);
211 - if([failQueryIdArray count] > 0){//含有补单失败项
212 - [userDefaults setObject:failQueryIdArray forKey:@"queryIds"];
213 - }else{//全部补单成功
214 - [userDefaults removeObjectForKey:@"queryIds"];
215 - }
216 - [userDefaults synchronize];
217 - }
218 -}
219 -
220 -
221 -- (void)receiveCreateOrder:(NSNotification *)notification
222 -{
223 - NSLog(@"创建订单成功");
224 - PoolPayInfo *payInfo = [notification object];
225 -
226 - NSNumber *amount = @([[payInfo postAmount] integerValue] * mExchange);
227 - NSString *serverId = [payInfo serverId];
228 - NSString *roleName = [payInfo playerName];
229 - NSString *queryId = [payInfo queryId];
230 -
231 - dispatch_async(dispatch_get_global_queue(0, 0), ^{
232 - [self handlerLeakOrder];
233 - });
234 -
235 - //NSString *isOpenThirdPay = [payInfo isOpenThirdPay];
236 -
237 - NSString *other = [payInfo other];
238 -
239 - if (other && [other length] > 0) {
240 - [[YouaiSDKMgr getInstance] openPay:serverId :roleName :amount :[payInfo queryId] :self.controller];
241 - }else{
242 - NSString* products = [payInfo products];
243 - [[YouaiSDKMgr getInstance] openApplePay:self.controller products:products amount:[payInfo postAmount] queryId:queryId];
244 - }
245 -}
246 -
247 -
248 --(void)paymentSuccess:(NSString *)accountId orderId:(NSString *)orderId currencyAmount:(double)amount currencyType:(NSString *)currencyType payType:(NSString *)payType custom:(NSArray *)customArray
249 -{
250 - [DCTrackingPoint paymentSuccess:orderId currencyAmount:amount currencyType:currencyType paymentType:payType];
251 - [ReYunChannel setPayment:orderId paymentType:payType currentType:currencyType currencyAmount:amount];
252 -}
253 -
254 -@end
...\ No newline at end of file ...\ No newline at end of file
1 -//
2 -// IapController.h
3 -// mangosanguo
4 -//
5 -// Created by Gino on 12-11-6.
6 -// Copyright (c) 2012年 private. All rights reserved.
7 -//
8 -#if applepay
9 -#import <Foundation/Foundation.h>
10 -#import "StoreKit/StoreKit.h"
11 -
12 -@interface IapController : NSObject<SKProductsRequestDelegate,SKPaymentTransactionObserver>
13 -{
14 - bool isRequestedBuy;
15 - SKPaymentTransaction *PayTransaction;
16 -
17 - NSMutableArray *payArray;
18 - SKPaymentTransaction *curTransaction;
19 -}
20 -
21 -+ (IapController *)sharedController;
22 -- (id)init;
23 -- (void)removeIt;
24 -- (void)requestProductData;
25 -- (void)requestBuyProduct:(NSString *)identifier;
26 -
27 -- (void)requestProductInfoById:(NSString *)str;
28 -- (void)comfireTransactions:(bool)isSuessPosted;
29 -- (void)checkReceiptIsFail;
30 -
31 -- (void)addItemToPayArray:(SKPaymentTransaction *)transaction;
32 -- (bool)checkPayArrayIsEmpty;
33 -- (void)checkReceiptForArray;
34 -
35 -- (void)setAppleCallBack: (NSString*)url;
36 -@end
37 -#endif
...\ No newline at end of file ...\ No newline at end of file
1 -//
2 -// GetWifiMac.h
3 -// mangosanguo
4 -//
5 -// Created by 莫 on 12-9-28.
6 -// Copyright (c) 2012年 private. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -
11 -@interface YouaiGetWifiMac : NSObject
12 -
13 -+ (NSString *)macaddress;
14 -@end
1 -//
2 -// YouaiLoginInfo.h
3 -// YouaiSDK
4 -//
5 -// Created by 莫 东荣 on 13-4-10.
6 -// Copyright (c) 2013年 莫 东荣. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface YouaiLoginInfo : NSObject //用户uid
12 -{
13 -//
14 -NSString *openId;
15 -//token
16 -NSString *token;
17 -//时间戳
18 -NSString *timestamp;
19 -
20 -}
21 -
22 -@property(retain,nonatomic) NSString *openId;
23 -@property(retain,nonatomic) NSString *token;
24 -@property(retain,nonatomic) NSString *timestamp;
25 -+ (YouaiLoginInfo *)getInstance;
26 -@end
...\ No newline at end of file ...\ No newline at end of file
1 -//
2 -// YouaiNotifications.h
3 -// YouaiSDK
4 -//
5 -// Created by 莫 东荣 on 13-4-10.
6 -// Copyright (c) 2013年 莫 东荣. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -extern NSString * const youaiExitNotification; /**< 退出 */
12 -extern NSString * const youaiLoginNotification; /**< 登录完成的通知*/
13 -extern NSString * const youaiPaytNotification; /**< 支付通知 */
14 -extern NSString * const youaiShareNotification; /**< 分享通知 */
15 -extern NSString * const youaiCenterNotification; /**< 用户中心通知 */
16 -extern NSString * const youaiErrorNotification; /**< 出错 */
17 -
18 -
19 -@interface YouaiNotifications : NSObject
20 -
21 -@end
1 -//
2 -// YouaiSDKMgr.h
3 -// YouaiSDK
4 -//
5 -// Created by 莫 东荣 on 13-4-9.
6 -// Copyright (c) 2013年 莫 东荣. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -#import "StoreKit/StoreKit.h"
11 -
12 -@interface YouaiSDKMgr : NSObject
13 -{
14 - NSString* appId_;
15 - NSString* appKey_;
16 - NSString* inviterCode_;
17 -
18 -// NSString* openId;
19 -// NSString* loginKey;
20 -}
21 -
22 -@property bool isApplePaying;
23 -
24 -+ (YouaiSDKMgr *)getInstance;
25 -- (void)initSDK;
26 -- (void)initSDK:(NSString *)weixinId;
27 -
28 -- (void)openLogin:(NSString *)appId : (NSString *)appKey : (UIViewController *)controller;
29 -- (void)openLogin:(NSString *)appId : (NSString *)appKey : (UIViewController *)controller : (NSString *) inviterCode;
30 -- (void)openLogin:(NSString *)appId : (NSString *)appKey : (UIViewController *)controller : (NSString *) inviterCode : (NSString *)userName : (NSString *)passWord;
31 -- (void)setStyleName:(NSString*)styleName;
32 -- (void)openLogin:(NSString *)appId : (NSString *)appKey : (UIViewController *)controller : (NSString *)userName : (NSString *)passWord;
33 -
34 -- (void)openCenter: (UIViewController *)controller;
35 -- (void)openPay: (NSString *)serverId : (NSString *)nickName : (NSString *)callBack : (UIViewController *)controller;
36 -- (void)openPay: (NSString *)serverId : (NSString *)nickName : (NSNumber *)payAmount : (NSString *)callBack : (UIViewController *)controller;
37 -- (void)openShare: (UIViewController *)controller;
38 -- (void)log: (NSString*)log_key : (NSInteger)log_data: (NSString*)log_remark;
39 -
40 -- (void)openApplePay:(UIViewController*)controll products:(NSString*)products amount:(NSString*)amount queryId:(NSString*) queryId;
41 -
42 -
43 -- (void)checkAilpay: (NSURL *)url : (UIViewController *)controller;
44 -
45 -- (void)applePayCallBack:(NSString *)url :(SKPaymentTransaction *)transaction :(NSString *)resultStr;
46 -
47 -
48 -
49 -@end
1 -//
2 -// YouaiViewController.h
3 -// newYouaiSDK
4 -//
5 -// Created by Mog90 on 14-9-28.
6 -// Copyright (c) 2014年 东荣 莫. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -#import "YouaiLoginInfo.h"
11 -
12 -@interface YouaiViewController : UIViewController<UIWebViewDelegate,UIAlertViewDelegate>
13 -{
14 - UIWebView *webView_;
15 - UIActivityIndicatorView *activityIndicator;
16 -}
17 -
18 -
19 -//@property(assign) int webViewWidth;
20 -//@property(assign) int webViewHeight;
21 -//@property(assign) int screenwidth;
22 -//@property(assign) int screenHeight;
23 -
24 -@property(assign) BOOL hasCorner;
25 -
26 --(void)setView:(int)webViewWidth :(int) webViewHeight :(int) screenwidth :(int) screenHeight;
27 -- (void)initWebView;
28 -- (void)loadWebPageWithString:(NSString *)url;
29 -- (void)loadWebPageWithJs:(NSString *)content;
30 -- (void)postNotification:(NSString *)name : (NSString *)code;
31 -- (void)receiveIap:(NSNotification *)notification;
32 -
33 -@end
1 -{"renyunAppKey": "d4f6d8e337472e5277634bcdb1ef6cf6", "dateEyeAppId": "", "payorderurl": "https://public.sdk.gzyouai.com/paycheck/create", "usertype": 139, "sdkSimpleName": "apple_xingwan", "gamechannelid": "", "APP_KEY": "f0455d5b7f2e982144b2ac8bc642e453", "custom": "{}", "sdkVersionCode": "V1_0", "loginCheckUrl": "https://public.sdk.gzyouai.com/logincheck/check", "appScheme": "com.ssmyj.ios.xw", "c2": "", "c1": "", "APP_ID": "5936756454c21d629d0c2755", "paycheckurl": "https://public.sdk.gzyouai.com/paycheck/confirm", "gameSimpleName": "qyj4"}
...\ No newline at end of file ...\ No newline at end of file
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>CFBundleDevelopmentRegion</key>
6 - <string>en</string>
7 - <key>CFBundleExecutable</key>
8 - <string>$(EXECUTABLE_NAME)</string>
9 - <key>CFBundleIdentifier</key>
10 - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 - <key>CFBundleInfoDictionaryVersion</key>
12 - <string>6.0</string>
13 - <key>CFBundleName</key>
14 - <string>$(PRODUCT_NAME)</string>
15 - <key>CFBundlePackageType</key>
16 - <string>APPL</string>
17 - <key>CFBundleShortVersionString</key>
18 - <string>1.0</string>
19 - <key>CFBundleSignature</key>
20 - <string>????</string>
21 - <key>CFBundleURLTypes</key>
22 - <array>
23 - <dict>
24 - <key>CFBundleTypeRole</key>
25 - <string>Editor</string>
26 - <key>CFBundleURLSchemes</key>
27 - <array>
28 - <string>xiaoaopay2016</string>
29 - </array>
30 - </dict>
31 - </array>
32 - <key>CFBundleVersion</key>
33 - <string>1</string>
34 - <key>LSRequiresIPhoneOS</key>
35 - <true/>
36 - <key>NSAppTransportSecurity</key>
37 - <dict>
38 - <key>NSAllowsArbitraryLoads</key>
39 - <true/>
40 - </dict>
41 - <key>UILaunchStoryboardName</key>
42 - <string>LaunchScreen</string>
43 - <key>UIMainStoryboardFile</key>
44 - <string>Main</string>
45 - <key>UIRequiredDeviceCapabilities</key>
46 - <array>
47 - <string>armv7</string>
48 - </array>
49 - <key>UISupportedInterfaceOrientations</key>
50 - <array>
51 - <string>UIInterfaceOrientationLandscapeLeft</string>
52 - <string>UIInterfaceOrientationLandscapeRight</string>
53 - </array>
54 -</dict>
55 -</plist>
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>NSAppTransportSecurity</key>
6 - <dict>
7 - <key>NSAllowsArbitraryLoads</key>
8 - <true/>
9 - </dict>
10 -
11 - <key>CFBundleURLTypes</key>
12 - <array>
13 - <dict>
14 - <key>CFBundleTypeRole</key>
15 - <string>Editor</string>
16 - <key>CFBundleURLSchemes</key>
17 - <array>
18 - <string>xiaoaopay2016</string>
19 - </array>
20 - </dict>
21 - </array>
22 -</dict>
23 -</plist>
1 -//
2 -// AppleIap.h
3 -// Demo_youdian
4 -//
5 -// Created by 许 on 17/6/20.
6 -// Copyright © 2017年 winFan. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface AppleIap : NSObject
12 -
13 -
14 --(void)applePay:(NSString*)products amount:(NSString*)amount queryId:(NSString*)queryId;
15 -
16 -@end
1 -//
2 -// AppleIap.m
3 -// Demo_youdian
4 -//
5 -// Created by 许 on 17/6/20.
6 -// Copyright © 2017年 winFan. All rights reserved.
7 -//
8 -
9 -#import "AppleIap.h"
10 -
11 -#import "IAPShare.h"
12 -#import <PoolSdk/PoolSdk2.h>
13 -
14 -@implementation AppleIap
15 -
16 -/**
17 - @return 商品ID
18 - */
19 -- (NSString*)getProductIdByAmount:(NSString*)products amount:(NSString*)amount
20 -{
21 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
22 - if(jsonData){
23 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
24 - if(productList){
25 - NSEnumerator* keysList = [productList keyEnumerator];
26 - id keyValue;
27 - while (keyValue = [keysList nextObject])
28 - {
29 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
30 - if(appleAmount.intValue == amount.intValue){
31 - NSLog(@"appleAmount:%@ amount:%@",appleAmount,amount);
32 - return keyValue;
33 - }
34 - }
35 - }
36 - }
37 - NSLog(@"amount get productId error amount:%@",amount);
38 - return nil;
39 -}
40 -
41 -
42 --(void)applePay:(NSString *)products amount:(NSString *)amount queryId:(NSString *)queryId
43 -{
44 - //内购ID
45 - NSString* productId = [self getProductIdByAmount:products amount:amount];
46 - if(productId){
47 - [self ipaPay:productId queryId:queryId];
48 - }else{
49 - NSLog(@"get apple product id error");
50 - }
51 -}
52 -
53 -/**
54 - 苹果支付结果回调
55 - */
56 -
57 -- (void)applePayCallBack:(NSString*)receiptStr queryId:(NSString*)queryId
58 -{
59 - //NSDictionary* payResultDic = notification.object;
60 - //NSString* receiptStr = [payResultDic objectForKey:@"payResult"];
61 - //NSString* queryId = [payResultDic objectForKey:@"query_id"];
62 - NSLog(@"applePayCallBack");
63 - NSDictionary* receiptDic = [NSDictionary dictionaryWithObjectsAndKeys:receiptStr,@"receipt",queryId,@"query_id", nil];
64 - NSString* result = [[NetCenter getInstance] httpPostSyn:[PoolUtils createPayUrl] :receiptDic];
65 -
66 - if([@"success" isEqualToString:result]){//确认订单成功
67 - }else{//失败
68 - NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
69 - NSMutableArray* queryIdArray = [userDefaults objectForKey:@"queryIds"];
70 -
71 - NSMutableArray* tempQueryIdArray = [[NSMutableArray alloc] initWithCapacity:10];
72 -
73 - if (queryIdArray) {
74 - }else{
75 - queryIdArray = [[NSMutableArray alloc]initWithCapacity:10];
76 - }
77 -
78 - for (NSString* arrayQueryId in queryIdArray) {
79 - [tempQueryIdArray addObject:arrayQueryId];
80 - }
81 -
82 - [tempQueryIdArray addObject:queryId];
83 - [userDefaults setObject:tempQueryIdArray forKey:@"queryIds"];
84 - [userDefaults setObject:receiptStr forKey:queryId];
85 - [userDefaults synchronize];
86 - }
87 -}
88 -
89 -
90 -
91 -- (void)initIpa:(NSString*)productId{
92 - if(![IAPShare sharedHelper].iap){
93 - NSLog(@"iap init");
94 - }
95 -
96 - NSSet* dataSet = [[NSSet alloc]initWithObjects:productId, nil];
97 - [IAPShare sharedHelper].iap = [[IAPHelper alloc] initWithProductIdentifiers:dataSet];
98 -}
99 -
100 -
101 -- (void)ipaPay:(NSString*) productId queryId:(NSString*)queryId{
102 - @synchronized([PoolSdk shareSDK]) {
103 - if([PoolSdk shareSDK].isApplePaying) {
104 - NSLog(@"apple paying");
105 - return;
106 - };
107 - [PoolSdk shareSDK].isApplePaying = true;
108 - }
109 - NSLog(@"productId:%@",productId);
110 - [self initIpa:productId];
111 - [[IAPShare sharedHelper].iap requestProductsWithCompletion:^(SKProductsRequest* request,SKProductsResponse* response)
112 - {
113 - NSLog(@"response");
114 - if(response && response > 0 ) {
115 - NSLog(@"response %lu",(unsigned long)[[IAPShare sharedHelper].iap.products count]);
116 - if([[IAPShare sharedHelper].iap.products count] > 0){
117 - NSLog(@"product count 1");
118 - SKProduct* product =[[IAPShare sharedHelper].iap.products objectAtIndex:0];
119 - NSString* queryIdStr = queryId;
120 - [[IAPShare sharedHelper].iap buyProduct:product
121 - onCompletion:^(SKPaymentTransaction* trans){
122 - [PoolSdk shareSDK].isApplePaying = false;
123 - NSLog(@"buy product callback");
124 -
125 - if(trans.error)
126 - {
127 - NSLog(@"Fail %@",[trans.error localizedDescription]);
128 - }
129 - else if(trans.transactionState == SKPaymentTransactionStatePurchased) {
130 -
131 - NSData* receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
132 -
133 - NSString* receiptStr = [receiptData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
134 -
135 - receiptStr = [receiptStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
136 -
137 - [self applePayCallBack:receiptStr queryId:queryIdStr];
138 - }
139 - else if(trans.transactionState == SKPaymentTransactionStateFailed) {
140 - NSLog(@"Fail");
141 - }
142 - }];
143 - }else{
144 - [PoolSdk shareSDK].isApplePaying = false;
145 - }
146 - }else{
147 - [PoolSdk shareSDK].isApplePaying = false;
148 - }
149 - }];
150 -}
151 -
152 -@end
1 -//
2 -// LonginController.h
3 -// NewLogin
4 -//
5 -// Created by 耿宇 on 16/3/28.
6 -// Copyright © 2016年 JT. All rights reserved.
7 -//
8 -
9 -#import <UIKit/UIKit.h>
10 -
11 -@interface LonginController : UIViewController
12 -@property(nonatomic,copy)void(^block)(BOOL,NSDictionary *dict);
13 -
14 --(instancetype)initWithGameId:(NSString *)gameId withAvatarImg:(NSString*)avatarImg withParamJson:(NSDictionary*)ParamJson;
15 -
16 -
17 -@end
1 -
2 -//
3 -// PPInterface.h
4 -// PoolSdk
5 -//
6 -// Created by winFan on 11/23/15.
7 -// Copyright (c) 2015 winFan. All rights reserved.
8 -//
9 -
10 -#import <PoolSdk/PoolSdk2.h>
11 -@interface SDKInterface : Interface
12 -
13 -@end
1 -//
2 -// UnionInterface.m
3 -// PoolSdk
4 -//
5 -// Created by winFan on 11/23/15.
6 -// Copyright (c) 2015 winFan. All rights reserved.
7 -//
8 -#include "SDKInterface.h"
9 -#import <UIKit/UIKit.h>
10 -#import "LonginController.h"
11 -#import "UpDatePerson.h"
12 -#import "XiaoaoPay.h"
13 -#import "AppleIap.h"
14 -
15 -
16 -@implementation SDKInterface : Interface
17 -
18 -/**
19 - 初始化SDK
20 -*/
21 -- (void)SDKinit:(UIViewController *) control
22 -{
23 - //必须继承
24 - [super SDKinit:control];
25 -
26 - [PoolConfig getInstance];
27 -
28 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationInitSDK notiName:@"InitSuccess" statusCode:POOLSDK_NO_ERROR description:@"initSuccess" extendData:nil];
29 -}
30 -
31 -/**
32 - 登录SDK
33 - */
34 -- (void)SDKloginSDK
35 -{
36 - NSLog(@"调用了LoginSDK");
37 - NSString* gameId = [[PoolConfig getInstance] getValueByKey:@"gameId"];
38 - LonginController * longin = [[LonginController alloc]initWithGameId:gameId withAvatarImg:nil withParamJson:nil];
39 - longin.block = ^(BOOL result , NSDictionary *dic){
40 - NSLog(@"login info %@",dic);
41 - if (result) {
42 - [self loginCheck:[dic objectForKey:@"usercode"] uid:[dic objectForKey:@"aokuid"]];
43 - }else{
44 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationLogin notiName:@"loginFail" statusCode:POOLSDK_ERROR_LOGIN_FAILED description:@"loginFail" extendData:nil];
45 - }
46 - };
47 -
48 -
49 - if ([[[UIDevice currentDevice]systemVersion]floatValue]>8.0) {
50 - longin.modalPresentationStyle = UIModalPresentationOverCurrentContext;
51 - }
52 - else{
53 - self.controller.modalPresentationStyle = UIModalPresentationCurrentContext;
54 - }
55 - [self.controller presentViewController:longin animated:NO completion:nil];
56 -}
57 -/*
58 - *登录验证请求方法模版
59 - */
60 -- (void)loginCheck:(NSString *)userCode uid:(NSString*)uid
61 -{
62 - NSLog(@"uid:%@",uid);
63 - PoolLoginInfo *loginInfo = [[PoolLoginInfo alloc]init];
64 - loginInfo.openId = userCode;//渠道userId
65 - loginInfo.timestamp = [self getCurrentTimestamp];
66 - loginInfo.sign = uid;
67 - dispatch_async(dispatch_get_global_queue(0, 0), ^{
68 - [[PoolChecker getInstance]startCheck:loginInfo];//登录验证请求
69 - });
70 -}
71 -
72 -
73 -- (void)SDKreport:(PoolReportInfo *)reportInfo
74 -{
75 - NSLog(@"reportInfo");
76 - if ([REPORT_CREATEROLE isEqualToString:[reportInfo reportType]]) {
77 -
78 - }else if ([[reportInfo reportType] isEqualToString:REPORT_ENTER]) {
79 -
80 - NSString *playerName = [reportInfo playerName];
81 - NSString *playerLevel = [reportInfo playerLevel];
82 -
83 - UpDatePerson *up = [[UpDatePerson alloc]init];
84 -
85 - [up updatePerson:playerName withGameLevel:playerLevel withTeamId:[reportInfo partyName]];
86 - up.block = ^(NSString * str){
87 - NSLog(@"%@",str);//返回更新玩家信息是否成功
88 - };
89 - }
90 -}
91 -
92 -
93 -/**
94 - SDK
95 - */
96 -- (void)SDKexitSDK
97 -{
98 -
99 -}
100 -
101 -- (void)SDKlogoutSDK
102 -{
103 - NSLog(@"切换账号");
104 -}
105 -
106 -- (void)receivePayMessage : (NSNotification *)notification;
107 -{
108 - NSString *order_id = [notification object];
109 - NSLog(@"订单ID:%@", order_id);
110 -}
111 -
112 -/**
113 - @return 商品名称
114 - */
115 -- (NSString*)getProductNameByAmount:(NSString*)products amount:(NSString*)amount
116 -{
117 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
118 - if(jsonData){
119 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
120 - if(productList){
121 - NSEnumerator* keysList = [productList keyEnumerator];
122 - id keyValue;
123 - while (keyValue = [keysList nextObject])
124 - {
125 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
126 - if(appleAmount.intValue == amount.intValue){
127 - NSString* productName = [[productList objectForKey:keyValue] objectForKey:@"name"];
128 - return productName;
129 - }
130 - }
131 - }
132 - }
133 - NSLog(@"get product name error amount:%@",amount);
134 - return @"元宝";
135 -}
136 -
137 -/**
138 - @return 商品ID
139 - */
140 -- (NSString*)getProductIdByAmount:(NSString*)products amount:(NSString*)amount
141 -{
142 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
143 - if(jsonData){
144 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
145 - if(productList){
146 - NSEnumerator* keysList = [productList keyEnumerator];
147 - id keyValue;
148 - while (keyValue = [keysList nextObject])
149 - {
150 - NSLog(@"i found %@",keyValue);
151 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
152 - NSLog(@"appleAmount:%@ amount:%@",appleAmount,amount);
153 - if(appleAmount.intValue == amount.intValue){
154 - return keyValue;
155 - }
156 - }
157 - }
158 - }
159 - return @"unknow";
160 -}
161 -
162 -- (void)receiveCreateOrder:(NSNotification *)notification
163 -{
164 - NSLog(@"创建订单成功");
165 - PoolPayInfo *payInfo = [notification object];
166 - NSString *queryId = [payInfo queryId];
167 - NSString *amount = [[NSString alloc]initWithFormat:@"%d",[payInfo postAmount].intValue * 100];
168 - NSString *gameId = [[PoolConfig getInstance]getValueByKey:@"gameId"];
169 - NSString *xaChannelId = [[PoolConfig getInstance]getValueByKey:@"xaChannelId"];
170 - NSString *productName = [self getProductNameByAmount:[payInfo products] amount:amount];//公共后台获取商品名称(对应游尚的商品ID(productID))
171 -
172 - NSString *other = [payInfo other];
173 -
174 - if ([@"" isEqualToString:other]) {//苹果支付
175 - [[[AppleIap alloc]init] applePay:[payInfo products] amount:[payInfo postAmount] queryId:queryId];
176 - }else{
177 - [[XiaoaoPay shareInstance]reuqrstPaytype:gameId andChannelid:xaChannelId andProductid:productName andUserid:[payInfo playerId] andServerid:[payInfo serverId] andExtra:queryId andProductName:[payInfo productName] andPrice:amount];
178 - [XiaoaoPay shareInstance].block = ^(BOOL result,NSString*payName,NSString * orederId){
179 - };
180 - }
181 -
182 -
183 -
184 -
185 -}
186 -
187 -- (void)applicationWillEnterForeground:(UIApplication *)application
188 -{
189 - //添加方法:
190 - NSLog(@"applicationWillEnterForeground");
191 - [[NSNotificationCenter defaultCenter]postNotificationName:@"closed" object:nil];
192 -}
193 -
194 -
195 --(NSString*)getCurrentTimestamp{
196 - // 时间戳转时间
197 - NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
198 - NSString* timeStr = [[NSString alloc]initWithFormat:@"%.f",interval];
199 - return timeStr;
200 -}
201 -
202 -
203 -@end
...\ No newline at end of file ...\ No newline at end of file
1 -//
2 -// UpDatePerson.h
3 -// NewLogin
4 -//
5 -// Created by 耿宇 on 16/5/11.
6 -// Copyright © 2016年 JT. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface UpDatePerson : NSObject
12 -@property(nonatomic,copy)void(^block)(NSString *);
13 --(void)updatePerson:(NSString *)nickName withGameLevel:(NSString *)gameLevel withTeamId:(NSString*)teamId;
14 -@end
1 -//
2 -// XiaoaoPay.h
3 -// xiaoAoPay
4 -//
5 -// Created by jzw on 16/12/8.
6 -// Copyright © 2016年 jzw. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface XiaoaoPay : NSObject
12 -@property(nonatomic,copy)void(^block)(BOOL,NSString*,NSString*);
13 -+(XiaoaoPay*)shareInstance;
14 --(void)reuqrstPaytype:(NSString*)gameid andChannelid:(NSString*)channelid andProductid:(NSString*)productid andUserid:(NSString*)userid andServerid:(NSString*)serverid andExtra:(NSString*)extra andProductName:(NSString *)productName andPrice:(NSString *)price;
15 -@end
1 -//
2 -// IAPHelper.h
3 -//
4 -// Original Created by Ray Wenderlich on 2/28/11.
5 -// Created by saturngod on 7/9/12.
6 -// Copyright 2011 Ray Wenderlich. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -#import "StoreKit/StoreKit.h"
11 -
12 -
13 -typedef void (^IAPProductsResponseBlock)(SKProductsRequest* request , SKProductsResponse* response);
14 -
15 -typedef void (^IAPbuyProductCompleteResponseBlock)(SKPaymentTransaction* transcation);
16 -
17 -typedef void (^checkReceiptCompleteResponseBlock)(NSString* response,NSError* error);
18 -
19 -typedef void (^resoreProductsCompleteResponseBlock) (SKPaymentQueue* payment,NSError* error);
20 -
21 -@interface IAPHelper : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver>
22 -
23 -@property (nonatomic,strong) NSSet *productIdentifiers;
24 -@property (nonatomic,strong) NSArray * products;
25 -@property (nonatomic,strong) NSMutableSet *purchasedProducts;
26 -@property (nonatomic,strong) SKProductsRequest *request;
27 -@property (nonatomic) BOOL production;
28 -
29 -//init With Product Identifiers
30 -- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers;
31 -
32 -//get Products List
33 -- (void)requestProductsWithCompletion:(IAPProductsResponseBlock)completion;
34 -
35 -
36 -//Buy Product
37 -- (void)buyProduct:(SKProduct *)productIdentifier onCompletion:(IAPbuyProductCompleteResponseBlock)completion;
38 -
39 -//restore Products
40 -- (void)restoreProductsWithCompletion:(resoreProductsCompleteResponseBlock)completion;
41 -
42 -//check isPurchased or not
43 -- (BOOL)isPurchasedProductsIdentifier:(NSString*)productID;
44 -
45 -//check receipt but recommend to use in server side instead of using this function
46 -- (void)checkReceipt:(NSData*)receiptData onCompletion:(checkReceiptCompleteResponseBlock)completion;
47 -
48 -- (void)checkReceipt:(NSData*)receiptData AndSharedSecret:(NSString*)secretKey onCompletion:(checkReceiptCompleteResponseBlock)completion;
49 -
50 -
51 -//saved purchased product
52 -- (void)provideContentWithTransaction:(SKPaymentTransaction *)transaction;
53 -
54 -- (void)provideContent:(NSString *)productIdentifier __deprecated_msg("use provideContentWithTransaction: instead.");
55 -
56 -//clear the saved products
57 -- (void)clearSavedPurchasedProducts;
58 -- (void)clearSavedPurchasedProductByID:(NSString*)productIdentifier;
59 -
60 -
61 -//Get The Price with local currency
62 -- (NSString *)getLocalePrice:(SKProduct *)product;
63 -
64 -@end
1 -//
2 -// IAPHelper.m
3 -//
4 -// Original Created by Ray Wenderlich on 2/28/11.
5 -// Created by saturngod on 7/9/12.
6 -// Copyright 2011 Ray Wenderlich. All rights reserved.
7 -//
8 -
9 -#import "IAPHelper.h"
10 -#import "NSString+Base64.h"
11 -#import "SFHFKeychainUtils.h"
12 -
13 -#if ! __has_feature(objc_arc)
14 -#error You need to either convert your project to ARC or add the -fobjc-arc compiler flag to IAPHelper.m.
15 -#endif
16 -
17 -
18 -@interface IAPHelper()
19 -@property (nonatomic,copy) IAPProductsResponseBlock requestProductsBlock;
20 -@property (nonatomic,copy) IAPbuyProductCompleteResponseBlock buyProductCompleteBlock;
21 -@property (nonatomic,copy) resoreProductsCompleteResponseBlock restoreCompletedBlock;
22 -@property (nonatomic,copy) checkReceiptCompleteResponseBlock checkReceiptCompleteBlock;
23 -
24 -@property (nonatomic,strong) NSMutableData* receiptRequestData;
25 -@end
26 -
27 -@implementation IAPHelper
28 -
29 -- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {
30 - if ((self = [super init])) {
31 -
32 - // Store product identifiers
33 - _productIdentifiers = productIdentifiers;
34 -
35 - // Check for previously purchased products
36 - NSMutableSet * purchasedProducts = [NSMutableSet set];
37 - for (NSString * productIdentifier in _productIdentifiers) {
38 -
39 - BOOL productPurchased = NO;
40 -
41 - NSString* password = [SFHFKeychainUtils getPasswordForUsername:productIdentifier andServiceName:@"IAPHelper" error:nil];
42 - if([password isEqualToString:@"YES"])
43 - {
44 - productPurchased = YES;
45 - }
46 -
47 - if (productPurchased) {
48 - [purchasedProducts addObject:productIdentifier];
49 - }
50 - }
51 - if ([SKPaymentQueue defaultQueue]) {
52 - [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
53 -
54 - self.purchasedProducts = purchasedProducts;
55 - }
56 -
57 - }
58 - return self;
59 -}
60 -
61 -- (void)dealloc
62 -{
63 - if ([SKPaymentQueue defaultQueue]) {
64 - [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
65 - }
66 -}
67 -
68 --(BOOL)isPurchasedProductsIdentifier:(NSString*)productID
69 -{
70 -
71 - BOOL productPurchased = NO;
72 -
73 - NSString* password = [SFHFKeychainUtils getPasswordForUsername:productID andServiceName:@"IAPHelper" error:nil];
74 - if([password isEqualToString:@"YES"])
75 - {
76 - productPurchased = YES;
77 - }
78 -
79 - return productPurchased;
80 -}
81 -
82 -- (void)requestProductsWithCompletion:(IAPProductsResponseBlock)completion {
83 -
84 - self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
85 - _request.delegate = self;
86 - self.requestProductsBlock = completion;
87 -
88 - [_request start];
89 -
90 -}
91 -
92 -- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
93 -
94 - self.products = response.products;
95 - self.request = nil;
96 -
97 - if(_requestProductsBlock) {
98 - _requestProductsBlock (request,response);
99 - }
100 -}
101 -
102 -- (void)recordTransaction:(SKPaymentTransaction *)transaction {
103 - // TODO: Record the transaction on the server side...
104 -}
105 -
106 -
107 -- (void)provideContentWithTransaction:(SKPaymentTransaction *)transaction {
108 -
109 - NSString* productIdentifier = @"";
110 -
111 - if (transaction.originalTransaction) {
112 - productIdentifier = transaction.originalTransaction.payment.productIdentifier;
113 - }
114 - else {
115 - productIdentifier = transaction.payment.productIdentifier;
116 - }
117 -
118 - //check productIdentifier exist or not
119 - //it can be possible nil
120 - if (productIdentifier) {
121 - [SFHFKeychainUtils storeUsername:productIdentifier andPassword:@"YES" forServiceName:@"IAPHelper" updateExisting:YES error:nil];
122 - [_purchasedProducts addObject:productIdentifier];
123 - }
124 -}
125 -
126 -- (void)provideContent:(NSString *)productIdentifier {
127 -
128 - [SFHFKeychainUtils storeUsername:productIdentifier andPassword:@"YES" forServiceName:@"IAPHelper" updateExisting:YES error:nil];
129 -
130 - [_purchasedProducts addObject:productIdentifier];
131 -
132 -
133 -}
134 -
135 -- (void)clearSavedPurchasedProducts {
136 -
137 - for (NSString * productIdentifier in _productIdentifiers) {
138 - [self clearSavedPurchasedProductByID:productIdentifier];
139 - }
140 -
141 -}
142 -- (void)clearSavedPurchasedProductByID:(NSString*)productIdentifier {
143 -
144 - [SFHFKeychainUtils deleteItemForUsername:productIdentifier andServiceName:@"IAPHelper" error:nil];
145 - [_purchasedProducts removeObject:productIdentifier];
146 -
147 -}
148 -
149 -
150 -- (void)completeTransaction:(SKPaymentTransaction *)transaction {
151 -
152 -
153 -
154 - [self recordTransaction: transaction];
155 -
156 - if ([SKPaymentQueue defaultQueue]) {
157 - [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
158 - }
159 -
160 - if(_buyProductCompleteBlock)
161 - {
162 - _buyProductCompleteBlock(transaction);
163 - }
164 -
165 -}
166 -
167 -- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
168 -
169 -
170 - [self recordTransaction: transaction];
171 - [self provideContentWithTransaction:transaction];
172 -
173 - if ([SKPaymentQueue defaultQueue]) {
174 - [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
175 -
176 -
177 - if(_buyProductCompleteBlock!=nil)
178 - {
179 - _buyProductCompleteBlock(transaction);
180 - }
181 - }
182 -
183 -}
184 -
185 -- (void)failedTransaction:(SKPaymentTransaction *)transaction {
186 -
187 - if (transaction.error.code != SKErrorPaymentCancelled)
188 - {
189 - NSLog(@"Transaction error: %@ %ld", transaction.error.localizedDescription,(long)transaction.error.code);
190 - }
191 -
192 - if ([SKPaymentQueue defaultQueue]) {
193 - [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
194 - if(_buyProductCompleteBlock) {
195 - _buyProductCompleteBlock(transaction);
196 - }
197 - }
198 -
199 -}
200 -
201 -- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
202 -{
203 -
204 -
205 - for (SKPaymentTransaction *transaction in transactions)
206 - {
207 - switch (transaction.transactionState)
208 - {
209 - case SKPaymentTransactionStatePurchased:
210 - [self completeTransaction:transaction];
211 - break;
212 - case SKPaymentTransactionStateFailed:
213 - [self failedTransaction:transaction];
214 - break;
215 - case SKPaymentTransactionStateRestored:
216 - [self restoreTransaction:transaction];
217 - default:
218 - break;
219 - }
220 - }
221 -}
222 -
223 -- (void)buyProduct:(SKProduct *)productIdentifier onCompletion:(IAPbuyProductCompleteResponseBlock)completion {
224 -
225 - self.buyProductCompleteBlock = completion;
226 -
227 - self.restoreCompletedBlock = nil;
228 - SKPayment *payment = [SKPayment paymentWithProduct:productIdentifier];
229 -
230 - if ([SKPaymentQueue defaultQueue]) {
231 - [[SKPaymentQueue defaultQueue] addPayment:payment];
232 - }
233 -
234 -}
235 -
236 --(void)restoreProductsWithCompletion:(resoreProductsCompleteResponseBlock)completion {
237 -
238 - //clear it
239 - self.buyProductCompleteBlock = nil;
240 -
241 - self.restoreCompletedBlock = completion;
242 - if ([SKPaymentQueue defaultQueue]) {
243 - [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
244 - }
245 - else {
246 - NSLog(@"Cannot get the default Queue");
247 - }
248 -
249 -
250 -}
251 -
252 -- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
253 -
254 - NSLog(@"Transaction error: %@ %ld", error.localizedDescription,(long)error.code);
255 - if(_restoreCompletedBlock) {
256 - _restoreCompletedBlock(queue,error);
257 - }
258 -}
259 -
260 -- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
261 -
262 - for (SKPaymentTransaction *transaction in queue.transactions)
263 - {
264 - switch (transaction.transactionState)
265 - {
266 - case SKPaymentTransactionStateRestored:
267 - {
268 - [self recordTransaction: transaction];
269 - [self provideContentWithTransaction:transaction];
270 -
271 - }
272 - default:
273 - break;
274 - }
275 - }
276 -
277 - if(_restoreCompletedBlock) {
278 - _restoreCompletedBlock(queue,nil);
279 - }
280 -
281 -}
282 -
283 -- (void)checkReceipt:(NSData*)receiptData onCompletion:(checkReceiptCompleteResponseBlock)completion
284 -{
285 - [self checkReceipt:receiptData AndSharedSecret:nil onCompletion:completion];
286 -}
287 -- (void)checkReceipt:(NSData*)receiptData AndSharedSecret:(NSString*)secretKey onCompletion:(checkReceiptCompleteResponseBlock)completion
288 -{
289 -
290 - self.checkReceiptCompleteBlock = completion;
291 -
292 - NSError *jsonError = nil;
293 - NSString *receiptBase64 = [NSString base64StringFromData:receiptData length:[receiptData length]];
294 -
295 -
296 - NSData *jsonData = nil;
297 -
298 - if(secretKey !=nil && ![secretKey isEqualToString:@""]) {
299 -
300 - jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithObjectsAndKeys:receiptBase64,@"receipt-data",
301 - secretKey,@"password",
302 - nil]
303 - options:NSJSONWritingPrettyPrinted
304 - error:&jsonError];
305 -
306 - }
307 - else {
308 - jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithObjectsAndKeys:
309 - receiptBase64,@"receipt-data",
310 - nil]
311 - options:NSJSONWritingPrettyPrinted
312 - error:&jsonError
313 - ];
314 - }
315 -
316 -
317 -// NSString* jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
318 -
319 - NSURL *requestURL = nil;
320 - if(_production)
321 - {
322 - requestURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
323 - }
324 - else {
325 - requestURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
326 - }
327 -
328 - NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:requestURL];
329 - [req setHTTPMethod:@"POST"];
330 - [req setHTTPBody:jsonData];
331 -
332 - NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
333 - if(conn) {
334 - self.receiptRequestData = [[NSMutableData alloc] init];
335 - } else {
336 - NSError* error = nil;
337 - NSMutableDictionary* errorDetail = [[NSMutableDictionary alloc] init];
338 - [errorDetail setValue:@"Can't create connection" forKey:NSLocalizedDescriptionKey];
339 - error = [NSError errorWithDomain:@"IAPHelperError" code:100 userInfo:errorDetail];
340 - if(_checkReceiptCompleteBlock) {
341 - _checkReceiptCompleteBlock(nil,error);
342 - }
343 - }
344 -}
345 -
346 --(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
347 - NSLog(@"Cannot transmit receipt data. %@",[error localizedDescription]);
348 -
349 - if(_checkReceiptCompleteBlock) {
350 - _checkReceiptCompleteBlock(nil,error);
351 - }
352 -
353 -}
354 -
355 --(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
356 - [self.receiptRequestData setLength:0];
357 -}
358 -
359 --(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
360 - [self.receiptRequestData appendData:data];
361 -}
362 -
363 --(void)connectionDidFinishLoading:(NSURLConnection *)connection {
364 - NSString *response = [[NSString alloc] initWithData:self.receiptRequestData encoding:NSUTF8StringEncoding];
365 -
366 - if(_checkReceiptCompleteBlock) {
367 - _checkReceiptCompleteBlock(response,nil);
368 - }
369 -}
370 -
371 -
372 -- (NSString *)getLocalePrice:(SKProduct *)product {
373 - if (product) {
374 - NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
375 - [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
376 - [formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
377 - [formatter setLocale:product.priceLocale];
378 -
379 - return [formatter stringFromNumber:product.price];
380 - }
381 - return @"";
382 -
383 -
384 -}
385 -@end
1 -//
2 -// IAPShare.h
3 -// ;
4 -//
5 -// Created by Htain Lin Shwe on 10/7/12.
6 -// Copyright (c) 2012 Edenpod. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -#import "IAPHelper.h"
11 -@interface IAPShare : NSObject
12 -@property (nonatomic,strong) IAPHelper *iap;
13 -
14 -+ (IAPShare *) sharedHelper;
15 -
16 -+(id)toJSON:(NSString*)json;
17 -@end
1 -//
2 -// IAPShare.m
3 -// inappPurchasesTest
4 -//
5 -// Created by Htain Lin Shwe on 10/7/12.
6 -// Copyright (c) 2012 Edenpod. All rights reserved.
7 -//
8 -
9 -#import "IAPShare.h"
10 -
11 -#if ! __has_feature(objc_arc)
12 -#error You need to either convert your project to ARC or add the -fobjc-arc compiler flag to IAPShare.m.
13 -#endif
14 -
15 -@implementation IAPShare
16 -@synthesize iap= _iap;
17 -
18 -+ (IAPShare *) sharedHelper {
19 - static IAPShare * _sharedHelper = nil;
20 - static dispatch_once_t onceToken;
21 - dispatch_once(&onceToken, ^{
22 - _sharedHelper = [[IAPShare alloc] init];
23 - _sharedHelper.iap = nil;
24 - });
25 - return _sharedHelper;
26 -}
27 -
28 -+(id)toJSON:(NSString *)json
29 -{
30 - NSError* e = nil;
31 - id jsonObject = [NSJSONSerialization JSONObjectWithData: [json dataUsingEncoding:NSUTF8StringEncoding]
32 - options: NSJSONReadingMutableContainers
33 - error: &e];
34 -
35 - if(e==nil) {
36 - return jsonObject;
37 - }
38 - else {
39 - NSLog(@"%@",[e localizedDescription]);
40 - return nil;
41 - }
42 -
43 -}
44 -
45 -@end
1 -//
2 -// NSString+Base64.h
3 -// Newsstand
4 -//
5 -// Created by Carlo Vigiani on 29/Oct/11.
6 -// Copyright (c) 2011 viggiosoft. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface NSString (Base64)
12 -
13 -+ (NSString *) base64StringFromData:(NSData *)data length:(long)length;
14 -
15 -@end
1 -//
2 -// NSString+Base64.m
3 -// Newsstand
4 -//
5 -// Created by Carlo Vigiani on 29/Oct/11.
6 -// Copyright (c) 2011 viggiosoft. All rights reserved.
7 -//
8 -
9 -#import "NSString+Base64.h"
10 -
11 -static char base64EncodingTable[64] = {
12 - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
13 - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
14 - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
15 - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
16 -};
17 -
18 -@implementation NSString (Base64)
19 -
20 -
21 -+ (NSString *) base64StringFromData:(NSData *)data length:(long)length {
22 - unsigned long ixtext, lentext;
23 - long ctremaining;
24 - unsigned char input[3], output[4];
25 - short i, charsonline = 0, ctcopy;
26 - const unsigned char *raw;
27 - NSMutableString *result;
28 -
29 - lentext = [data length];
30 - if (lentext < 1)
31 - return @"";
32 - result = [NSMutableString stringWithCapacity: lentext];
33 - raw = [data bytes];
34 - ixtext = 0;
35 -
36 - while (true) {
37 - ctremaining = lentext - ixtext;
38 - if (ctremaining <= 0)
39 - break;
40 - for (i = 0; i < 3; i++) {
41 - unsigned long ix = ixtext + i;
42 - if (ix < lentext)
43 - input[i] = raw[ix];
44 - else
45 - input[i] = 0;
46 - }
47 - output[0] = (input[0] & 0xFC) >> 2;
48 - output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
49 - output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
50 - output[3] = input[2] & 0x3F;
51 - ctcopy = 4;
52 - switch (ctremaining) {
53 - case 1:
54 - ctcopy = 2;
55 - break;
56 - case 2:
57 - ctcopy = 3;
58 - break;
59 - }
60 -
61 - for (i = 0; i < ctcopy; i++)
62 - [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
63 -
64 - for (i = ctcopy; i < 4; i++)
65 - [result appendString: @"="];
66 -
67 - ixtext += 3;
68 - charsonline += 4;
69 -
70 - if ((length > 0) && (charsonline >= length))
71 - charsonline = 0;
72 - }
73 - return result;
74 -}
75 -
76 -
77 -@end
1 -//
2 -// SFHFKeychainUtils.h
3 -//
4 -// Created by Buzz Andersen on 10/20/08.
5 -// Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone.
6 -// Copyright 2008 Sci-Fi Hi-Fi. All rights reserved.
7 -//
8 -// Permission is hereby granted, free of charge, to any person
9 -// obtaining a copy of this software and associated documentation
10 -// files (the "Software"), to deal in the Software without
11 -// restriction, including without limitation the rights to use,
12 -// copy, modify, merge, publish, distribute, sublicense, and/or sell
13 -// copies of the Software, and to permit persons to whom the
14 -// Software is furnished to do so, subject to the following
15 -// conditions:
16 -//
17 -// The above copyright notice and this permission notice shall be
18 -// included in all copies or substantial portions of the Software.
19 -//
20 -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 -// OTHER DEALINGS IN THE SOFTWARE.
28 -//
29 -
30 -#import <UIKit/UIKit.h>
31 -
32 -
33 -@interface SFHFKeychainUtils : NSObject {
34 -
35 -}
36 -
37 -+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error;
38 -+ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error;
39 -+ (BOOL) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error;
40 -
41 -@end
...\ No newline at end of file ...\ No newline at end of file
1 -//
2 -// SFHFKeychainUtils.m
3 -//
4 -
5 -// Created by Buzz Andersen on 10/20/08.
6 -// Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone.
7 -// Copyright 2008 Sci-Fi Hi-Fi. All rights reserved.
8 -//
9 -
10 -// Permission is hereby granted, free of charge, to any person
11 -// obtaining a copy of this software and associated documentation
12 -// files (the "Software"), to deal in the Software without
13 -// restriction, including without limitation the rights to use,
14 -// copy, modify, merge, publish, distribute, sublicense, and/or sell
15 -// copies of the Software, and to permit persons to whom the
16 -// Software is furnished to do so, subject to the following
17 -// conditions:
18 -//
19 -
20 -// The above copyright notice and this permission notice shall be
21 -// included in all copies or substantial portions of the Software.
22 -//
23 -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25 -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28 -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 -// OTHER DEALINGS IN THE SOFTWARE.
31 -//
32 -
33 -#import "SFHFKeychainUtils.h"
34 -#import <Security/Security.h>
35 -
36 -
37 -static NSString *SFHFKeychainUtilsErrorDomain = @"SFHFKeychainUtilsErrorDomain";
38 -
39 -#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR
40 -
41 -@interface SFHFKeychainUtils (PrivateMethods)
42 -(SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error;
43 -@end
44 -
45 -#endif
46 -
47 -@implementation SFHFKeychainUtils
48 -
49 -#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR
50 -
51 -+(NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error {
52 - if (!username || !serviceName) {
53 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
54 - return nil;
55 - }
56 -
57 - SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername: username andServiceName: serviceName error: error];
58 - if (*error || !item) {
59 - return nil;
60 - }
61 -
62 - // from Advanced Mac OS X Programming, ch. 16
63 - UInt32 length;
64 - char *password;
65 - SecKeychainAttribute attributes[8];
66 - SecKeychainAttributeList list;
67 - attributes[0].tag = kSecAccountItemAttr;
68 - attributes[1].tag = kSecDescriptionItemAttr;
69 - attributes[2].tag = kSecLabelItemAttr;
70 - attributes[3].tag = kSecModDateItemAttr;
71 - list.count = 4;
72 - list.attr = attributes;
73 - OSStatus status = SecKeychainItemCopyContent(item, NULL, &list, &length, (void **)&password);
74 - if (status != noErr) {
75 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
76 - return nil;
77 - }
78 - NSString *passwordString = nil;
79 - if (password != NULL) {
80 - char passwordBuffer[1024];
81 - if (length > 1023) {
82 - length = 1023;
83 - }
84 - strncpy(passwordBuffer, password, length);
85 - passwordBuffer[length] = '\0';
86 - passwordString = [NSString stringWithCString:passwordBuffer];
87 - }
88 - SecKeychainItemFreeContent(&list, password);
89 - CFRelease(item);
90 - return passwordString;
91 -}
92 -
93 -+ (void) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error {
94 -
95 - if (!username || !password || !serviceName) {
96 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
97 - return;
98 - }
99 - OSStatus status = noErr;
100 - SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername: username andServiceName: serviceName error: error];
101 - if (*error && [*error code] != noErr) {
102 - return;
103 - }
104 - *error = nil;
105 -
106 - if (item) {
107 - status = SecKeychainItemModifyAttributesAndData(item,NULL,strlen([password UTF8String]),[password UTF8String]);
108 - CFRelease(item);
109 - }
110 - else {
111 - status = SecKeychainAddGenericPassword(NULL,strlen([serviceName UTF8String]),[serviceName UTF8String],strlen([username UTF8String]),[username UTF8String],strlen([password UTF8String]),[password UTF8String],NULL);
112 -
113 - }
114 - if (status != noErr) {
115 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
116 - }
117 -}
118 -
119 -+ (void) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error {
120 - if (!username || !serviceName) {
121 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: 2000 userInfo: nil];
122 - return;
123 - }
124 -
125 - *error = nil;
126 -
127 - SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername: username andServiceName: serviceName error: error];
128 - if (*error && [*error code] != noErr) {
129 - return;
130 - }
131 -
132 - OSStatus status;
133 - if (item) {
134 - status = SecKeychainItemDelete(item);
135 - CFRelease(item);
136 - }
137 -
138 - if (status != noErr) {
139 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
140 - }
141 -}
142 -
143 -+ (SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error {
144 - if (!username || !serviceName) {
145 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
146 - return nil;
147 - }
148 -
149 - *error = nil;
150 - SecKeychainItemRef item;
151 - OSStatus status = SecKeychainFindGenericPassword(NULL,strlen([serviceName UTF8String]),[serviceName UTF8String],strlen([username UTF8String]),[username UTF8String], NULL,NULL,&item);
152 -
153 - if (status != noErr) {
154 - if (status != errSecItemNotFound) {
155 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
156 - }
157 - return nil;
158 - }
159 - return item;
160 -}
161 -
162 -#else
163 -
164 -+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error {
165 -
166 - if (!username || !serviceName) {
167 - if (error != nil) {
168 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
169 - }
170 - return nil;
171 - }
172 -
173 - if (error != nil) {
174 - *error = nil;
175 - }
176 - // Set up a query dictionary with the base query attributes: item type (generic), username, and service
177 - NSArray *keys = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClass, kSecAttrAccount, kSecAttrService, nil];
178 - NSArray *objects = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClassGenericPassword, username, serviceName, nil];
179 - NSMutableDictionary *query = [[NSMutableDictionary alloc] initWithObjects: objects forKeys: keys];
180 - // First do a query for attributes, in case we already have a Keychain item with no password data set.
181 - // One likely way such an incorrect item could have come about is due to the previous (incorrect)
182 - // version of this code (which set the password as a generic attribute instead of password data).
183 - NSMutableDictionary *attributeQuery = [query mutableCopy];
184 - [attributeQuery setObject: (id) kCFBooleanTrue forKey:(__bridge_transfer id) kSecReturnAttributes];
185 - CFTypeRef attrResult = NULL;
186 - OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) attributeQuery, &attrResult);
187 - //NSDictionary *attributeResult = (__bridge_transfer NSDictionary *)attrResult;
188 - if (status != noErr) {
189 - // No existing item found--simply return nil for the password
190 - if (error != nil && status != errSecItemNotFound) {
191 - //Only return an error if a real exception happened--not simply for "not found."
192 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
193 - }
194 - return nil;
195 - }
196 -
197 - // We have an existing item, now query for the password data associated with it.
198 - NSMutableDictionary *passwordQuery = [query mutableCopy];
199 - [passwordQuery setObject: (id) kCFBooleanTrue forKey: (__bridge_transfer id) kSecReturnData];
200 - CFTypeRef resData = NULL;
201 - status = SecItemCopyMatching((__bridge CFDictionaryRef) passwordQuery, (CFTypeRef *) &resData);
202 - NSData *resultData = (__bridge_transfer NSData *)resData;
203 - if (status != noErr) {
204 - if (status == errSecItemNotFound) {
205 - // We found attributes for the item previously, but no password now, so return a special error.
206 - // Users of this API will probably want to detect this error and prompt the user to
207 - // re-enter their credentials. When you attempt to store the re-entered credentials
208 - // using storeUsername:andPassword:forServiceName:updateExisting:error
209 - // the old, incorrect entry will be deleted and a new one with a properly encrypted
210 - // password will be added.
211 -
212 - if (error != nil) {
213 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -1999 userInfo: nil];
214 - }
215 - }
216 - else {
217 - // Something else went wrong. Simply return the normal Keychain API error code.
218 - if (error != nil) {
219 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
220 - }
221 - }
222 - return nil;
223 - }
224 - NSString *password = nil;
225 - if (resultData) {
226 - password = [[NSString alloc] initWithData: resultData encoding: NSUTF8StringEncoding];
227 - }
228 - else {
229 - // There is an existing item, but we weren't able to get password data for it for some reason,
230 - // Possibly as a result of an item being incorrectly entered by the previous code.
231 - // Set the -1999 error so the code above us can prompt the user again.
232 -
233 - if (error != nil) {
234 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -1999 userInfo: nil];
235 - }
236 - }
237 - return password;
238 -}
239 -
240 -+ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error
241 -
242 -{
243 - if (!username || !password || !serviceName)
244 -
245 - {
246 - if (error != nil)
247 - {
248 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
249 - }
250 - return NO;
251 - }
252 -
253 - // See if we already have a password entered for these credentials.
254 -
255 - NSError *getError = nil;
256 - NSString *existingPassword = [SFHFKeychainUtils getPasswordForUsername: username andServiceName: serviceName error:&getError];
257 -
258 - if ([getError code] == -1999)
259 - {
260 - // There is an existing entry without a password properly stored (possibly as a result of the previous incorrect version of this code.
261 -
262 - // Delete the existing item before moving on entering a correct one.
263 - getError = nil;
264 -
265 - [self deleteItemForUsername: username andServiceName: serviceName error: &getError];
266 -
267 - if ([getError code] != noErr)
268 - {
269 - if (error != nil)
270 - {
271 - *error = getError;
272 - }
273 - return NO;
274 - }
275 - }
276 - else if ([getError code] != noErr)
277 - {
278 - if (error != nil)
279 - {
280 - *error = getError;
281 - }
282 - return NO;
283 - }
284 - if (error != nil)
285 - {
286 - *error = nil;
287 - }
288 -
289 - OSStatus status = noErr;
290 -
291 - if (existingPassword)
292 - {
293 -
294 - // We have an existing, properly entered item with a password.
295 - // Update the existing item.
296 -
297 - if (![existingPassword isEqualToString:password] && updateExisting)
298 - {
299 - //Only update if we're allowed to update existing. If not, simply do nothing.
300 -
301 - NSArray *keys = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClass,kSecAttrService,kSecAttrLabel,kSecAttrAccount,nil];
302 -
303 - NSArray *objects = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClassGenericPassword,serviceName,serviceName,username,nil];
304 -
305 - NSDictionary *query = [[NSDictionary alloc] initWithObjects: objects forKeys: keys];
306 -
307 - status = SecItemUpdate((__bridge CFDictionaryRef) query, (__bridge CFDictionaryRef) [NSDictionary dictionaryWithObject: [password dataUsingEncoding: NSUTF8StringEncoding] forKey: (__bridge_transfer NSString *) kSecValueData]);
308 - }
309 - }
310 - else
311 - {
312 - // No existing entry (or an existing, improperly entered, and therefore now
313 -
314 - // deleted, entry). Create a new entry.
315 -
316 -
317 - NSArray *keys = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClass,kSecAttrService,kSecAttrLabel,kSecAttrAccount,kSecValueData,nil];
318 -
319 - NSArray *objects = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClassGenericPassword,serviceName,serviceName,username,[password dataUsingEncoding: NSUTF8StringEncoding],nil];
320 -
321 - NSDictionary *query = [[NSDictionary alloc] initWithObjects: objects forKeys: keys];
322 -
323 - status = SecItemAdd((__bridge CFDictionaryRef) query, NULL);
324 - }
325 - if (error != nil && status != noErr)
326 - {
327 - // Something went wrong with adding the new item. Return the Keychain error code.
328 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
329 - return NO;
330 - }
331 - return YES;
332 -}
333 -
334 -+ (BOOL) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error
335 -{
336 - if (!username || !serviceName)
337 - {
338 - if (error != nil)
339 - {
340 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
341 - }
342 - return NO;
343 - }
344 - if (error != nil)
345 - {
346 - *error = nil;
347 - }
348 - NSArray *keys = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClass, kSecAttrAccount, kSecAttrService, kSecReturnAttributes, nil];
349 - NSArray *objects = [[NSArray alloc] initWithObjects: (__bridge_transfer NSString *) kSecClassGenericPassword, username, serviceName, kCFBooleanTrue, nil];
350 - NSDictionary *query = [[NSDictionary alloc] initWithObjects: objects forKeys: keys];
351 - OSStatus status = SecItemDelete((__bridge CFDictionaryRef) query);
352 -
353 - if (error != nil && status != noErr)
354 - {
355 - *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
356 - return NO;
357 - }
358 - return YES;
359 -}
360 -#endif
361 -@end
...\ No newline at end of file ...\ No newline at end of file
1 -{"gtAppId": "3271E2986B984E5D83C94471C63292A9", "gameId": "1113", "payorderurl": "https://public.sdk.gzyouai.com/paycheck/create", "usertype": 189, "sdkSimpleName": "youshang_ios", "gamechannelid": "9628", "xaChannelId": "9628", "custom": "{}", "sdkVersionCode": "V1_0_0", "loginCheckUrl": "https://public.sdk.gzyouai.com/logincheck/check", "appScheme": "com.xiaoao.xsqy", "c2": "", "c1": "", "adAppId": "1313CF7DE9604F1AA262B78D5D0F45C0", "paycheckurl": "https://public.sdk.gzyouai.com/paycheck/confirm", "gameSimpleName": "fytx_test"}
...\ No newline at end of file ...\ No newline at end of file
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>UIStatusBarHidden</key>
6 - <true/>
7 - <key>UIViewControllerBasedStatusBarAppearance</key>
8 - <false/>
9 -</dict>
10 -</plist>
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 -<plist version="1.0">
4 -<dict>
5 - <key>ProjectID</key>
6 - <string>1</string>
7 - <key>devEnv</key>
8 - <string>65094646</string>
9 -</dict>
10 -</plist>
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/en.lproj/InfoPlist.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/en.lproj/InfoPlist.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/en.lproj/Localizable.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/en.lproj/Localizable.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ko.lproj/InfoPlist.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ko.lproj/InfoPlist.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ko.lproj/Localizable.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ko.lproj/Localizable.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ru.lproj/InfoPlist.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ru.lproj/InfoPlist.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ru.lproj/Localizable.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/ru.lproj/Localizable.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hans.lproj/InfoPlist.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hans.lproj/InfoPlist.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hans.lproj/Localizable.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hans.lproj/Localizable.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hant.lproj/InfoPlist.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hant.lproj/InfoPlist.strings and /dev/null differ
......
1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hant.lproj/Localizable.strings and /dev/null differ 1 Binary files a/PoolSdk_Demo/poolsdk_file/poolsdk_zhongshouyou/SDK/LuckBundle.bundle/zh-Hant.lproj/Localizable.strings and /dev/null differ
......
1 -//
2 -// LuckIAPManage.h
3 -// luck
4 -//
5 -// Created by CaiShengWei on 15/7/30.
6 -// Copyright (c) 2015年 William. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -//支付成功通知
12 -extern NSString * const kLuckIAPPayResultSuccessNotification;
13 -//支付失败通知
14 -extern NSString * const kLuckIAPPayResultFailNotification;
15 -//恢复成功通知
16 -extern NSString * const kLuckIAPRestoreSuccessNotification;
17 -
18 -
19 -@interface LuckIAPManage : NSObject
20 -
21 -/**
22 - * IAP支付单例
23 - */
24 -+ (LuckIAPManage *) defaultManage;
25 -
26 -
27 -/**
28 - * IAP支付
29 - *
30 - * @param roleName 游戏角色
31 - * @param roleId 角色ID
32 - * @param server 游戏区服
33 - * @param serverId 服务器ID
34 - * @param feePointId 计费点ID(纯数字)
35 - * @param goodName 商品名称
36 - * @param goodDesc 商品描述
37 - * @param callBackInfo 厂商自定义参数
38 - *
39 - */
40 -- (void)startPayWithRoleName:(NSString *)roleName
41 - roleId:(NSString *)roleId
42 - server:(NSString *)server
43 - serverId:(NSString *)serverId
44 - feePointId:(NSString *)feePointId
45 - goodName:(NSString *)goodName
46 - goodDesc:(NSString *)goodDesc
47 - callBackInfo:(NSString *)callBackInfo;
48 -
49 -
50 -/**
51 - * 恢复购买(非消耗品和自动续订恢复)
52 - *
53 - * @param roleName 游戏角色
54 - * @param roleId 角色ID
55 - * @param server 游戏区服
56 - * @param serverId 服务器ID
57 - * @param callBackInfo 厂商自定义参数
58 - */
59 -- (void)restoreTransactionsRoleName:(NSString *)roleName
60 - roleId:(NSString *)roleId
61 - server:(NSString *)server
62 - serverId:(NSString *)serverId
63 - callBackInfo:(NSString *)callBackInfo;
64 -
65 -@end
1 -//
2 -// LuckLoginManage.h
3 -// LuckNewDemo
4 -//
5 -// Created by CaiShengWei on 15/7/22.
6 -// Copyright (c) 2015年 luck. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -@interface LuckLoginManage : NSObject
12 -
13 -//使用单例类,方便在全局控制
14 -+ (LuckLoginManage *)defaultManage;
15 -
16 -
17 -//隐藏显示提示框登录界面
18 -- (void)showLoginAlertView;
19 -- (void)hideLoginAlertView;
20 -
21 -//显示隐藏控制器登录界面
22 -- (void)showLoginViewController;
23 -- (void)hideLoginViewController;
24 -
25 -//显示隐藏浮动图标(单机游戏不要显示浮标)
26 -- (void)showFloatMenuView;
27 -- (void)hideFloatMenuView;
28 -
29 -//显示游戏客服
30 -- (void)showGameServiceView;
31 -
32 -//显示评价页面(该接口实现由苹果控制,每年展示3次,iOS10.3以上才能使用)
33 -- (void)showEvaluateView;
34 -
35 -/**显示绑定手机视图*/
36 -- (void)showBindingPhoneView;
37 -
38 -/**绑定手机成功的通知 会传递手机号码*/
39 -extern NSString * const kLuckBlindingPhoneSuccessNotification;
40 -
41 -/**
42 - * 提交用户角色信息
43 - * 参数配置
44 - * @param role 游戏角色(必填)
45 - * @param roleId 角色Id
46 - * @param server 游戏区服(必填)
47 - * @param serverId 游戏服务器ID
48 - * @param callBackInfo 厂商自定义参数
49 - */
50 -- (void)commitUserRoleWithRole:(NSString *)role
51 - roleId:(NSString *)roleId
52 - server:(NSString *)server
53 - serverId:(NSString *)serverId
54 - callBackInfo:(NSString *)callBackInfo;
55 -
56 -
57 -
58 -#pragma mark - 单机登录方法
59 -
60 -/**
61 - * 单机游戏切换账号
62 - */
63 -- (void)changeAccountOnSingleGame;
64 -
65 -
66 -#pragma mark - 显示论坛
67 -/**
68 - * 显示论坛
69 - */
70 -- (void)showForumViewController;
71 -
72 -
73 -@end
1 -//
2 -// LuckProject.h
3 -// luck
4 -//
5 -// Created by CaiShengWei on 15/7/30.
6 -// Copyright (c) 2015年 William. All rights reserved.
7 -//
8 -
9 -#import <Foundation/Foundation.h>
10 -
11 -/**
12 - * 枚举类型:屏幕方向
13 - */
14 -typedef NS_ENUM(NSInteger, LuckInterfaceOrientationMask) {
15 - LuckViewPortrait = 0, //竖屏(不可旋转)
16 - LuckViewLandscape, //横屏(可旋转)
17 - LuckViewLandscapeLeft, //横屏(home键在左边,不可旋转)
18 - LuckViewLandscapeRight,//横屏(home键在右边,不可旋转)
19 -};
20 -
21 -
22 -@interface LuckProject : NSObject
23 -
24 -/**
25 - * 单例模式
26 - */
27 -+ (LuckProject *) shareData;
28 -
29 -
30 -/**
31 - * 项目参数配置
32 - * @param gameName 游戏名称
33 - * @param gameVerName 游戏版本号
34 - * @param customerEmail 客服邮箱/QQ
35 - * @param customerPhone 客户电话
36 - * @param viewOrientations 屏幕方向
37 - * @param isCopyRighted YES有版权,NO无版权(是否有logo)
38 - * @param isSingleGame 是否是单机游戏
39 - */
40 -- (void)projectWithGameName:(NSString *)gameName
41 - gameVerName:(NSString *)gameVerName
42 - customerEmail:(NSString *)customerEmail
43 - customerPhone:(NSString *)customerPhone
44 - viewOrientations:(LuckInterfaceOrientationMask)viewOrientations
45 - isCopyRighted:(BOOL)isCopyRighted
46 - isSingleGame:(BOOL)isSingleGame;
47 -
48 -
49 -/**
50 - * 第三方登录回调
51 - * @param application
52 - * @param url
53 - * @param sourceApplication
54 - * @param annotation
55 - */
56 -- (BOOL)application:(UIApplication *)application
57 - openURL:(NSURL *)url
58 - sourceApplication:(NSString *)sourceApplication
59 - annotation:(id)annotation;
60 -
61 -
62 -/**
63 - * 第三方登录回调
64 - * @param application
65 - * @param url
66 - */
67 -- (BOOL)application:(UIApplication *)application
68 - handleOpenURL:(NSURL *)url;
69 -
70 -
71 -@end
1 -
2 -//
3 -// PPInterface.h
4 -// PoolSdk
5 -//
6 -// Created by winFan on 11/23/15.
7 -// Copyright (c) 2015 winFan. All rights reserved.
8 -//
9 -
10 -#import <PoolSdk/PoolSdk2.h>
11 -@interface SDKInterface : Interface
12 -
13 -@end
1 -//
2 -// UnionInterface.m
3 -// PoolSdk
4 -//
5 -// Created by winFan on 11/23/15.
6 -// Copyright (c) 2015 winFan. All rights reserved.
7 -//
8 -#include "SDKInterface.h"
9 -#import <UIKit/UIKit.h>
10 -#import <LuckSDK/LuckProject.h>
11 -#import <LuckSDK/LuckLoginManage.h>
12 -#import <LuckSDK/LuckIAPManage.h>
13 -
14 -@implementation SDKInterface : Interface
15 -
16 -/**
17 - 初始化SDK
18 -*/
19 -- (void)SDKinit:(UIViewController *) control
20 -{
21 - //必须继承
22 - [super SDKinit:control];
23 -
24 - [PoolConfig getInstance];
25 -
26 - NSString * sdkGameName = [[PoolConfig getInstance]getValueByKey:@"sdkGameName"];
27 - NSString * sdkEmail = [[PoolConfig getInstance]getValueByKey:@"sdkEmail"];
28 - NSString * sdkPhone = [[PoolConfig getInstance]getValueByKey:@"sdkPhone"];
29 -
30 - //配置项目参数
31 - [[LuckProject shareData] projectWithGameName:sdkGameName
32 - gameVerName:[[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleVersion"]
33 - customerEmail:sdkEmail
34 - customerPhone:sdkPhone
35 - viewOrientations:LuckViewLandscape
36 - isCopyRighted:NO
37 - isSingleGame:NO]; //viewOrientations (屏幕方向): CmgeViewPortrait 竖屏(不可旋转),\
38 - CmgeViewLandscape 横屏(可旋转),\ CmgeViewLandscapeLeft 横屏(home 键在左边,不可旋转),\ CmgeViewLandscapeRight 横屏 (home 键在右边,不可旋转)
39 - //isCopyRighted (是否有版权): YES有版权,NO无版权 //isSingleGame(是否是单机游戏): YES 单机游戏,NO 网游
40 -
41 - [[PoolChecker getInstance] sendNotice:PoolSDKNotificationInitSDK notiName:@"InitSuccess" statusCode:POOLSDK_NO_ERROR description:@"initSuccess" extendData:nil];
42 -
43 -
44 - //登录成功,获取登录信息(单机登录失败时也会发此通知,用户信息字典为nil)
45 - [[NSNotificationCenter defaultCenter] addObserver:self
46 - selector:@selector(loginInfo:)
47 - name:@"luckLoginInfo"
48 - object:nil];
49 - //注册成功的通知,可在此进行新用户注册的计数
50 - [[NSNotificationCenter defaultCenter] addObserver:self
51 - selector:@selector(regSuccess)
52 - name:@"luckRegisterSuccess"
53 - object:nil];
54 -
55 - //退出登录界面
56 - [[NSNotificationCenter defaultCenter] addObserver:self
57 - selector:@selector(quitLoginView)
58 - name:@"kLuckQuitLogin"
59 - object:nil];
60 -}
61 -
62 -- (NSString *)encodeParameter:(NSString *)originalPara {
63 - CFStringRef encodeParaCf = CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)originalPara, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8);
64 - NSString *encodePara = (__bridge NSString *)(encodeParaCf);
65 - CFRelease(encodeParaCf);
66 - return encodePara;
67 -}
68 -
69 -
70 -// ************************** 实现所有监听方法 ************************** //
71 -
72 -//登录成功后服务器返回的字典参数(单机登录失败时也会收到此通知,用户信息字典为nil)
73 --(void)loginInfo:(NSNotification *)value
74 -{
75 - NSDictionary *dic = [value object];
76 - NSLog(@"dic = %@",dic);
77 -
78 - //用户帐号
79 - //NSString * luckUserAccount =[NSString stringWithFormat:@"%@",[dic objectForKey:@"a"]];
80 - //用户ID
81 - NSString * luckUserId =[NSString stringWithFormat:@"%@", [dic objectForKey:@"b"]];
82 - //服务器当前时间戳
83 - NSString * luckTimestamp = [NSString stringWithFormat:@"%@",[dic objectForKey:@"d"]];
84 - //MD5(userId&timestamp&appkey)
85 - NSString * luckSign = [NSString stringWithFormat:@"%@", [self encodeParameter:[dic objectForKey:@"e"]]];
86 -
87 - PoolLoginInfo *loginInfo = [[PoolLoginInfo alloc]init];
88 - loginInfo.openId = luckUserId;//渠道userId
89 - loginInfo.timestamp = luckTimestamp;
90 - loginInfo.sign = luckSign;//渠道SDK的token
91 - dispatch_async(dispatch_get_global_queue(0, 0), ^{
92 - [[PoolChecker getInstance]startCheck:loginInfo];//登录验证请求
93 - });
94 -
95 -
96 - /*******网游 登录成功后,显示浮标*******/
97 - [[LuckLoginManage defaultManage] showFloatMenuView];
98 -}
99 -
100 -//退出登录界面
101 --(void)quitLoginView
102 -{
103 - NSLog(@"sdk 退出登录界面");
104 -}
105 -
106 -//注册成功后的操作
107 --(void)regSuccess
108 -{
109 - NSLog(@"sdk 注册成功");
110 -}
111 -
112 -#pragma mark - 第三方支付回调
113 -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
114 -{
115 - return [[LuckProject shareData]application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
116 -}
117 -
118 -- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
119 - return [[LuckProject shareData] application:application handleOpenURL:url];
120 -
121 -}
122 -
123 -
124 -#pragma mark - sdk操作
125 -/**
126 - 登录SDK
127 - */
128 -- (void)SDKloginSDK
129 -{
130 - NSLog(@"调用了LoginSDK");
131 -
132 - //全屏模式登录界面
133 - //[[LuckLoginManage defaultManage] showLoginViewController];
134 -
135 - //半透明登录
136 - [[LuckLoginManage defaultManage] showLoginAlertView];
137 -}
138 -
139 -- (void)SDKreport:(PoolReportInfo *)reportInfo
140 -{
141 - NSLog(@"reportInfo");
142 - if ([REPORT_CREATEROLE isEqualToString:[reportInfo reportType]]) {
143 -
144 - }else if ([[reportInfo reportType] isEqualToString:REPORT_ENTER]) {
145 -
146 - //提交用户角色信息
147 - [[LuckLoginManage defaultManage] commitUserRoleWithRole:[reportInfo playerName]
148 - roleId:[reportInfo playerId]
149 - server:[reportInfo serverName]
150 - serverId:[reportInfo serverId]
151 - callBackInfo:@""];
152 - }
153 -}
154 -
155 -
156 -/**
157 - @return 商品名称
158 - */
159 -- (NSString*)getProductNameByAmount:(NSString*)products amount:(NSString*)amount
160 -{
161 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
162 - if(jsonData){
163 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
164 - if(productList){
165 - NSEnumerator* keysList = [productList keyEnumerator];
166 - id keyValue;
167 - while (keyValue = [keysList nextObject])
168 - {
169 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
170 - if(appleAmount.intValue == amount.intValue){
171 - NSString* productName = [[productList objectForKey:keyValue] objectForKey:@"name"];
172 - return productName;
173 - }
174 - }
175 - }
176 - }
177 - NSLog(@"get product name error amount:%@",amount);
178 - return @"元宝";
179 -}
180 -
181 -/**
182 - @return 商品ID
183 - */
184 -- (NSString*)getProductIdByAmount:(NSString*)products amount:(NSString*)amount
185 -{
186 - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:products options:NSJSONWritingPrettyPrinted error:nil];
187 - if(jsonData){
188 - NSDictionary* productList = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
189 - if(productList){
190 - NSEnumerator* keysList = [productList keyEnumerator];
191 - id keyValue;
192 - while (keyValue = [keysList nextObject])
193 - {
194 - NSLog(@"i found %@",keyValue);
195 - NSString* appleAmount = [[productList objectForKey:keyValue] objectForKey:@"amount"];
196 - NSLog(@"appleAmount:%@ amount:%@",appleAmount,amount);
197 - if(appleAmount.intValue == amount.intValue){
198 - return keyValue;
199 - }
200 - }
201 - }
202 - }
203 - return @"unknow";
204 -}
205 -
206 -- (void)receiveCreateOrder:(NSNotification *)notification
207 -{
208 - NSLog(@"创建订单成功");
209 - PoolPayInfo *payInfo = [notification object];
210 -
211 - NSString *myamount = [payInfo postAmount];
212 - NSString *productId = [self getProductIdByAmount:payInfo.products amount:myamount];
213 - NSLog(@"commit productId:%@",productId);
214 - //IAP支付
215 - [[LuckIAPManage defaultManage] startPayWithRoleName:[payInfo playerName]
216 - roleId:[payInfo playerId]
217 - server:[payInfo serverName]
218 - serverId:[payInfo serverId]
219 - feePointId:productId
220 - goodName:[payInfo productName]
221 - goodDesc:[payInfo productDesc]
222 - callBackInfo:[payInfo queryId]];
223 -}
224 -
225 --(NSString*)getCurrentTimestamp{
226 - // 时间戳转时间
227 - NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
228 - NSString* timeStr = [[NSString alloc]initWithFormat:@"%.f",interval];
229 - return timeStr;
230 -}
231 -
232 -@end
1 -{"payorderurl": "http://183.57.76.181:9020/paycheck/create", "usertype": 187, "sdkSimpleName": "zhongshouyou", "gamechannelid": "", "custom": "{}", "sdkVersionCode": "V2_2_9", "loginCheckUrl": "http://183.57.76.181:9010/logincheck/check", "appScheme": "appScheme", "c2": "", "c1": "", "paycheckurl": "http://183.57.76.181:9020/paycheck/confirm", "gameSimpleName": "fytx_test"}
...\ No newline at end of file ...\ No newline at end of file
1 +channelRootPath = "poolsdk_file"
2 +gameProjName = 'Demo'
...\ No newline at end of file ...\ No newline at end of file
1 +# Copyright 2012 Calvin Rien
2 +#
3 +# Licensed under the Apache License, Version 2.0 (the "License");
4 +# you may not use this file except in compliance with the License.
5 +# You may obtain a copy of the License at
6 +#
7 +# http://www.apache.org/licenses/LICENSE-2.0
8 +#
9 +# Unless required by applicable law or agreed to in writing, software
10 +# distributed under the License is distributed on an "AS IS" BASIS,
11 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 +# See the License for the specific language governing permissions and
13 +# limitations under the License.
14 +
15 +# A pbxproj file is an OpenStep format plist
16 +# {} represents dictionary of key=value pairs delimited by ;
17 +# () represents list of values delimited by ,
18 +# file starts with a comment specifying the character type
19 +# // !$*UTF8*$!
20 +
21 +# when adding a file to a project, create the PBXFileReference
22 +# add the PBXFileReference's guid to a group
23 +# create a PBXBuildFile with the PBXFileReference's guid
24 +# add the PBXBuildFile to the appropriate build phase
25 +
26 +# when adding a header search path add
27 +# HEADER_SEARCH_PATHS = "path/**";
28 +# to each XCBuildConfiguration object
29 +
30 +# Xcode4 will read either a OpenStep or XML plist.
31 +# this script uses `plutil` to validate, read and write
32 +# the pbxproj file. Plutil is available in OS X 10.2 and higher
33 +# Plutil can't write OpenStep plists, so I save as XML
34 +
35 +import datetime
36 +import json
37 +import ntpath
38 +import os
39 +import plistlib
40 +import re
41 +import shutil
42 +import subprocess
43 +import uuid
44 +
45 +from UserDict import IterableUserDict
46 +from UserList import UserList
47 +
48 +regex = '[a-zA-Z0-9\\._/-]*'
49 +
50 +
51 +class PBXEncoder(json.JSONEncoder):
52 + def default(self, obj):
53 + """Tests the input object, obj, to encode as JSON."""
54 +
55 + if isinstance(obj, (PBXList, PBXDict)):
56 + return obj.data
57 +
58 + return json.JSONEncoder.default(self, obj)
59 +
60 +
61 +class PBXDict(IterableUserDict):
62 + def __init__(self, d=None):
63 + if d:
64 + d = dict([(PBXType.Convert(k), PBXType.Convert(v)) for k, v in d.items()])
65 +
66 + IterableUserDict.__init__(self, d)
67 +
68 + def __setitem__(self, key, value):
69 + IterableUserDict.__setitem__(self, PBXType.Convert(key), PBXType.Convert(value))
70 +
71 + def remove(self, key):
72 + self.data.pop(PBXType.Convert(key), None)
73 +
74 +
75 +class PBXList(UserList):
76 + def __init__(self, l=None):
77 + if isinstance(l, basestring):
78 + UserList.__init__(self)
79 + self.add(l)
80 + return
81 + elif l:
82 + l = [PBXType.Convert(v) for v in l]
83 +
84 + UserList.__init__(self, l)
85 +
86 + def add(self, value):
87 + value = PBXType.Convert(value)
88 +
89 + if value in self.data:
90 + return False
91 +
92 + self.data.append(value)
93 + return True
94 +
95 + def remove(self, value):
96 + value = PBXType.Convert(value)
97 +
98 + if value in self.data:
99 + self.data.remove(value)
100 + return True
101 + return False
102 +
103 + def __setitem__(self, key, value):
104 + UserList.__setitem__(self, PBXType.Convert(key), PBXType.Convert(value))
105 +
106 +
107 +class PBXType(PBXDict):
108 + def __init__(self, d=None):
109 + PBXDict.__init__(self, d)
110 +
111 + if 'isa' not in self:
112 + self['isa'] = self.__class__.__name__
113 + self.id = None
114 +
115 + @staticmethod
116 + def Convert(o):
117 + if isinstance(o, list):
118 + return PBXList(o)
119 + elif isinstance(o, dict):
120 + isa = o.get('isa')
121 +
122 + if not isa:
123 + return PBXDict(o)
124 +
125 + cls = globals().get(isa)
126 +
127 + if cls and issubclass(cls, PBXType):
128 + return cls(o)
129 +
130 + print 'warning: unknown PBX type: %s' % isa
131 + return PBXDict(o)
132 + else:
133 + return o
134 +
135 + @staticmethod
136 + def IsGuid(o):
137 + return re.match('^[A-F0-9]{24}$', str(o))
138 +
139 + @classmethod
140 + def GenerateId(cls):
141 + return ''.join(str(uuid.uuid4()).upper().split('-')[1:])
142 +
143 + @classmethod
144 + def Create(cls, *args, **kwargs):
145 + return cls(*args, **kwargs)
146 +
147 +
148 +class PBXFileReference(PBXType):
149 + def __init__(self, d=None):
150 + PBXType.__init__(self, d)
151 + self.build_phase = None
152 +
153 + types = {
154 + '.a': ('archive.ar', 'PBXFrameworksBuildPhase'),
155 + '.app': ('wrapper.application', None),
156 + '.s': ('sourcecode.asm', 'PBXSourcesBuildPhase'),
157 + '.c': ('sourcecode.c.c', 'PBXSourcesBuildPhase'),
158 + '.cpp': ('sourcecode.cpp.cpp', 'PBXSourcesBuildPhase'),
159 + '.framework': ('wrapper.framework', 'PBXFrameworksBuildPhase'),
160 + '.h': ('sourcecode.c.h', None),
161 + '.hpp': ('sourcecode.c.h', None),
162 + '.d': ('sourcecode.dtrace', 'PBXSourcesBuildPhase'),
163 + '.swift': ('sourcecode.swift', 'PBXSourcesBuildPhase'),
164 + '.icns': ('image.icns', 'PBXResourcesBuildPhase'),
165 + '.m': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'),
166 + '.j': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'),
167 + '.mm': ('sourcecode.cpp.objcpp', 'PBXSourcesBuildPhase'),
168 + '.nib': ('wrapper.nib', 'PBXResourcesBuildPhase'),
169 + '.plist': ('text.plist.xml', 'PBXResourcesBuildPhase'),
170 + '.json': ('text.json', 'PBXResourcesBuildPhase'),
171 + '.png': ('image.png', 'PBXResourcesBuildPhase'),
172 + '.rtf': ('text.rtf', 'PBXResourcesBuildPhase'),
173 + '.tiff': ('image.tiff', 'PBXResourcesBuildPhase'),
174 + '.txt': ('text', 'PBXResourcesBuildPhase'),
175 + '.xcodeproj': ('wrapper.pb-project', None),
176 + '.xib': ('file.xib', 'PBXResourcesBuildPhase'),
177 + '.strings': ('text.plist.strings', 'PBXResourcesBuildPhase'),
178 + '.bundle': ('wrapper.plug-in', 'PBXResourcesBuildPhase'),
179 + '.dylib': ('compiled.mach-o.dylib', 'PBXFrameworksBuildPhase'),
180 + '.xcdatamodeld': ('wrapper.xcdatamodel', 'PBXSourcesBuildPhase'),
181 + '.xcassets': ('folder.assetcatalog', 'PBXResourcesBuildPhase'),
182 + '.tbd': ('sourcecode.text-based-dylib-definition', 'PBXFrameworksBuildPhase'),
183 + }
184 +
185 + trees = [
186 + '<absolute>',
187 + '<group>',
188 + 'BUILT_PRODUCTS_DIR',
189 + 'DEVELOPER_DIR',
190 + 'SDKROOT',
191 + 'SOURCE_ROOT',
192 + ]
193 +
194 + def guess_file_type(self, ignore_unknown_type=False):
195 + self.remove('explicitFileType')
196 + self.remove('lastKnownFileType')
197 +
198 +
199 + ext = os.path.splitext(self.get('name', ''))[1]
200 + if os.path.isdir(self.get('path')) and ext not in XcodeProject.special_folders:
201 + f_type = 'folder'
202 + build_phase = None
203 + ext = ''
204 + else:
205 + f_type, build_phase = PBXFileReference.types.get(ext, ('?', 'PBXResourcesBuildPhase'))
206 +
207 + self['lastKnownFileType'] = f_type
208 + self.build_phase = build_phase
209 +
210 + if f_type == '?' and not ignore_unknown_type:
211 + print 'unknown file extension: %s' % ext
212 + print 'please add extension and Xcode type to PBXFileReference.types'
213 +
214 + return f_type
215 +
216 + def set_file_type(self, ft):
217 + self.remove('explicitFileType')
218 + self.remove('lastKnownFileType')
219 +
220 + self['explicitFileType'] = ft
221 +
222 + @classmethod
223 + def Create(cls, os_path, tree='SOURCE_ROOT', ignore_unknown_type=False):
224 + if tree not in cls.trees:
225 + print 'Not a valid sourceTree type: %s' % tree
226 + return None
227 +
228 + fr = cls()
229 + fr.id = cls.GenerateId()
230 + fr['path'] = os_path
231 + fr['name'] = os.path.split(os_path)[1]
232 + fr['sourceTree'] = '<absolute>' if os.path.isabs(os_path) else tree
233 + fr.guess_file_type(ignore_unknown_type=ignore_unknown_type)
234 +
235 + return fr
236 +
237 +
238 +class PBXBuildFile(PBXType):
239 + def set_weak_link(self, weak=False):
240 + k_settings = 'settings'
241 + k_attributes = 'ATTRIBUTES'
242 +
243 + s = self.get(k_settings)
244 +
245 + if not s:
246 + if weak:
247 + self[k_settings] = PBXDict({k_attributes: PBXList(['Weak'])})
248 +
249 + return True
250 +
251 + atr = s.get(k_attributes)
252 +
253 + if not atr:
254 + if weak:
255 + atr = PBXList()
256 + else:
257 + return False
258 +
259 + if weak:
260 + atr.add('Weak')
261 + else:
262 + atr.remove('Weak')
263 +
264 + self[k_settings][k_attributes] = atr
265 +
266 + return True
267 +
268 + def add_compiler_flag(self, flag):
269 + k_settings = 'settings'
270 + k_attributes = 'COMPILER_FLAGS'
271 +
272 + if k_settings not in self:
273 + self[k_settings] = PBXDict()
274 +
275 + if k_attributes not in self[k_settings]:
276 + self[k_settings][k_attributes] = flag
277 + return True
278 +
279 + flags = self[k_settings][k_attributes].split(' ')
280 +
281 + if flag in flags:
282 + return False
283 +
284 + flags.append(flag)
285 +
286 + self[k_settings][k_attributes] = ' '.join(flags)
287 +
288 + @classmethod
289 + def Create(cls, file_ref, weak=False):
290 + if isinstance(file_ref, PBXFileReference):
291 + file_ref = file_ref.id
292 +
293 + bf = cls()
294 + bf.id = cls.GenerateId()
295 + bf['fileRef'] = file_ref
296 +
297 + if weak:
298 + bf.set_weak_link(True)
299 +
300 + return bf
301 +
302 +
303 +class PBXGroup(PBXType):
304 + def add_child(self, ref):
305 + if not isinstance(ref, PBXDict):
306 + return None
307 +
308 + isa = ref.get('isa')
309 +
310 + if isa != 'PBXFileReference' and isa != 'PBXGroup':
311 + return None
312 +
313 + if 'children' not in self:
314 + self['children'] = PBXList()
315 +
316 + self['children'].add(ref.id)
317 +
318 + return ref.id
319 +
320 + def remove_child(self, id):
321 + if 'children' not in self:
322 + self['children'] = PBXList()
323 + return
324 +
325 + if not PBXType.IsGuid(id):
326 + id = id.id
327 +
328 + self['children'].remove(id)
329 +
330 + def has_child(self, id):
331 + if 'children' not in self:
332 + self['children'] = PBXList()
333 + return False
334 +
335 + if not PBXType.IsGuid(id):
336 + id = id.id
337 +
338 + return id in self['children']
339 +
340 + def get_name(self):
341 + path_name = os.path.split(self.get('path', ''))[1]
342 + return self.get('name', path_name)
343 +
344 + @classmethod
345 + def Create(cls, name, path=None, tree='SOURCE_ROOT'):
346 + grp = cls()
347 + grp.id = cls.GenerateId()
348 + grp['name'] = name
349 + grp['children'] = PBXList()
350 +
351 + if path:
352 + grp['path'] = path
353 + grp['sourceTree'] = tree
354 + else:
355 + grp['sourceTree'] = '<group>'
356 +
357 + return grp
358 +
359 +
360 +class PBXNativeTarget(PBXType):
361 + pass
362 +
363 +
364 +class PBXProject(PBXType):
365 + pass
366 +
367 +
368 +class PBXContainerItemProxy(PBXType):
369 + pass
370 +
371 +
372 +class PBXReferenceProxy(PBXType):
373 + pass
374 +
375 +
376 +class PBXVariantGroup(PBXType):
377 + pass
378 +
379 +
380 +class PBXTargetDependency(PBXType):
381 + pass
382 +
383 +
384 +class PBXAggregateTarget(PBXType):
385 + pass
386 +
387 +
388 +class PBXHeadersBuildPhase(PBXType):
389 + pass
390 +
391 +class XCVersionGroup(PBXType):
392 + pass
393 +
394 +class PBXBuildPhase(PBXType):
395 + def add_build_file(self, bf):
396 + if bf.get('isa') != 'PBXBuildFile':
397 + return False
398 +
399 + if 'files' not in self:
400 + self['files'] = PBXList()
401 +
402 + self['files'].add(bf.id)
403 +
404 + return True
405 +
406 + def remove_build_file(self, id):
407 + if 'files' not in self:
408 + self['files'] = PBXList()
409 + return
410 +
411 + self['files'].remove(id)
412 +
413 + def has_build_file(self, id):
414 + if 'files' not in self:
415 + self['files'] = PBXList()
416 + return False
417 +
418 + if not PBXType.IsGuid(id):
419 + id = id.id
420 +
421 + return id in self['files']
422 +
423 +
424 +class PBXFrameworksBuildPhase(PBXBuildPhase):
425 + pass
426 +
427 +
428 +class PBXResourcesBuildPhase(PBXBuildPhase):
429 + pass
430 +
431 +
432 +class PBXShellScriptBuildPhase(PBXBuildPhase):
433 + @classmethod
434 + def Create(cls, script, shell="/bin/sh", files=[], input_paths=[], output_paths=[], show_in_log = '0'):
435 + bf = cls()
436 + bf.id = cls.GenerateId()
437 + bf['files'] = files
438 + bf['inputPaths'] = input_paths
439 + bf['outputPaths'] = output_paths
440 + bf['runOnlyForDeploymentPostprocessing'] = '0';
441 + bf['shellPath'] = shell
442 + bf['shellScript'] = script
443 + bf['showEnvVarsInLog'] = show_in_log
444 +
445 + return bf
446 +
447 +
448 +class PBXSourcesBuildPhase(PBXBuildPhase):
449 + pass
450 +
451 +
452 +class PBXCopyFilesBuildPhase(PBXBuildPhase):
453 + pass
454 +
455 +
456 +class XCBuildConfiguration(PBXType):
457 + def add_search_paths(self, paths, base, key, recursive=True, escape=True):
458 + modified = False
459 +
460 + if not isinstance(paths, list):
461 + paths = [paths]
462 +
463 + if base not in self:
464 + self[base] = PBXDict()
465 +
466 + for path in paths:
467 + if recursive and not path.endswith('/**'):
468 + path = os.path.join(path, '**')
469 +
470 + if key not in self[base]:
471 + self[base][key] = PBXList()
472 + elif isinstance(self[base][key], basestring):
473 + self[base][key] = PBXList(self[base][key])
474 +
475 + if path == '$(inherited)':
476 + escape = False
477 +
478 + if escape:
479 + if self[base][key].add('"%s"' % path): # '\\"%s\\"' % path
480 + modified = True
481 + else:
482 + if self[base][key].add(path): # '\\"%s\\"' % path
483 + modified = True
484 +
485 + return modified
486 +
487 + def add_header_search_paths(self, paths, recursive=True):
488 + return self.add_search_paths(paths, 'buildSettings', 'HEADER_SEARCH_PATHS', recursive=recursive)
489 +
490 + def add_library_search_paths(self, paths, recursive=True):
491 + return self.add_search_paths(paths, 'buildSettings', 'LIBRARY_SEARCH_PATHS', recursive=recursive)
492 +
493 + def add_framework_search_paths(self, paths, recursive=True):
494 + return self.add_search_paths(paths, 'buildSettings', 'FRAMEWORK_SEARCH_PATHS', recursive=recursive)
495 +
496 + def add_other_cflags(self, flags):
497 + return self.add_flag('OTHER_CFLAGS', flags)
498 +
499 + def add_other_ldflags(self, flags):
500 + return self.add_flag('OTHER_LDFLAGS', flags)
501 +
502 + def add_flag(self, key, flags):
503 + modified = False
504 + base = 'buildSettings'
505 +
506 + if isinstance(flags, basestring):
507 + flags = PBXList(flags)
508 +
509 + if base not in self:
510 + self[base] = PBXDict()
511 +
512 + for flag in flags:
513 + if key not in self[base]:
514 + self[base][key] = PBXList()
515 + elif isinstance(self[base][key], basestring):
516 + self[base][key] = PBXList(self[base][key])
517 +
518 + if self[base][key].add(flag):
519 + self[base][key] = [e for e in self[base][key] if e]
520 + modified = True
521 +
522 + return modified
523 +
524 + def remove_flag(self, key, flags):
525 + modified = False
526 + base = 'buildSettings'
527 +
528 + if isinstance(flags, basestring):
529 + flags = PBXList(flags)
530 +
531 + if base in self: # there are flags, so we can "remove" something
532 + for flag in flags:
533 + if key not in self[base]:
534 + return False
535 + elif isinstance(self[base][key], basestring):
536 + self[base][key] = PBXList(self[base][key])
537 +
538 + if self[base][key].remove(flag):
539 + self[base][key] = [e for e in self[base][key] if e]
540 + modified = True
541 +
542 + if len(self[base][key]) == 0:
543 + self[base].pop(key, None)
544 +
545 + return modified
546 +
547 + def remove_other_ldflags(self, flags):
548 + return self.remove_flag('OTHER_LD_FLAGS', flags)
549 +
550 + # Set a single-valued flag under buildSettings
551 + def add_single_valued_flag(self, flag, value):
552 + modified = False
553 + base = 'buildSettings'
554 + key = flag
555 +
556 + if not self.has_key(base):
557 + self[base] = PBXDict()
558 + if self[base].has_key(key):
559 + if self[base][key] == value:
560 + return False
561 + self[base][key] = value
562 + modified = True
563 + return modified
564 +
565 + # Remove a single-valued flag under buildSettings
566 + def remove_single_valued_flag(self, flag):
567 + modified = False
568 + base = 'buildSettings'
569 + key = flag
570 +
571 + if self.has_key(base) and self[base].has_key(key):
572 + self[base].pop(key, None)
573 + modified = True
574 + return modified
575 +
576 +class XCConfigurationList(PBXType):
577 + pass
578 +
579 +
580 +class XcodeProject(PBXDict):
581 + plutil_path = 'plutil'
582 + special_folders = ['.bundle', '.framework', '.xcodeproj', '.xcassets', '.xcdatamodeld']
583 +
584 + def __init__(self, d=None, path=None):
585 + if not path:
586 + path = os.path.join(os.getcwd(), 'project.pbxproj')
587 +
588 + self.pbxproj_path = os.path.abspath(path)
589 + self.source_root = os.path.abspath(os.path.join(os.path.split(path)[0], '..'))
590 +
591 + IterableUserDict.__init__(self, d)
592 +
593 + self.data = PBXDict(self.data)
594 + self.objects = self.get('objects')
595 + self.modified = False
596 +
597 + root_id = self.get('rootObject')
598 +
599 + if root_id:
600 + self.root_object = self.objects[root_id]
601 + root_group_id = self.root_object.get('mainGroup')
602 + self.root_group = self.objects[root_group_id]
603 + else:
604 + print "error: project has no root object"
605 + self.root_object = None
606 + self.root_group = None
607 +
608 + for k, v in self.objects.iteritems():
609 + v.id = k
610 +
611 + def add_other_cflags(self, flags):
612 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
613 +
614 + for b in build_configs:
615 + if b.add_other_cflags(flags):
616 + self.modified = True
617 +
618 + def add_other_ldflags(self, flags):
619 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
620 +
621 + for b in build_configs:
622 + if b.add_other_ldflags(flags):
623 + self.modified = True
624 +
625 + def remove_other_ldflags(self, flags):
626 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
627 +
628 + for b in build_configs:
629 + if b.remove_other_ldflags(flags):
630 + self.modified = True
631 +
632 + def add_header_search_paths(self, paths, recursive=True):
633 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
634 +
635 + for b in build_configs:
636 + if b.add_header_search_paths(paths, recursive):
637 + self.modified = True
638 +
639 + def add_framework_search_paths(self, paths, recursive=True):
640 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
641 +
642 + for b in build_configs:
643 + if b.add_framework_search_paths(paths, recursive):
644 + self.modified = True
645 +
646 + def add_library_search_paths(self, paths, recursive=True):
647 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
648 +
649 + for b in build_configs:
650 + if b.add_library_search_paths(paths, recursive):
651 + self.modified = True
652 +
653 + def add_flags(self, pairs, configuration='All'):
654 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
655 +
656 + # iterate over all the pairs of configurations
657 + for b in build_configs:
658 + if configuration != "All" and b.get('name') != configuration :
659 + continue
660 +
661 + for k in pairs:
662 + if b.add_flag(k, pairs[k]):
663 + self.modified = True
664 +
665 + def remove_flags(self, pairs, configuration='All'):
666 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
667 +
668 + # iterate over all the pairs of configurations
669 + for b in build_configs:
670 + if configuration != "All" and b.get('name') != configuration :
671 + continue
672 + for k in pairs:
673 + if b.remove_flag(k, pairs[k]):
674 + self.modified = True
675 +
676 + # Set a single-valued flag (whereas add_flags adds a flag to a list of flags with a given key)
677 + def add_single_valued_flag(self, flag, value, configuration='All'):
678 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
679 +
680 + for b in build_configs:
681 + if configuration != "All" and b.get('name') != configuration :
682 + continue
683 +
684 + if b.add_single_valued_flag(flag, value):
685 + self.modified = True
686 +
687 + # Remove a single-valued flag (whereas remove_flags deletes a flag from a list of flags with a given key)
688 + def remove_single_valued_flag(self, flag, configuration='All'):
689 + build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration']
690 +
691 + for b in build_configs:
692 + if configuration != "All" and b.get('name') != configuration :
693 + continue
694 +
695 + if b.remove_single_valued_flag(flag):
696 + self.modified = True
697 +
698 + def get_obj(self, id):
699 + return self.objects.get(id)
700 +
701 + def get_ids(self):
702 + return self.objects.keys()
703 +
704 + def get_files_by_os_path(self, os_path, tree='SOURCE_ROOT'):
705 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference'
706 + and f.get('path') == os_path
707 + and f.get('sourceTree') == tree]
708 +
709 + return files
710 +
711 + def get_files_by_name(self, name, parent=None):
712 + if parent:
713 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference'
714 + and f.get('name') == name
715 + and parent.has_child(f)]
716 + else:
717 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference'
718 + and f.get('name') == name]
719 +
720 + return files
721 +
722 + def get_keys_for_files_by_name(self, name):
723 + keys = [key for key in self.objects if self.objects.data[key].get('name') == name
724 + and self.objects.data[key].get('isa') == 'PBXFileReference']
725 + return keys
726 +
727 +
728 + def get_build_files(self, id):
729 + files = [f for f in self.objects.values() if f.get('isa') == 'PBXBuildFile'
730 + and f.get('fileRef') == id]
731 + return files
732 +
733 + def get_groups_by_name(self, name, parent=None):
734 + if parent:
735 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'
736 + and g.get_name() == name
737 + and parent.has_child(g)]
738 + else:
739 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'
740 + and g.get_name() == name]
741 +
742 + return groups
743 +
744 + def get_or_create_group(self, name, path=None, parent=None):
745 + if not name:
746 + return None
747 +
748 + if not parent:
749 + parent = self.root_group
750 + elif not isinstance(parent, PBXGroup):
751 + # assume it's an id
752 + parent = self.objects.get(parent, self.root_group)
753 +
754 + groups = self.get_groups_by_name(name)
755 +
756 + for grp in groups:
757 + if parent.has_child(grp.id):
758 + return grp
759 +
760 + grp = PBXGroup.Create(name, path)
761 + parent.add_child(grp)
762 +
763 + self.objects[grp.id] = grp
764 +
765 + self.modified = True
766 +
767 + return grp
768 +
769 + def get_groups_by_os_path(self, path):
770 + path = os.path.abspath(path)
771 +
772 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'
773 + and os.path.abspath(g.get('path', '/dev/null')) == path]
774 +
775 + return groups
776 +
777 + def get_build_phases(self, phase_name):
778 + phases = [p for p in self.objects.values() if p.get('isa') == phase_name]
779 +
780 + return phases
781 +
782 + def get_target_by_name(self, name):
783 + targets = self.get_build_phases('PBXNativeTarget')
784 + target = None
785 + for t in targets:
786 + if t.get("name") == name:
787 + target = t
788 + break
789 + return target
790 +
791 + def get_relative_path(self, os_path):
792 + return os.path.relpath(os_path, self.source_root)
793 +
794 + def verify_files(self, file_list, parent=None):
795 + # returns list of files not in the current project.
796 + if not file_list:
797 + return []
798 +
799 + if parent:
800 + exists_list = [f.get('name') for f in self.objects.values() if f.get('isa') == 'PBXFileReference' and f.get('name') in file_list and parent.has_child(f)]
801 + else:
802 + exists_list = [f.get('name') for f in self.objects.values() if f.get('isa') == 'PBXFileReference' and f.get('name') in file_list]
803 +
804 + return set(file_list).difference(exists_list)
805 +
806 + def add_run_script(self, target, script=None, insert_before_compile=False):
807 + result = []
808 + targets = [t for t in self.get_build_phases('PBXNativeTarget') + self.get_build_phases('PBXAggregateTarget') if t.get('name') == target]
809 + if len(targets) != 0 :
810 + script_phase = PBXShellScriptBuildPhase.Create(script)
811 + for t in targets:
812 + skip = False
813 + for buildPhase in t['buildPhases']:
814 + if self.objects[buildPhase].get('isa') == 'PBXShellScriptBuildPhase' and self.objects[buildPhase].get('shellScript') == script:
815 + skip = True
816 +
817 + if not skip:
818 + if insert_before_compile:
819 + t['buildPhases'].insert(0, script_phase.id)
820 + else:
821 + t['buildPhases'].add(script_phase.id)
822 + self.objects[script_phase.id] = script_phase
823 + result.append(script_phase)
824 +
825 + return result
826 +
827 + def add_run_script_all_targets(self, script=None):
828 + result = []
829 + targets = self.get_build_phases('PBXNativeTarget') + self.get_build_phases('PBXAggregateTarget')
830 + if len(targets) != 0 :
831 + script_phase = PBXShellScriptBuildPhase.Create(script)
832 + for t in targets:
833 + skip = False
834 + for buildPhase in t['buildPhases']:
835 + if self.objects[buildPhase].get('isa') == 'PBXShellScriptBuildPhase' and self.objects[buildPhase].get('shellScript') == script:
836 + skip = True
837 +
838 + if not skip:
839 + t['buildPhases'].add(script_phase.id)
840 + self.objects[script_phase.id] = script_phase
841 + result.append(script_phase)
842 +
843 + return result
844 +
845 + def add_folder(self, os_path, parent=None, excludes=None, recursive=True, create_build_files=True):
846 + if not os.path.isdir(os_path):
847 + return []
848 +
849 + if not excludes:
850 + excludes = []
851 +
852 + results = []
853 +
854 + if not parent:
855 + parent = self.root_group
856 + elif not isinstance(parent, PBXGroup):
857 + # assume it's an id
858 + parent = self.objects.get(parent, self.root_group)
859 +
860 + path_dict = {os.path.split(os_path)[0]: parent}
861 + special_list = []
862 +
863 + for (grp_path, subdirs, files) in os.walk(os_path):
864 + parent_folder, folder_name = os.path.split(grp_path)
865 + parent = path_dict.get(parent_folder, parent)
866 +
867 + if [sp for sp in special_list if parent_folder.startswith(sp)]:
868 + continue
869 +
870 + if folder_name.startswith('.'):
871 + special_list.append(grp_path)
872 + continue
873 +
874 + if os.path.splitext(grp_path)[1] in XcodeProject.special_folders:
875 + # if this file has a special extension (bundle or framework mainly) treat it as a file
876 + special_list.append(grp_path)
877 + new_files = self.verify_files([folder_name], parent=parent)
878 +
879 + # Ignore this file if it is in excludes
880 + if new_files and not [m for m in excludes if re.match(m, grp_path)]:
881 + results.extend(self.add_file(grp_path, parent, create_build_files=create_build_files))
882 +
883 + continue
884 +
885 + # create group
886 + grp = self.get_or_create_group(folder_name, path=self.get_relative_path(grp_path), parent=parent)
887 + path_dict[grp_path] = grp
888 +
889 + results.append(grp)
890 +
891 + file_dict = {}
892 +
893 + for f in files:
894 + if f[0] == '.' or [m for m in excludes if re.match(m, f)]:
895 + continue
896 +
897 + kwds = {
898 + 'create_build_files': create_build_files,
899 + 'parent': grp,
900 + 'name': f
901 + }
902 +
903 + f_path = os.path.join(grp_path, f)
904 + file_dict[f_path] = kwds
905 +
906 + new_files = self.verify_files([n.get('name') for n in file_dict.values()], parent=grp)
907 + add_files = [(k, v) for k, v in file_dict.items() if v.get('name') in new_files]
908 +
909 + for path, kwds in add_files:
910 + kwds.pop('name', None)
911 + self.add_file(path, **kwds)
912 +
913 + if not recursive:
914 + break
915 +
916 + for r in results:
917 + self.objects[r.id] = r
918 +
919 + return results
920 +
921 + def path_leaf(self, path):
922 + head, tail = ntpath.split(path)
923 + return tail or ntpath.basename(head)
924 +
925 + def add_file_if_doesnt_exist(self, f_path, parent=None, tree='SOURCE_ROOT', create_build_files=True, weak=False, ignore_unknown_type=False):
926 + for obj in self.objects.values():
927 + if 'path' in obj:
928 + if self.path_leaf(f_path) == self.path_leaf(obj.get('path')):
929 + return []
930 +
931 + return self.add_file(f_path, parent, tree, create_build_files, weak, ignore_unknown_type=ignore_unknown_type)
932 +
933 + def add_file(self, f_path, parent=None, tree='SOURCE_ROOT', create_build_files=True, weak=False, ignore_unknown_type=False, target=None):
934 + results = []
935 + abs_path = ''
936 +
937 + if os.path.isabs(f_path):
938 + abs_path = f_path
939 +
940 + if not os.path.exists(f_path):
941 + return results
942 + elif tree == 'SOURCE_ROOT':
943 + f_path = os.path.relpath(f_path, self.source_root)
944 + else:
945 + tree = '<absolute>'
946 +
947 + if not parent:
948 + parent = self.root_group
949 + elif not isinstance(parent, PBXGroup):
950 + # assume it's an id
951 + parent = self.objects.get(parent, self.root_group)
952 +
953 + file_ref = PBXFileReference.Create(f_path, tree, ignore_unknown_type=ignore_unknown_type)
954 + parent.add_child(file_ref)
955 + results.append(file_ref)
956 +
957 + # create a build file for the file ref
958 + if file_ref.build_phase and create_build_files:
959 + phases = self.get_build_phases(file_ref.build_phase)
960 + if target:
961 + target = self.get_target_by_name(target)
962 +
963 + for phase in phases:
964 + if (not target) or (phase.id in target.get('buildPhases')):
965 + build_file = PBXBuildFile.Create(file_ref, weak=weak)
966 + phase.add_build_file(build_file)
967 + results.append(build_file)
968 +
969 + if abs_path and tree == 'SOURCE_ROOT' \
970 + and os.path.isfile(abs_path) \
971 + and file_ref.build_phase == 'PBXFrameworksBuildPhase':
972 + library_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0])
973 + self.add_library_search_paths([library_path], recursive=False)
974 +
975 + if abs_path and tree == 'SOURCE_ROOT' \
976 + and not os.path.isfile(abs_path) \
977 + and file_ref.build_phase == 'PBXFrameworksBuildPhase':
978 + framework_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0])
979 + self.add_framework_search_paths([framework_path, '$(inherited)'], recursive=False)
980 +
981 + for r in results:
982 + self.objects[r.id] = r
983 +
984 + if results:
985 + self.modified = True
986 +
987 + return results
988 +
989 + def check_and_repair_framework(self, base):
990 + name = os.path.basename(base)
991 +
992 + if ".framework" in name:
993 + basename = name[:-len(".framework")]
994 +
995 + finalHeaders = os.path.join(base, "Headers")
996 + finalCurrent = os.path.join(base, "Versions/Current")
997 + finalLib = os.path.join(base, basename)
998 + srcHeaders = "Versions/A/Headers"
999 + srcCurrent = "A"
1000 + srcLib = "Versions/A/" + basename
1001 +
1002 + if not os.path.exists(finalHeaders):
1003 + os.symlink(srcHeaders, finalHeaders)
1004 + if not os.path.exists(finalCurrent):
1005 + os.symlink(srcCurrent, finalCurrent)
1006 + if not os.path.exists(finalLib):
1007 + os.symlink(srcLib, finalLib)
1008 +
1009 +
1010 + def get_file_id_by_path(self, f_path):
1011 + for k, v in self.objects.iteritems():
1012 + if str(v.get('path')) == f_path:
1013 + return k
1014 + return 0
1015 +
1016 +
1017 + def remove_file_by_path(self, f_path, recursive=True):
1018 + id = self.get_file_id_by_path(f_path)
1019 + if id != 0:
1020 + self.remove_file(id, recursive=recursive)
1021 + return
1022 +
1023 +
1024 + def remove_file(self, id, recursive=True):
1025 + if not PBXType.IsGuid(id):
1026 + id = id.id
1027 +
1028 + if id in self.objects:
1029 + self.objects.remove(id)
1030 + # Remove from PBXResourcesBuildPhase and PBXSourcesBuildPhase if necessary
1031 + buildFiles = [f for f in self.objects.values() if f.get('isa') == 'PBXBuildFile']
1032 + for buildFile in buildFiles:
1033 + if id == buildFile.get('fileRef'):
1034 + key = buildFile.id
1035 + PBXRBP = [f for f in self.objects.values() if f.get('isa') == 'PBXResourcesBuildPhase']
1036 + PBXSBP = [f for f in self.objects.values() if f.get('isa') == 'PBXSourcesBuildPhase']
1037 + self.objects.remove(key)
1038 + if len(PBXSBP) and PBXSBP[0].has_build_file(key):
1039 + PBXSBP[0].remove_build_file(key)
1040 + if len(PBXRBP) and PBXRBP[0].has_build_file(key):
1041 + PBXRBP[0].remove_build_file(key)
1042 + if recursive:
1043 + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup']
1044 +
1045 + for group in groups:
1046 + if id in group['children']:
1047 + group.remove_child(id)
1048 +
1049 + self.modified = True
1050 +
1051 + def remove_group(self, id, recursive = True):
1052 + if not PBXType.IsGuid(id):
1053 + id = id.id
1054 + name = self.objects.get(id).get('path')
1055 + children = self.objects.get(id).get('children')
1056 + if name is None:
1057 + name = id
1058 + if id in self.objects:
1059 + if recursive:
1060 + for childKey in children:
1061 + childValue = self.objects.get(childKey)
1062 + if childValue.get('isa') == 'PBXGroup':
1063 + self.remove_group(childKey, True)
1064 + else:
1065 + self.remove_file(childKey, False)
1066 +
1067 + self.objects.remove(id);
1068 +
1069 + def remove_group_by_name(self, name, recursive = True):
1070 + groups = self.get_groups_by_name(name)
1071 + if len(groups):
1072 + for group in groups:
1073 + self.remove_group(group.id, recursive)
1074 +
1075 + def move_file(self, id, dest_grp=None):
1076 + pass
1077 +
1078 + def apply_patch(self, patch_path, xcode_path):
1079 + if not os.path.isfile(patch_path) or not os.path.isdir(xcode_path):
1080 + print 'ERROR: couldn\'t apply "%s" to "%s"' % (patch_path, xcode_path)
1081 + return
1082 +
1083 + print 'applying "%s" to "%s"' % (patch_path, xcode_path)
1084 +
1085 + return subprocess.call(['patch', '-p1', '--forward', '--directory=%s' % xcode_path, '--input=%s' % patch_path])
1086 +
1087 + def apply_mods(self, mod_dict, default_path=None):
1088 + if not default_path:
1089 + default_path = os.getcwd()
1090 +
1091 + keys = mod_dict.keys()
1092 +
1093 + for k in keys:
1094 + v = mod_dict.pop(k)
1095 + mod_dict[k.lower()] = v
1096 +
1097 + parent = mod_dict.pop('group', None)
1098 +
1099 + if parent:
1100 + parent = self.get_or_create_group(parent)
1101 +
1102 + excludes = mod_dict.pop('excludes', [])
1103 +
1104 + if excludes:
1105 + excludes = [re.compile(e) for e in excludes]
1106 +
1107 + compiler_flags = mod_dict.pop('compiler_flags', {})
1108 +
1109 + for k, v in mod_dict.items():
1110 + if k == 'patches':
1111 + for p in v:
1112 + if not os.path.isabs(p):
1113 + p = os.path.join(default_path, p)
1114 +
1115 + self.apply_patch(p, self.source_root)
1116 + elif k == 'folders':
1117 + # get and compile excludes list
1118 + # do each folder individually
1119 + for folder in v:
1120 + kwds = {}
1121 +
1122 + # if path contains ':' remove it and set recursive to False
1123 + if ':' in folder:
1124 + args = folder.split(':')
1125 + kwds['recursive'] = False
1126 + folder = args.pop(0)
1127 +
1128 + if os.path.isabs(folder) and os.path.isdir(folder):
1129 + pass
1130 + else:
1131 + folder = os.path.join(default_path, folder)
1132 + if not os.path.isdir(folder):
1133 + continue
1134 +
1135 + if parent:
1136 + kwds['parent'] = parent
1137 +
1138 + if excludes:
1139 + kwds['excludes'] = excludes
1140 +
1141 + self.add_folder(folder, **kwds)
1142 + elif k == 'headerpaths' or k == 'librarypaths':
1143 + paths = []
1144 +
1145 + for p in v:
1146 + if p.endswith('/**'):
1147 + p = os.path.split(p)[0]
1148 +
1149 + if not os.path.isabs(p):
1150 + p = os.path.join(default_path, p)
1151 +
1152 + if not os.path.exists(p):
1153 + continue
1154 +
1155 + p = self.get_relative_path(p)
1156 + paths.append(os.path.join('$(SRCROOT)', p, "**"))
1157 +
1158 + if k == 'headerpaths':
1159 + self.add_header_search_paths(paths)
1160 + else:
1161 + self.add_library_search_paths(paths)
1162 + elif k == 'other_cflags':
1163 + self.add_other_cflags(v)
1164 + elif k == 'other_ldflags':
1165 + self.add_other_ldflags(v)
1166 + elif k == 'libs' or k == 'frameworks' or k == 'files':
1167 + paths = {}
1168 +
1169 + for p in v:
1170 + kwds = {}
1171 +
1172 + if ':' in p:
1173 + args = p.split(':')
1174 + p = args.pop(0)
1175 +
1176 + if 'weak' in args:
1177 + kwds['weak'] = True
1178 +
1179 + file_path = os.path.join(default_path, p)
1180 + search_path, file_name = os.path.split(file_path)
1181 +
1182 + if [m for m in excludes if re.match(m, file_name)]:
1183 + continue
1184 +
1185 + try:
1186 + expr = re.compile(file_name)
1187 + except re.error:
1188 + expr = None
1189 +
1190 + if expr and os.path.isdir(search_path):
1191 + file_list = os.listdir(search_path)
1192 +
1193 + for f in file_list:
1194 + if [m for m in excludes if re.match(m, f)]:
1195 + continue
1196 +
1197 + if re.search(expr, f):
1198 + kwds['name'] = f
1199 + paths[os.path.join(search_path, f)] = kwds
1200 + p = None
1201 +
1202 + if k == 'libs':
1203 + kwds['parent'] = self.get_or_create_group('Libraries', parent=parent)
1204 + elif k == 'frameworks':
1205 + kwds['parent'] = self.get_or_create_group('Frameworks', parent=parent)
1206 +
1207 + if p:
1208 + kwds['name'] = file_name
1209 +
1210 + if k == 'libs':
1211 + p = os.path.join('usr', 'lib', p)
1212 + kwds['tree'] = 'SDKROOT'
1213 + elif k == 'frameworks':
1214 + p = os.path.join('System', 'Library', 'Frameworks', p)
1215 + kwds['tree'] = 'SDKROOT'
1216 + elif k == 'files' and not os.path.exists(file_path):
1217 + # don't add non-existent files to the project.
1218 + continue
1219 +
1220 + paths[p] = kwds
1221 +
1222 + new_files = self.verify_files([n.get('name') for n in paths.values()])
1223 + add_files = [(k, v) for k, v in paths.items() if v.get('name') in new_files]
1224 +
1225 + for path, kwds in add_files:
1226 + kwds.pop('name', None)
1227 +
1228 + if 'parent' not in kwds and parent:
1229 + kwds['parent'] = parent
1230 +
1231 + self.add_file(path, **kwds)
1232 +
1233 + if compiler_flags:
1234 + for k, v in compiler_flags.items():
1235 + filerefs = []
1236 +
1237 + for f in v:
1238 + filerefs.extend([fr.id for fr in self.objects.values() if fr.get('isa') == 'PBXFileReference'
1239 + and fr.get('name') == f])
1240 +
1241 + buildfiles = [bf for bf in self.objects.values() if bf.get('isa') == 'PBXBuildFile'
1242 + and bf.get('fileRef') in filerefs]
1243 +
1244 + for bf in buildfiles:
1245 + if bf.add_compiler_flag(k):
1246 + self.modified = True
1247 +
1248 + def backup(self, file_name=None, backup_name=None):
1249 + if not file_name:
1250 + file_name = self.pbxproj_path
1251 +
1252 + if not backup_name:
1253 + backup_name = "%s.%s.backup" % (file_name, datetime.datetime.now().strftime('%d%m%y-%H%M%S'))
1254 +
1255 + shutil.copy2(file_name, backup_name)
1256 + return backup_name
1257 +
1258 + def save(self, file_name=None, old_format=False, sort=False):
1259 + if old_format :
1260 + self.save_format_xml(file_name)
1261 + else:
1262 + self.save_new_format(file_name, sort)
1263 +
1264 + def save_format_xml(self, file_name=None):
1265 + """Saves in old (xml) format"""
1266 + if not file_name:
1267 + file_name = self.pbxproj_path
1268 +
1269 + # This code is adapted from plistlib.writePlist
1270 + with open(file_name, "w") as f:
1271 + writer = PBXWriter(f)
1272 + writer.writeln("<plist version=\"1.0\">")
1273 + writer.writeValue(self.data)
1274 + writer.writeln("</plist>")
1275 +
1276 + def save_new_format(self, file_name=None, sort=False):
1277 + """Save in Xcode 3.2 compatible (new) format"""
1278 + if not file_name:
1279 + file_name = self.pbxproj_path
1280 +
1281 + # process to get the section's info and names
1282 + objs = self.data.get('objects')
1283 + sections = dict()
1284 + uuids = dict()
1285 +
1286 + for key in objs:
1287 + l = list()
1288 +
1289 + if objs.get(key).get('isa') in sections:
1290 + l = sections.get(objs.get(key).get('isa'))
1291 +
1292 + l.append(tuple([key, objs.get(key)]))
1293 + sections[objs.get(key).get('isa')] = l
1294 +
1295 + if 'name' in objs.get(key):
1296 + uuids[key] = objs.get(key).get('name')
1297 + elif 'path' in objs.get(key):
1298 + uuids[key] = objs.get(key).get('path')
1299 + else:
1300 + if objs.get(key).get('isa') == 'PBXProject':
1301 + uuids[objs.get(key).get('buildConfigurationList')] = 'Build configuration list for PBXProject "Unity-iPhone"'
1302 + elif objs.get(key).get('isa')[0:3] == 'PBX':
1303 + uuids[key] = objs.get(key).get('isa')[3:-10]
1304 + else:
1305 + uuids[key] = 'Build configuration list for PBXNativeTarget "TARGET_NAME"'
1306 +
1307 + ro = self.data.get('rootObject')
1308 + uuids[ro] = 'Project object'
1309 +
1310 + for key in objs:
1311 + # transitive references (used in the BuildFile section)
1312 + if 'fileRef' in objs.get(key) and objs.get(key).get('fileRef') in uuids:
1313 + uuids[key] = uuids[objs.get(key).get('fileRef')]
1314 +
1315 + # transitive reference to the target name (used in the Native target section)
1316 + if objs.get(key).get('isa') == 'PBXNativeTarget':
1317 + uuids[objs.get(key).get('buildConfigurationList')] = uuids[objs.get(key).get('buildConfigurationList')].replace('TARGET_NAME', uuids[key])
1318 +
1319 + self.uuids = uuids
1320 + self.sections = sections
1321 +
1322 + out = open(file_name, 'w')
1323 + out.write('// !$*UTF8*$!\n')
1324 + self._printNewXCodeFormat(out, self.data, '', enters=True, sort=sort)
1325 + out.close()
1326 +
1327 + @classmethod
1328 + def addslashes(cls, s):
1329 + d = {'"': '\\"', "'": "\\'", "\0": "\\\0", "\\": "\\\\", "\n":"\\n"}
1330 + return ''.join(d.get(c, c) for c in s)
1331 +
1332 + def _printNewXCodeFormat(self, out, root, deep, enters=True, sort=False):
1333 + if isinstance(root, IterableUserDict):
1334 + out.write('{')
1335 +
1336 + if enters:
1337 + out.write('\n')
1338 +
1339 + isa = root.pop('isa', '')
1340 +
1341 + if isa != '': # keep the isa in the first spot
1342 + if enters:
1343 + out.write('\t' + deep)
1344 +
1345 + out.write('isa = ')
1346 + self._printNewXCodeFormat(out, isa, '\t' + deep, enters=enters)
1347 + out.write(';')
1348 +
1349 + if enters:
1350 + out.write('\n')
1351 + else:
1352 + out.write(' ')
1353 +
1354 + for key in sorted(root.iterkeys()): # keep the same order as Apple.
1355 + if enters:
1356 + out.write('\t' + deep)
1357 +
1358 + if re.match(regex, key).group(0) == key:
1359 + out.write(key.encode("utf-8") + ' = ')
1360 + else:
1361 + out.write('"' + key.encode("utf-8") + '" = ')
1362 +
1363 + if key == 'objects':
1364 + out.write('{') # open the objects section
1365 +
1366 + if enters:
1367 + out.write('\n')
1368 + #root.remove('objects') # remove it to avoid problems
1369 +
1370 + sections = [
1371 + ('PBXBuildFile', False),
1372 + ('PBXCopyFilesBuildPhase', True),
1373 + ('PBXFileReference', False),
1374 + ('PBXFrameworksBuildPhase', True),
1375 + ('PBXGroup', True),
1376 + ('PBXAggregateTarget', True),
1377 + ('PBXNativeTarget', True),
1378 + ('PBXProject', True),
1379 + ('PBXResourcesBuildPhase', True),
1380 + ('PBXShellScriptBuildPhase', True),
1381 + ('PBXSourcesBuildPhase', True),
1382 + ('XCBuildConfiguration', True),
1383 + ('XCConfigurationList', True),
1384 + ('PBXTargetDependency', True),
1385 + ('PBXVariantGroup', True),
1386 + ('PBXReferenceProxy', True),
1387 + ('PBXContainerItemProxy', True),
1388 + ('XCVersionGroup', True)]
1389 +
1390 + for section in sections: # iterate over the sections
1391 + if self.sections.get(section[0]) is None:
1392 + continue
1393 +
1394 + out.write('\n/* Begin %s section */' % section[0].encode("utf-8"))
1395 + self.sections.get(section[0]).sort(cmp=lambda x, y: cmp(x[0], y[0]))
1396 +
1397 + if sort and section[0] == 'PBXGroup':
1398 + for entry in self.sections.get(section[0]):
1399 + entry[1]['children'] = sorted(entry[1]['children'],
1400 + key=lambda x: self.uuids[x].encode("utf-8"))
1401 +
1402 + for pair in self.sections.get(section[0]):
1403 + key = pair[0]
1404 + value = pair[1]
1405 + out.write('\n')
1406 +
1407 + if enters:
1408 + out.write('\t\t' + deep)
1409 +
1410 + out.write(key.encode("utf-8"))
1411 +
1412 + if key in self.uuids:
1413 + out.write(" /* " + self.uuids[key].encode("utf-8") + " */")
1414 +
1415 + out.write(" = ")
1416 + self._printNewXCodeFormat(out, value, '\t\t' + deep, enters=section[1])
1417 + out.write(';')
1418 +
1419 + out.write('\n/* End %s section */\n' % section[0].encode("utf-8"))
1420 +
1421 + out.write(deep + '\t}') # close of the objects section
1422 + else:
1423 + self._printNewXCodeFormat(out, root[key], '\t' + deep, enters=enters)
1424 +
1425 + out.write(';')
1426 +
1427 + if enters:
1428 + out.write('\n')
1429 + else:
1430 + out.write(' ')
1431 +
1432 + root['isa'] = isa # restore the isa for further calls
1433 +
1434 + if enters:
1435 + out.write(deep)
1436 +
1437 + out.write('}')
1438 +
1439 + elif isinstance(root, UserList):
1440 + out.write('(')
1441 +
1442 + if enters:
1443 + out.write('\n')
1444 +
1445 + for value in root:
1446 + if enters:
1447 + out.write('\t' + deep)
1448 +
1449 + self._printNewXCodeFormat(out, value, '\t' + deep, enters=enters)
1450 + out.write(',')
1451 +
1452 + if enters:
1453 + out.write('\n')
1454 +
1455 + if enters:
1456 + out.write(deep)
1457 +
1458 + out.write(')')
1459 +
1460 + else:
1461 + if len(root) > 0 and re.match(regex, root).group(0) == root:
1462 + out.write(root.encode("utf-8"))
1463 + else:
1464 + out.write('"' + XcodeProject.addslashes(root.encode("utf-8")) + '"')
1465 +
1466 + if root in self.uuids:
1467 + out.write(" /* " + self.uuids[root].encode("utf-8") + " */")
1468 +
1469 + @classmethod
1470 + def Load(cls, path, pure_python=False):
1471 + if pure_python:
1472 + import openstep_parser as osp
1473 + tree = osp.OpenStepDecoder.ParseFromFile(open(path, 'r'))
1474 + else:
1475 + cls.plutil_path = os.path.join(os.path.split(__file__)[0], 'plutil')
1476 +
1477 + if not os.path.isfile(XcodeProject.plutil_path):
1478 + cls.plutil_path = 'plutil'
1479 +
1480 + # load project by converting to xml and then convert that using plistlib
1481 + p = subprocess.Popen([XcodeProject.plutil_path, '-convert', 'xml1', '-o', '-', path], stdout=subprocess.PIPE)
1482 + stdout, stderr = p.communicate()
1483 +
1484 + # If the plist was malformed, return code will be non-zero
1485 + if p.returncode != 0:
1486 + print stdout
1487 + return None
1488 +
1489 + tree = plistlib.readPlistFromString(stdout)
1490 +
1491 + return XcodeProject(tree, path)
1492 +
1493 + @classmethod
1494 + def LoadFromXML(cls, path):
1495 + tree = plistlib.readPlist(path)
1496 + return XcodeProject(tree, path)
1497 +
1498 +
1499 +# The code below was adapted from plistlib.py.
1500 +
1501 +class PBXWriter(plistlib.PlistWriter):
1502 + def writeValue(self, value):
1503 + if isinstance(value, (PBXList, PBXDict)):
1504 + plistlib.PlistWriter.writeValue(self, value.data)
1505 + else:
1506 + plistlib.PlistWriter.writeValue(self, value)
1507 +
1508 + def simpleElement(self, element, value=None):
1509 + """
1510 + We have to override this method to deal with Unicode text correctly.
1511 + Non-ascii characters have to get encoded as character references.
1512 + """
1513 + if value is not None:
1514 + value = _escapeAndEncode(value)
1515 + self.writeln("<%s>%s</%s>" % (element, value, element))
1516 + else:
1517 + self.writeln("<%s/>" % element)
1518 +
1519 +
1520 +# Regex to find any control chars, except for \t \n and \r
1521 +_controlCharPat = re.compile(
1522 + r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f"
1523 + r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]")
1524 +
1525 +
1526 +def _escapeAndEncode(text):
1527 + m = _controlCharPat.search(text)
1528 + if m is not None:
1529 + raise ValueError("strings can't contains control characters; "
1530 + "use plistlib.Data instead")
1531 + text = text.replace("\r\n", "\n") # convert DOS line endings
1532 + text = text.replace("\r", "\n") # convert Mac line endings
1533 + text = text.replace("&", "&amp;") # escape '&'
1534 + text = text.replace("<", "&lt;") # escape '<'
1535 + text = text.replace(">", "&gt;") # escape '>'
1536 + return text.encode("ascii", "xmlcharrefreplace") # encode as ascii with xml character references
1 +import os
2 +
3 +import commands
4 +
5 +
6 +buildProjName = ''
7 +targetName = ''
8 +import shutil
9 +import os
10 +
11 +def buildProj():
12 +
13 + if buildProjName == '':
14 + print('buildProjName is not define')
15 +
16 + else:
17 + #build project
18 + print('start build proj')
19 + commands.getstatusoutput('xcodebuild -project ' + buildProjName + '.xcodeproj')
20 + releaseDir = os.path.abspath('.') + '/Release'
21 + if not os.path.exists(releaseDir):
22 + os.mkdir(releaseDir)
23 +
24 + ipaPath = releaseDir + '/' + buildProjName + '-Release.ipa'
25 + buildPath = os.path.abspath('.') + '/build'
26 + if os.path.exists(ipaPath):
27 + os.remove(ipaPath)
28 +
29 + resultStr = commands.getstatusoutput('xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/' + targetName + '.app -o ' +ipaPath)
30 + #print(resultStr)
31 +
32 + if os.path.exists(buildPath):
33 + shutil.rmtree(buildPath)
34 +
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 9
10 #include "UnionInterface.h" 10 #include "UnionInterface.h"
11 #import <SafariServices/SafariServices.h> 11 #import <SafariServices/SafariServices.h>
12 -@interface Interface : NSObject <UnionInterface,SFSafariViewControllerDelegate> 12 +@interface Interface : NSObject <UnionInterface>
13 @property(nonatomic, strong)UIViewController *controller; 13 @property(nonatomic, strong)UIViewController *controller;
14 14
15 15
......
...@@ -29,5 +29,7 @@ ...@@ -29,5 +29,7 @@
29 29
30 - (void)httpPostAsyncOpen:(NSString*)postUrl :(NSDictionary*)postDict; 30 - (void)httpPostAsyncOpen:(NSString*)postUrl :(NSDictionary*)postDict;
31 31
32 -- (NSString *)dicToString:(NSDictionary *) dict; 32 +-(void)httpGetAsync:(NSString *)url completionHandler:(void (^ __nullable)(NSURLResponse* __nullable response, NSData* __nullable data, NSError* __nullable connectionError)) handler;
33 +
34 +- (NSString * __nullable)dicToString:(NSDictionary * __nullable) dict;
33 @end 35 @end
......
...@@ -30,7 +30,10 @@ ...@@ -30,7 +30,10 @@
30 30
31 @property(nonatomic, strong)NSString *openId; 31 @property(nonatomic, strong)NSString *openId;
32 32
33 -#define REPORT_URL @"https://statistic.public.sdk.gzyouai.com/sdk/statistic" //@http://public.sdk.gzyouai.com:9030/sdk/statistic"//@"http://10.200.201.230:9001/sdk/statistic"//@"https://statistic.public.sdk.gzyouai.com/sdk/statistic"// 33 +#define REPORT_URL @"https://statistic.public.sdk.gzyouai.com/sdk/statistic" //http://183.57.76.181:9030/sdk/statistic
34 +
35 +#define REPORT_IDFA_URL @"https://statistic.public.sdk.gzyouai.com/sdk/last_channel?idfa=" //@"http://183.57.76.181:9030/sdk/last_channel?idfa="//
36 +
34 #define REPORT_OPEN @"open" 37 #define REPORT_OPEN @"open"
35 #define REPORT_ENTER @"enter" 38 #define REPORT_ENTER @"enter"
36 #define REPORT_CREATEROLE @"createrole" 39 #define REPORT_CREATEROLE @"createrole"
......
...@@ -187,6 +187,8 @@ ...@@ -187,6 +187,8 @@
187 187
188 - (void)applicationWillResignActive:(UIApplication *)application; 188 - (void)applicationWillResignActive:(UIApplication *)application;
189 189
190 +-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options;
191 +
190 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; 192 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
191 193
192 @end 194 @end
......
...@@ -126,5 +126,7 @@ ...@@ -126,5 +126,7 @@
126 126
127 - (void)applicationWillResignActive:(UIApplication *)application; 127 - (void)applicationWillResignActive:(UIApplication *)application;
128 128
129 +-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options;
130 +
129 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; 131 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
130 @end 132 @end
...\ No newline at end of file ...\ No newline at end of file
......