项目想做成电商app平台

基础构想将现有的app维护好,以上一个版本的app为模版创建多个app给租户使用

需求: 1.现有app 为模版 里面涉及的有关现有App的图片字样 要使用boundle包装起来
并创建一个全局文件替换字样
2.有关推送分享登陆模块创建confige配置文件 使租户可以使用自己的账户
3.因为大量租户无须有高度自定义话的内容所以初步模版不考虑配置不同的控件页面样式 只需要能替换appid icon name 和一些主题色就好

根据需求思考方案:可以简化开发步骤 通过创建多个target创建大量相似项目 (可能可以使用脚本替换)

1.png

2.png

3.png

如图步骤 你就可以生成2个包名不同的APP了
但是根据需求我们还需要查找出有关现有app的图片文字进行替换
以及有关推送分享登陆模块创建confige配置文件 使租户可以使用自己的账户

5.png

然后通过 读取项目配置做差异化

.h


#import <Foundation/Foundation.h>

@class ArchConfigAccount;

/**
 *  全部配置文件,主要用来存储不同平行学院中的关于分享,友盟,以及服务器配置
 */
@interface ArchConfig : NSObject

+ (ArchConfig *)sharedInstance;

@property (nonatomic, strong, readonly) NSString *serverUrl;

@property (nonatomic, strong, readonly) NSString *chineseName;
@property (nonatomic, strong, readonly) NSString *englishName;

////////////////////分享相关////////////////////
//关于我们中,分享的描述语句
@property (nonatomic, strong, readonly) NSString *aboutShareDescription;
//学院微博账号
@property (nonatomic, strong, readonly) NSString *weiboAccount;

////////////////////第三方Key等////////////////////
//数据统计,友盟
@property (nonatomic, strong, readonly) ArchConfigAccount *umeng;

@property (nonatomic, strong, readonly) ArchConfigAccount *wechat;
@property (nonatomic, strong, readonly) ArchConfigAccount *weibo;
@property (nonatomic, strong, readonly) ArchConfigAccount *qq;

@property (nonatomic, strong, readonly) ArchConfigAccount *share;

//信鸽推送
@property (nonatomic, strong, readonly) ArchConfigAccount *xgPush;
//ShareSDK 短信验证
@property (nonatomic, strong, readonly) ArchConfigAccount *sms;


////////////////////UI相关////////////////////
//侧边栏,栏目列表
@property (nonatomic, strong, readonly) NSArray *tabsArray;
@property (nonatomic, strong, readonly) NSString *openUpBackgroundImagePath;
@property (nonatomic, strong, readonly) NSString *openUpLogoImagePath;
@property (nonatomic, strong, readonly) NSString *loginBackgroundImagePath;
@property (nonatomic, strong, readonly) NSString *sideVCBackgroundImagePath;
@property (nonatomic, strong, readonly) NSString *userBackgroundImagePath;
@property (nonatomic, strong, readonly) NSString *defaultPortraitImagePath;
//系统默认配色
@property (nonatomic, strong, readonly) UIColor *appColor;

@property (nonatomic, strong, readonly) NSString *appId;

@property (nonatomic, strong, readonly) NSString *loginTextStyle;

@property (nonatomic, strong, readonly) NSString *aboutUsShareImagePath;


//当前平行学院使用前缀
- (NSString *)prefix;


- (NSString *)getResourcePath:(NSString *)resourceName withSuffix:(NSString *)suffix;
- (NSString *)getResourcePath:(NSString *)resourceName;

@end


@interface ArchConfigAccount : NSObject

@property (nonatomic, strong) NSString *appID;
@property (nonatomic, strong) NSString *appKey;
@property (nonatomic, strong) NSString *appSecret;
@property (nonatomic, strong) NSString *callbackUrl;


- (id)initWithDictionary:(NSDictionary *)dic;

@end

.m

#import "ArchConfig.h"
#import "UIColor+Ext.h"

static NSString *kServerAddressKey = @"ServerAddress";
static NSString *kUMengKey = @"UMeng";
static NSString *kXGPush = @"XGPush";
static NSString *kSocialAccountKey = @"SocialAccount";
static NSString *kSMSKey = @"SMS";
static NSString *kShareSDK = @"ShareSDK";

static NSString *kTabKey = @"Tabs";

static NSString *kChineseNameKey = @"ChineseName";
static NSString *kEnglishNameKey = @"EnglishName";
static NSString *kAboutShareDescriptionKey = @"AboutShareDescription";

static NSString *kAppIDKey = @"AppID";

static NSString *kAppColorKey = @"AppColor";

static NSString *kWeiboAccountKey = @"WeiboAccount";
static NSString *kLoginTextStyle = @"LoginTextStyle";
static NSString *kaboutUsShareImage = @"aboutUsShareImage";

@interface ArchConfig()

@property (nonatomic, strong, readwrite) ArchConfigAccount *umeng;
@property (nonatomic, strong, readwrite) ArchConfigAccount *wechat;
@property (nonatomic, strong, readwrite) ArchConfigAccount *weibo;
@property (nonatomic, strong, readwrite) ArchConfigAccount *qq;
@property (nonatomic, strong, readwrite) ArchConfigAccount *xgPush;
@property (nonatomic, strong, readwrite) ArchConfigAccount *sms;
@property (nonatomic, strong, readwrite) ArchConfigAccount *share;

@property (nonatomic, strong, readwrite) UIColor *appColor;

@property (nonatomic, strong, readwrite) NSArray *tabsArray;

@property (nonatomic, strong, readwrite) NSString *openUpBackgroundImagePath;
@property (nonatomic, strong, readwrite) NSString *openUpLogoImagePath;
@property (nonatomic, strong, readwrite) NSString *loginBackgroundImagePath;
@property (nonatomic, strong, readwrite) NSString *sideVCBackgroundImagePath;
@property (nonatomic, strong, readwrite) NSString *userBackgroundImagePath;
@property (nonatomic, strong, readwrite) NSString *defaultPortraitImagePath;

@property (nonatomic, strong, readwrite) NSString *appId;

@property (nonatomic, strong, readwrite) NSString *chineseName;
@property (nonatomic, strong, readwrite) NSString *englishName;
@property (nonatomic, strong, readwrite) NSString *weiboAccount;
@property (nonatomic, strong, readwrite) NSString *aboutShareDescription;
@property (nonatomic, strong, readwrite) NSString *aboutUrl;
@property (nonatomic, strong, readwrite) NSString *serverUrl;
@property (nonatomic, strong, readwrite) NSString *loginTextStyle;
@property (nonatomic, strong, readwrite) NSString *aboutUsShareImagePath;


@end

#pragma mark - ArchConfig
@implementation ArchConfig

+ (id)sharedInstance{
    static dispatch_once_t pred = 0;
    __strong static id _sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}

- (id)init{
    self = [super init];
    if (self) {
        NSString *fileName = @"config.plist";
        NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:[self getResourcePath:fileName]];
        [self setupData:dic];
        self.openUpLogoImagePath = [self getResourcePath:@"openUpLogo.png"];
        self.openUpBackgroundImagePath = [self getResourcePath:@"openUpBackground.jpg"];
        
        self.sideVCBackgroundImagePath = [self getResourcePath:@"sideVCBackground" withSuffix:@"png"];
        self.loginBackgroundImagePath = [self getResourcePath:@"loginBackground" withSuffix:@"jpg"];
        self.userBackgroundImagePath = [self getResourcePath:@"userBackground" withSuffix:@"png"];
        self.defaultPortraitImagePath = [self getResourcePath:@"defaultPortrait" withSuffix:@"jpg"];
        self.aboutUsShareImagePath = [self getResourcePath:@"aboutUsShare" withSuffix:@"jpg"];

    }
    return self;
}

- (NSString *)getResourcePath:(NSString *)resourceName withSuffix:(NSString *)suffix{
    NSString *folderPath = [NSString stringWithFormat:@"Colleges/%@/",@AppPrefix];
    
    NSString *filePath = [[NSBundle mainBundle] pathForResource:resourceName ofType:suffix inDirectory:folderPath];
    
    //如果图片,先检测是否有图片,如果没有,查找@2x,@3x
    if ([suffix isEqualToString:@"png"] || [suffix isEqualToString:@"jpg"]) {
        if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
            return filePath;
        }else{
            NSString *fileName = [NSString stringWithFormat:@"%@%@",resourceName,[self imageSuffixForDevice]];
            filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:suffix inDirectory:folderPath];
            return filePath;
        }
    }
    return filePath;
}

- (NSString *)getResourcePath:(NSString *)resourceName{
    return [self getResourcePath:resourceName withSuffix:nil];
}

#pragma mark - Private

- (void)setupData:(NSDictionary *)dic{
    
    self.chineseName = [dic objectForKey:kChineseNameKey];
    self.englishName = [dic objectForKey:kEnglishNameKey];
    self.aboutShareDescription = [dic objectForKey:kAboutShareDescriptionKey];
    self.appId = [dic objectForKey:kAppIDKey];
    self.weiboAccount = [dic objectForKey:kWeiboAccountKey];
    self.loginTextStyle = [dic objectForKey:kLoginTextStyle];
    
    NSString *colorStr = [dic objectForKey:kAppColorKey];
    if (colorStr) {
        self.appColor = [UIColor colorWithRGBString:colorStr];
    }
    
    self.tabsArray = [dic objectForKey:kTabKey];
    
    NSDictionary *umeng = [dic objectForKey:kUMengKey];
    self.umeng = [[ArchConfigAccount alloc] initWithDictionary:umeng];
    
    if ([self.umeng.appKey isNull]) {
        DDLogError(@"友盟AppKey为空");
    }
    
    self.serverUrl = [dic objectForKey:kServerAddressKey];
    if ([self.serverUrl isNull]) {
        DDLogError(@"服务器地址为空");
    }
    
    NSDictionary *xgPush = [dic objectForKey:kXGPush];
    self.xgPush = [[ArchConfigAccount alloc] initWithDictionary:xgPush];
    if ([self.xgPush.appKey isNull] || [self.xgPush.appID isNull]) {
        DDLogError(@"信鸽AppID或AppKey为空");
    }
    
    NSDictionary *sms = [dic objectForKey:kSMSKey];
    self.sms = [[ArchConfigAccount alloc] initWithDictionary:sms];
    if ([self.sms.appKey isNull] || [self.sms.appSecret isNull]) {
        DDLogError(@"SMS AppKey或AppSecret为空");
    }
    
    NSDictionary *share = [dic objectForKey:kShareSDK];
    self.share = [[ArchConfigAccount alloc] initWithDictionary:share];
    if ([self.share.appKey isNull]) {
        DDLogError(@"ShareSDK AppKey为空");
    }
    
    NSDictionary *social = [dic objectForKey:kSocialAccountKey];
    self.wechat = [[ArchConfigAccount alloc] initWithDictionary:[social objectForKey:@"wechat"]];
    self.qq = [[ArchConfigAccount alloc] initWithDictionary:[social objectForKey:@"qq"]];
    
    
    self.weibo = [[ArchConfigAccount alloc] initWithDictionary:[social objectForKey:@"weibo"]];
    
    if (self.tabsArray.count==0) {
        DDLogError(@"侧边栏不能为空");
    }
}

#pragma mark - Public
- (NSString *)prefix{
    return @AppPrefix;
}

@end


#pragma mark - ArchConfigAccount
@implementation ArchConfigAccount

- (id)initWithDictionary:(NSDictionary *)dic{
    self = [super init];
    if (self) {
        self.appID = [dic objectForKey:@"id"];
        self.appKey = [dic objectForKey:@"key"];
        self.appSecret = [dic objectForKey:@"secret"];
        self.callbackUrl = [dic objectForKey:@"callback"];
    }
    return self;
}

@end

之后通过读取文件取得个性化定制
但是此方式图片处理不是很好如果图片过多较难处理
思路通过唐桥猿题库的博客

在Xcode的一个项目中,可以允许建立多个编译的target,每个target代表着最终编译出来的一个App文件,在每个target中,可以添加不同的编译源文件和资源文件。最终,通过我们在不同target之间,修改其 Copy Bundle Resources 和 Compile Sources 配置,使课程之间的差异性得到实现。我们具体的配置方案如下:

我们的每个课程的资源文件都具有相同的文件名,例如首页背景都叫 HomeBackgroundBg.png ,由于每个课程背景不一样,所以我们在工程中,每一个课程target下,通过修改Copy Bundle Resources,使其都配置有不同的(但是同名) HomeBackgroundBg.png 。这样的好处是,在代码逻辑层面,我们可以完全不用处理课程间资源文件的差异性问题。资源文件的差异性都是通过配置文件来保证的。

对于文案一类的差别,我们通过修改Compile Sources,使不同的课程有着不同的文案定义文件。通过这样,我们使不同课程有了不同的文案。另外包括后台网络接口的差异性问题,统计项的差异性问题,也都是这样处理的。

如此简易版的多target 相似项目也就又了一定的可行性

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容