最烦每次都要代码去绑定 ccb 里面的属性和方法了,有时候因为大小写的错误很烦。
所以找了 cocosbuilder 的源码,在它基础上生成 .h , .cpp 代码文件。
- (BOOL) publishDirectory:(NSString*) dir subPath:(NSString*) subPath
{
CocosBuilderAppDelegate* ad = [CocosBuilderAppDelegate appDelegate];
ResourceManager* resManager = [ResourceManager sharedManager];
NSArray* resIndependentDirs = [resManager resIndependentDirs];
NSFileManager* fm = [NSFileManager defaultManager];
// Path to output directory for the currently exported path
NSString* outDir = NULL;
if (projectSettings.flattenPaths && projectSettings.publishToZipFile)
{
outDir = outputDir;
}
else
{
outDir = [outputDir stringByAppendingPathComponent:subPath];
}
// Check for generated sprite sheets
BOOL isGeneratedSpriteSheet = NO;
NSDate* srcSpriteSheetDate = NULL;
if ([projectSettings.generatedSpriteSheets objectForKey:subPath])
{
isGeneratedSpriteSheet = YES;
srcSpriteSheetDate = [self latestModifiedDateForDirectory:dir];
// Clear temporary sprite sheet directory
[fm removeItemAtPath:[projectSettings tempSpriteSheetCacheDirectory] error:NULL];
}
// Create the directory if it doesn't exist
if (!isGeneratedSpriteSheet)
{
BOOL createdDirs = [fm createDirectoryAtPath:outDir withIntermediateDirectories:YES attributes:NULL error:NULL];
if (!createdDirs)
{
[warnings addWarningWithDescription:@"Failed to create output directory %@" isFatal:YES];
return NO;
}
}
// Add files from main directory
NSMutableSet* files = [NSMutableSet setWithArray:[fm contentsOfDirectoryAtPath:dir error:NULL]];
// Add files from resolution depentant directories
for (NSString* publishExt in publishForResolutions)
{
NSString* resolutionDir = [dir stringByAppendingPathComponent:publishExt];
BOOL isDirectory;
if ([fm fileExistsAtPath:resolutionDir isDirectory:&isDirectory] && isDirectory)
{
[files addObjectsFromArray:[fm contentsOfDirectoryAtPath:resolutionDir error:NULL]];
}
}
// Add files from the -auto directory
NSString* autoDir = [dir stringByAppendingPathComponent:@"resources-auto"];
BOOL isDirAuto;
if ([fm fileExistsAtPath:autoDir isDirectory:&isDirAuto] && isDirAuto)
{
[files addObjectsFromArray:[fm contentsOfDirectoryAtPath:autoDir error:NULL]];
}
// Iterate through all files
for (NSString* fileName in files)
{
if ([fileName hasPrefix:@"."]) continue;
NSString* filePath = [dir stringByAppendingPathComponent:fileName];
BOOL isDirectory;
BOOL fileExists = [fm fileExistsAtPath:filePath isDirectory:&isDirectory];
if (fileExists && isDirectory)
{
NSString* childPath = NULL;
if (subPath) childPath = [NSString stringWithFormat:@"%@/%@", subPath, fileName];
else childPath = fileName;
// Skip resource independent directories
if ([resIndependentDirs containsObject:fileName]) continue;
// Skip generated sprite sheets
if (isGeneratedSpriteSheet) continue;
// Skip the empty folder
if ([[fm contentsOfDirectoryAtPath:filePath error:NULL] count] == 0) continue;
// Skip the fold no .ccb files when onlyPublishCCBs is true
if(projectSettings.onlyPublishCCBs && ![self containsCCBFile:filePath]) continue;
[self publishDirectory:filePath subPath:childPath];
}
else
{
// Publish file
// Copy files
for (NSString* ext in copyExtensions)
{
// Skip non png files for generated sprite sheets
if (isGeneratedSpriteSheet && ![ext isEqualToString:@"png"]) continue;
if ([[fileName lowercaseString] hasSuffix:ext] && !projectSettings.onlyPublishCCBs)
{
// This file should be copied
NSString* dstFile = [outDir stringByAppendingPathComponent:fileName];
// Use temp cache directory for generated sprite sheets
if (isGeneratedSpriteSheet)
{
dstFile = [[projectSettings tempSpriteSheetCacheDirectory] stringByAppendingPathComponent:fileName];
}
// Make conversion rules for audio
NSString* newFormat = NULL;
if ([ext isEqualToString:@"wav"])
{
if (targetType == kCCBPublisherTargetTypeIPhone)
{
newFormat = @"caf";
}
else if (targetType == kCCBPublisherTargetTypeHTML5)
{
newFormat = @"mp3";
}
else if (targetType == kCCBPublisherTargetTypeAndroid)
{
newFormat = @"ogg";
}
}
/*
else if ([ext isEqualToString:@"mp3"])
{
if (targetType == kCCBPublisherTargetTypeAndroid)
{
newFormat = @"ogg";
}
}
*/
if (newFormat)
{
// Set new name
dstFile = [[dstFile stringByDeletingPathExtension] stringByAppendingPathExtension:newFormat];
// Add to conversion table
NSString* localName = fileName;
if (subPath) localName = [subPath stringByAppendingPathComponent:fileName];
[self addRenamingRuleFrom:localName to:[[localName stringByDeletingPathExtension] stringByAppendingPathExtension:newFormat]];
}
// Copy file (and possibly convert)
if (![self copyFileIfChanged:filePath to:dstFile forResolution:NULL isSpriteSheet:isGeneratedSpriteSheet outDir:outDir srcDate: srcSpriteSheetDate]) return NO;
if (publishForResolutions)
{
for (NSString* res in publishForResolutions)
{
if (![self copyFileIfChanged:filePath to:dstFile forResolution:res isSpriteSheet:isGeneratedSpriteSheet outDir:outDir srcDate: srcSpriteSheetDate]) return NO;
}
}
}
}
// Publish ccb files
if ([[fileName lowercaseString] hasSuffix:@"ccb"] && !isGeneratedSpriteSheet)
{
NSString* strippedFileName = [fileName stringByDeletingPathExtension];
NSString* dstFile = [[outDir stringByAppendingPathComponent:strippedFileName] stringByAppendingPathExtension:publishFormat];
//处理 g_pTempOutPutPath
{
NSString* strPath = [NSString stringWithFormat:@"%@",dstFile];
NSArray* ary = [dir componentsSeparatedByString:@"/"];
NSMutableString* outPutPath = [NSMutableString stringWithString:@""];
for (int iii=0;iii<[ary count]-1 ;iii++ )
{
NSString* str = [ary objectAtIndex:iii ];
[outPutPath appendFormat:@"/%@",str];
}
g_pTempRootPath = outPutPath;//root path
NSString* strOutPathDirect = [NSString stringWithFormat:@"%@/codeOutPut/",outPutPath];
outPutPath = [NSMutableString stringWithFormat:@"%@/%@" , strOutPathDirect ,strippedFileName];
if(1 )
{
NSError* error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:strOutPathDirect withIntermediateDirectories:NO attributes:nil error:&error];
if (error != nil) {
NSLog(@"error = %@",error);
}
}
g_pTempOutPutClassName = strippedFileName;
g_pTempOutPutPath = [NSString stringWithString:outPutPath];
}
// Add file to list of published files
NSString* localFileName = [dstFile relativePathFromBaseDirPath:outputDir];
[publishedResources addObject:localFileName];
if ([dstFile isEqualToString:filePath])
{
[warnings addWarningWithDescription:@"Publish will overwrite files in resource directory." isFatal:YES];
return NO;
}
NSDate* srcDate = [CCBFileUtil modificationDateForFile:filePath];
NSDate* dstDate = [CCBFileUtil modificationDateForFile:dstFile];
//if (![fm fileExistsAtPath:dstFile] || [self srcFile:filePath isNewerThanDstFile:dstFile])
if (![srcDate isEqualToDate:dstDate])
{
[ad modalStatusWindowUpdateStatusText:[NSString stringWithFormat:@"Publishing %@...", fileName]];
// Remove old file
[fm removeItemAtPath:dstFile error:NULL];
// Copy the file
BOOL sucess = [self publishCCBFile:filePath to:dstFile];
if (!sucess) return NO;
[CCBFileUtil setModificationDate:srcDate forFile:dstFile];
}
g_pTempOutPutPath = nil;
}
}
}
if (isGeneratedSpriteSheet)
{
// Sprite files should have been saved to the temp cache directory, now actually generate the sprite sheets
NSString* spriteSheetDir = [outDir stringByDeletingLastPathComponent];
NSString* spriteSheetName = [outDir lastPathComponent];
ProjectSettingsGeneratedSpriteSheet* ssSettings = [projectSettings smartSpriteSheetForSubPath:subPath];
// Check if sprite sheet needs to be re-published
for (NSString* res in publishForResolutions)
{
NSArray* srcDirs = [NSArray arrayWithObjects:
[projectSettings.tempSpriteSheetCacheDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"resources-%@", res]],
projectSettings.tempSpriteSheetCacheDirectory,
nil];
NSString* spriteSheetFile = NULL;
if (publishToSingleResolution) spriteSheetFile = outDir;
else spriteSheetFile = [[spriteSheetDir stringByAppendingPathComponent:[NSString stringWithFormat:@"resources-%@", res]] stringByAppendingPathComponent:spriteSheetName];
// Skip publish if sprite sheet exists and is up to date
NSDate* dstDate = [CCBFileUtil modificationDateForFile:[spriteSheetFile stringByAppendingPathExtension:@"plist"]];
if (dstDate && [dstDate isEqualToDate:srcSpriteSheetDate] && !ssSettings.isDirty)
{
continue;
}
Tupac* packer = [Tupac tupac];
packer.outputName = spriteSheetFile;
packer.outputFormat = TupacOutputFormatCocos2D;
if (targetType == kCCBPublisherTargetTypeIPhone)
{
packer.imageFormat = ssSettings.textureFileFormat;
packer.compress = ssSettings.compress;
packer.dither = ssSettings.dither;
}
else if (targetType == kCCBPublisherTargetTypeAndroid)
{
packer.imageFormat = ssSettings.textureFileFormatAndroid;
packer.compress = NO;
packer.dither = ssSettings.ditherAndroid;
}
else if (targetType == kCCBPublisherTargetTypeHTML5)
{
packer.imageFormat = ssSettings.textureFileFormatHTML5;
packer.compress = NO;
packer.dither = ssSettings.ditherHTML5;
}
// Update progress
[ad modalStatusWindowUpdateStatusText:[NSString stringWithFormat:@"Generating sprite sheet %@...", [[subPath stringByAppendingPathExtension:@"plist"] lastPathComponent]]];
// Pack texture
packer.directoryPrefix = subPath;
packer.border = YES;
[packer createTextureAtlasFromDirectoryPaths:srcDirs];
// Set correct modification date
[CCBFileUtil setModificationDate:srcSpriteSheetDate forFile:[spriteSheetFile stringByAppendingPathExtension:@"plist"]];
}
[publishedResources addObject:[subPath stringByAppendingPathExtension:@"plist"]];
[publishedResources addObject:[subPath stringByAppendingPathExtension:@"png"]];
if (ssSettings.isDirty) {
ssSettings.isDirty = NO;
[projectSettings store];
}
}
return YES;
}
//
- (void) writeDocument:(NSDictionary*)doc
{
NSDictionary* nodeGraph = [doc objectForKey:@"nodeGraph"];
jsControlled = [[doc objectForKey:@"jsControlled"] boolValue];
[self outputAssginedMemberAndSelector:nodeGraph];//输出绑定的变量和函数
[self cacheStringsForNode:nodeGraph];
[self cacheStringsForSequences:doc];
[self transformStringCache];
[self writeHeader];
[self writeStringCache];
[self writeSequences:doc];
[self writeNodeGraph:nodeGraph];
}
NSString* g_pTempOutSuperClassName;//父类头文件的类名字
NSString* g_pTempOutSubClassName;//子类头文件的类名字
NSString* g_pWantSaveCodeFilePath = nil;//希望存储代码的位置
-(void)searchMemberAndAppend:(NSDictionary*)node saveInMemberString:(NSMutableString*)strMembers saveInMemberInitString:(NSMutableString*)strMembersInit strMembersBind:(NSMutableString*)strMembersBind saveMenuBind:(NSMutableString*)strMenuBinds saveMenuHead:(NSMutableString*)strMenuHead saveMenuCPP:(NSMutableString*)strMenuCpp saveMenuCallBackFun_SuperHead:(NSMutableString*)strMenuCallBackFun_SuperHead
{
NSString* baseClass = [node objectForKey:@"baseClass"];
NSString* customClass = [node objectForKey:@"customClass"];
NSArray* aryChildren = [node objectForKey:@"children" ];
NSString* displayName = [node objectForKey:@"displayName"];
NSString* memberVarAssignmentName = [node objectForKey:@"memberVarAssignmentName"];
NSNumber* memberVarAssignmentType = [node objectForKey:@"memberVarAssignmentType"];
//检查生成代码的目录
if ([displayName isEqualToString:@"code_save_path"])
{
g_pWantSaveCodeFilePath = memberVarAssignmentName;
return;
}
//成员
if ([memberVarAssignmentType intValue] == 2 && [memberVarAssignmentName length] > 0)
{
NSString* classnames = [customClass length] == 0 ? baseClass : customClass;
NSString* comentStr = [displayName isEqualToString:baseClass] ? @"" : displayName;
//owner
// 类型* 成员名;//注释
NSString* oneMember = [NSString stringWithFormat:@"\t%@* %@;//%@\r\n",classnames,memberVarAssignmentName ,comentStr];
[strMembers appendString:oneMember];
//初始化代码
NSString* strInit = [NSString stringWithFormat:@"\t\t%@ = NULL;\r\n",memberVarAssignmentName];
[strMembersInit appendString:strInit];
//绑定成员
NSString* strBind = [NSString stringWithFormat:@"\t\tCCB_MEMBERVARIABLEASSIGNER_GLUE(this, \"%@\", %@*, this->%@);\r\n",memberVarAssignmentName,classnames,memberVarAssignmentName];
[strMembersBind appendString:strBind];
}
//绑定菜单项
if ([baseClass rangeOfString:@"CCMenuItem"].length > 0)
{
//菜单项的绑定
NSArray* aryProperties = [node objectForKey:@"properties"];
for (NSDictionary* dic in aryProperties)
{
NSString* proname = [dic objectForKey:@"name"];
NSString* protype = [dic objectForKey:@"type"];
if ([proname rangeOfString:@"block"].length > 0 && [protype rangeOfString:@"Block"].length > 0 )
{
NSArray* aryTheValue = [dic objectForKey:@"value"];
if ([aryTheValue count] == 1) {
continue;
}
NSString* funName = [aryTheValue objectAtIndex:0];
if ([funName isKindOfClass:[NSString class]] == NO || [funName length] == 0) {
break;
}
//绑定
NSString* newBind = [NSString stringWithFormat:@"\t\tCCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, \"%@\", %@::%@);\r\n", funName ,g_pTempOutSuperClassName, funName ];
if ([strMenuBinds rangeOfString:newBind].length == 0)
{
[strMenuBinds appendString:newBind];
//头文件函数
[strMenuHead appendFormat:@"\tvirtual void %@(cocos2d::CCObject* pSender);\r\n",funName];
//cpp 文件
[strMenuCpp appendFormat:@"void %@::%@(cocos2d::CCObject* pSender)\r\n{\r\n\r\n}\r\n",g_pTempOutSubClassName,funName];
//父类头文件里面的函数声明 必须给子类来实现
[strMenuCallBackFun_SuperHead appendFormat:@"\tvirtual void %@(cocos2d::CCObject* pSender)=0;\r\n",funName];
}
break;
}
}
}
//检查 child
for (NSDictionary* subNode in aryChildren)
{
if ([subNode isKindOfClass:[NSDictionary class]]) {
[self searchMemberAndAppend:subNode saveInMemberString:strMembers saveInMemberInitString:(NSMutableString*)strMembersInit strMembersBind:strMembersBind saveMenuBind:strMenuBinds saveMenuHead:strMenuHead saveMenuCPP:strMenuCpp saveMenuCallBackFun_SuperHead:strMenuCallBackFun_SuperHead];
}
}
}
extern NSString* g_pTempOutPutPath;
extern NSString* g_pTempOutPutClassName;
extern NSString* g_pTempRootPath;
-(void)outputAssginedMemberAndSelector:(NSDictionary*)nodeGraph
{
//输出方式是 父类一个头文件,子类一个头文件+一个CPP文件.每次publish都重新生成父类的头文件,然后判断子类的头文件和cpp文件是否存在,如果已经存在,则不再做生成操作
g_pTempOutSuperClassName = [NSString stringWithFormat:@"%@_ccbHead",g_pTempOutPutClassName];
g_pTempOutSubClassName = g_pTempOutPutClassName;
g_pWantSaveCodeFilePath = nil;
//存储成员
NSMutableString* strMembers = [NSMutableString stringWithString:@"\r\n"];//成员定义
NSMutableString* strMembersInit = [NSMutableString stringWithString:@"\r\n"];//成员初始化
NSMutableString* strMembersBind = [NSMutableString stringWithString:@"\r\n"];//成员绑定
NSMutableString* strMenuBinds = [NSMutableString stringWithString:@"\r\n"];//菜单事件绑定
NSMutableString* strMenuHead = [NSMutableString stringWithString:@"\r\n"];//菜单函数头
NSMutableString* strMenuCpp = [NSMutableString stringWithString:@"\r\n"];//菜单函数 cpp
NSMutableString* strMenuCallBackFun_SuperHead = [NSMutableString stringWithString:@"\r\n"];
[self searchMemberAndAppend:nodeGraph saveInMemberString:strMembers saveInMemberInitString:(NSMutableString*)strMembersInit strMembersBind:strMembersBind saveMenuBind:strMenuBinds saveMenuHead:strMenuHead saveMenuCPP:strMenuCpp saveMenuCallBackFun_SuperHead:strMenuCallBackFun_SuperHead];
// NSLog(@"%@",strMembers);
// NSLog(@"%@",strMenuBinds);
// NSLog(@"%@",strMenuHead);
// NSLog(@"%@",strMenuCpp);
//写文件存储
if (g_pTempOutPutPath != nil)
{
NSError* error = nil;
[strMembers writeToFile:[NSString stringWithFormat:@"%@__member.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
if (error != nil) {
NSLog(@"error = %@",error);
error = nil;
}
[strMenuBinds writeToFile:[NSString stringWithFormat:@"%@__menuBind.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
if (error != nil) {
NSLog(@"error = %@",error);
error = nil;
}
[strMenuHead writeToFile:[NSString stringWithFormat:@"%@__menuH.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
if (error != nil) {
NSLog(@"error = %@",error);
error = nil;
}
[strMenuCpp writeToFile:[NSString stringWithFormat:@"%@__menuCPP.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
if (error != nil) {
NSLog(@"error = %@",error);
error = nil;
}
}
//自动生成 .h 文件 和子类的 .h .cpp文件
if (g_pWantSaveCodeFilePath.length > 0)
{
NSString* templatePath1 = [[NSBundle mainBundle] pathForResource:@"TemplateCCB_CodeFile_Head_h" ofType:@"txt"];
//得到写父类头文件的路径
NSString* pathHeadSuper = [NSString stringWithFormat:@"%@/%@/%@.h",g_pTempRootPath,g_pWantSaveCodeFilePath , g_pTempOutSuperClassName ];
NSLog(@"Head file path = %@",pathHeadSuper);
//首先替换父类模板的内容
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSError* error = nil;
NSString* strContenTemplateH = [NSString stringWithContentsOfFile:templatePath1 encoding:enc error:&error];//父类模板本地读取
if (error) {
NSLog(@"error = %@",error);
}
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile_Head" withString:g_pTempOutSuperClassName];
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input properties here." withString:strMembers];//成员定义
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input init here." withString:strMembersInit];//变量初始化
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input memberBind here." withString:strMembersBind];//成员绑定
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input menuItemSelector shengming here." withString:strMenuCallBackFun_SuperHead];//函数声明绑定
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input menuItemSelector here." withString:strMenuBinds];//函数绑定
strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input ccb file name here." withString:[NSString stringWithFormat:@"strCCBFileName = \"%@.ccbi\";",g_pTempOutSubClassName ]];//ccb文件
error = nil;
[strContenTemplateH writeToFile:pathHeadSuper atomically:NO encoding:enc error:&error];
if (error) {
NSLog(@"error = %@",error);
}
}
//替换子类的头文件的内容
if (g_pWantSaveCodeFilePath.length > 0)
{
NSString* pathHeadSub = [NSString stringWithFormat:@"%@/%@/%@.h",g_pTempRootPath,g_pWantSaveCodeFilePath , g_pTempOutSubClassName ];
NSLog(@"Head file path = %@",pathHeadSub);
bool isAllReadyExist = [[NSFileManager defaultManager] fileExistsAtPath:pathHeadSub];
if (!isAllReadyExist)
{
NSString* templatePath2 = [[NSBundle mainBundle] pathForResource:@"TemplateCCB_CodeFile_h" ofType:@"txt"];
//首先替换父类模板的内容
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSError* error = nil;
NSString* strContenTemplateH_sub = [NSString stringWithContentsOfFile:templatePath2 encoding:enc error:&error];//子类 .h 模板
if (error) {
NSLog(@"error = %@",error);
}
strContenTemplateH_sub = [strContenTemplateH_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile_Head" withString:g_pTempOutSuperClassName];
strContenTemplateH_sub = [strContenTemplateH_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile" withString:g_pTempOutSubClassName];
strContenTemplateH_sub = [strContenTemplateH_sub stringByReplacingOccurrencesOfString:@"//input subclass menu shengming here." withString:strMenuHead];
error = nil;
[strContenTemplateH_sub writeToFile:pathHeadSub atomically:NO encoding:enc error:&error];
if (error) {
NSLog(@"error = %@",error);
}
}
}
//替换子类的cpp 文件的内容
if (g_pWantSaveCodeFilePath.length > 0)
{
NSString* pathCppSub = [NSString stringWithFormat:@"%@/%@/%@.cpp",g_pTempRootPath,g_pWantSaveCodeFilePath , g_pTempOutSubClassName ];
NSLog(@"Cpp file path = %@",pathCppSub);
bool isAllReadyExist = [[NSFileManager defaultManager] fileExistsAtPath:pathCppSub];
if (!isAllReadyExist)
{
NSString* templatePath3 =[[NSBundle mainBundle] pathForResource:@"TemplateCCB_CodeFile_cpp" ofType:@"txt"];
//首先替换父类模板的内容
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSError* error = nil;
NSString* strContenTemplateCPP_sub = [NSString stringWithContentsOfFile:templatePath3 encoding:enc error:&error];//子类 .cpp 模板
if (error) {
NSLog(@"error = %@",error);
}
strContenTemplateCPP_sub = [strContenTemplateCPP_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile_Head" withString:g_pTempOutSuperClassName];
strContenTemplateCPP_sub = [strContenTemplateCPP_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile" withString:g_pTempOutSubClassName];
strContenTemplateCPP_sub = [strContenTemplateCPP_sub stringByReplacingOccurrencesOfString:@"//input menuItemSelector dingyi here." withString:strMenuCpp];
error = nil;
[strContenTemplateCPP_sub writeToFile:pathCppSub atomically:NO encoding:enc error:&error];
if (error) {
NSLog(@"error = %@",error);
}
}
}
}
模板文件暂不提供