【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 34 Next »

1.如何修改app的名字

   如图,打开工程,在infoPlist.strings里面修改CFBundleDisplayName。分别对应( 英文,繁体中文,简体中文)

2.如何给app设置图标

   如下图:选中imges.xcassets,点击appicon,会出现最右边的面板,将自己的图标拖入相应的2x,3x等框中即可

 (ps:xcode里面2x,3x图的尺寸网上都可以查到,可参考链接:https://developer.apple.com/library/ios/qa/qa1686/_index.html)

   

3. 如何根据报表路径创建带有参数的报表?

[IFEntryViewController initWithPath:(NSString *)reportPath serverUrl:(NSString *)serverUrl viewType:(IFEntryViewType)viewType parameters:(NSDictionary *) params];

参数说明

参数名参数说明可否为空
reportPath报表的路径,例如:@"mobile.test.cpt"
serverUrl报表所在的服务器地址 
viewType预览类型。
IFEntryViewTypePage为分页
IFEntryViewTypeWrite为填报

表单为nil

 是
params报表传递的参数 是

4. 如果购买了决策系统,在移动端想查看决策系统的报表,又不想用FR默认的目录树结构,如何定制自己的目录树?

登录服务器
[IFIntegrationUtils logInto:DEFAULT_SERVERNAME serverUrl:url withUsername:username andPassword:password success:^{
    //第二步,登录成功,加载目录树
    [IFIntegrationUtils loadReportTree:^(NSArray *reportsArray) {
        //第三步,根据目录树和报表的树结构数组,创建自定义目录树,关于返回的数据结构在下面详细介绍。
    } failure:^(NSString *msg) {
    } isObj:YES];
} failure:^(NSString *msg) {
	//登录失败的处理
}];

 

下面详细介绍下服务器返回的目录树结构数组reportsArray:
reportsArray数组里的元素类型都是IFEntryNode;
IFEntryNode可以是文件夹,也可以是具体报表,可以通过方法[node isFolder]来判断;
如果node是文件夹,可以通过[node children]方法来获取文件夹下的子元素数组,仍然为IFEntryNode的数组对象;
如果node是报表类型,可以通过[[IFEntryViewController alloc] initWithEntry:node]的方式创建出报表视图控制器,并展示报表。    

5. 如何获取决策系统里已经收藏的报表?

 


//第一步,登录服务器
[IFIntegrationUtils logInto:DEFAULT_SERVERNAME serverUrl:url withUsername:username andPassword:password success:^{
    //第二步,登录成功,获取收藏夹报表数组
    [IFIntegrationUtils favorites:^(NSMutableArray *favorites) {
    	//第三步,根据收藏夹报表自定义展示页面
    } failure:^(NSString *message) {
    }];
} failure:^(NSString *msg) {
}];
获取的收藏夹报表数组,一样全是IFEntryNode对象,可以采取一样的方式展示报表。

6. 如何在集成的App里使用微信分享功能?

可参考微信开放平台中的iOS接入指南

7. 怎么登出服务器?

[IFIntegrationUtils logout];

8. OEM定制的App,都支持定制哪些内容?

a. 因为OEM是一个新的工程,可以设置App的图标和名称,因此不需要调用额外的接口就能达到修改App图标和名称的目的;

b. 第一次打开App时,默认服务器列表的定制:

1.删除FR的默认服务器:
[IFOEMUtils removeDemoServer];
		
2.增加一个默认服务器:
[IFOEMUtils addServerWithName:(NSString *)serverName andURL:(NSString *)serverURL addUsername:(NSString *)username addPassword:(NSString *)password userEditable:(BOOL)userEditable];
参数说明
参数名参数说明是否可以为空
serverName服务器名称
serverURL服务器地址
username默认用户名
password默认密码
userEditable用户名、密码以及服务器名称地址是否允许用户修改

c. 关于页面的定制:

1.去除FR默认的关于页面:
[IFOEMUtils removeAbout];
2.自定义关于页面上的信息:
[IFOEMUtils setAppVersion:(NSString *) version];//设置版本号
		[IFOEMUtils setCopyright:(NSString *) copyRight];//设置版权信息
		[IFOEMUtils setAppIconName:(NSString *) iconName];//设置关于页面里的图标。

d. App内默认消息提醒样式的定制:FR内默认消息提醒采用顶部出现会自动消失的蓝色(正常提示消息)或红色(错误/警告消息)提醒消息。如果想使用符合自己App风格的提示消息,可以使用:

[IFOEMUtils setMessageHandler:(void (^) (NSString *message, BOOL isSuccess)) handler];
参数说明	
参数名参数说明
handler消息处理函数

Block参数说明

参数名参数说明
message消息内容
isSuccessYES表示只是提示;NO表示错误/警告

e. App右上角为设置按钮,支持放置自定义按钮:

[IFOEMUtils setAppSettingBarButtonItem:(UIBarButtonItem *) settingItem];

 settingItem:设置按钮。

9. 集成时如何支持报表离线预览

首先,在AppDelegate中的didFinishLaunchingWithOptions方法创建离线所需要的数据库表:

[IFIntegrationUtils createTable];

然后,使用第8个问题中,自定义右上角设置按钮的方式,创建自定义的设置按钮,点击事件打开FR内置的设置界面

IFFrameAppSettingViewController *settingViewController = [[IFFrameAppSettingViewController alloc] initWithCustomItems:customItems];

customItems:是个二维数组,设置界面中除了离线相关的按钮外,还可以自己添加按钮,元素类型为一组关联的设置按钮组,按钮类型为:IFFrameAppSettingItem。

例如:添加一个注销按钮:
IFFrameAppSettingItem *logoutItem = [[IFFrameAppSettingItem alloc] initWithTitle:@"注销" andAction:^(UITableViewCell *selectedCell) {
    [IFIntegrationUtils logOut];
    [self dismissViewControllerAnimated:YES completion:nil];
}];
NSArray *logOutSection = [[NSArray alloc] initWithObjects:logoutItem, nil];
NSArray *customItems = [[NSArray alloc] initWithObjects:logOutSection, nil];
IFFrameAppSettingViewController *settingViewController = [[IFFrameAppSettingViewController alloc] initWithCustomItems:customItems];

10. 如何让App支持修改密码

说明:如果用户是管理员,则任何时候可修改密码;如果服务器是同步数据集或者开启了http认证/ldap认证,则是不支持修改密码的。符合条件后,可以通过如下方式修改密码:

//首先登录
[IFIntegrationUtils logInto:DEFAULT_SERVERNAME serverUrl:url withUsername:username andPassword:password success:^{
	//登录成功后通过此方法获知服务器是否支持修改密码
    if([IFIntegrationUtils canChangePassword]) {
    	//这时候,需要2个参数,原始密码和新密码;这边可以写自己的修改密码让用户输入,比对2次输入是否相同等。假如这边已经拿到原始密码originalPassword和新密码newPassword,则调用
    	[IFIntegrationUtils changePassword:originalPassword newPassword:newPassword success:^{
    		//修改成功
		} failure:^(NSString *message) {
			//修改失败,旧密码有误
		}];
    } else {
    	//服务器不支持修改密码
    }
} failure:^(NSString *msg) {
	//登录失败
}];

11. 如何在集成的App里支持信鸽推送?

第一步:注册信鸽账号

首先需要到信鸽开发中心上注册自己的App,关于证书和程序绑定,上面都会有详细的教程。

注册完成后,会得到三个和App相关的参数:ACCESS ID,ACCESS KEY,SECRET KEY。

客户端需要调用接口来注册程序的ACCESSID和ACESSKEY

第二步:在自己工程里面,引入信鸽的库"XGPush"

引入的方式,可以参考FRDemo,直接加入工程(也可以通过cocoapods,至于cocoapods怎么管理第三方库,可以自己百度谷歌看看)

第三步:在App中注册信鸽
//AppDelegate.m
//App启动的时候,设置好本机信鸽的access id、access key(第一步中拿到的)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	[IFOEMUtils setXinGeAppId:123456788];	//access id
	[IFOEMUtils setXinGeAppKey:@"ISHGJ5A7342D"];//accesskey
	//do somethigs
	return YES;
}

如果是OEM集成,客户端做这些就可以了。如果是一般集成,在AppDelegate中还需要做如下注册信鸽的设置:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
	NSString * deviceTokenStr = [XGPush registerDevice:deviceToken];
	[XGPush registerDevice:deviceToken];
	[IFIntegrationUtils setDeviceToken:deviceTokenStr];//必须,在程序里记录设备。
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
	[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
	// 处理推送消息
}
第四步:服务器设置

先要给FineReport服务器安装好信鸽插件

安装好后,可以考到这个设置界面

填入iOS用的ACCESS ID 和 secret key ,保存

第五步:测试

a. 手机登录到服务器(必须是真机)。登录成功后,按home键,让app进入后台(或者锁屏)

b.创建定时调度任务

按下方添加定时调度任务

一分钟之内,手机应该会收到如下的消息



12. 如何获取报表在服务器端配置的封面图?

在通过IFIntegrationUtils loadReportTree方法获取到IFEntryNode数组后,对每一个entryNode,使用

[IFIntegrationUtils readEntryImage:entryNode.entryId coverId:entryNode.coverId sucess:^(UIImage *image) {
        //image就是服务器端配置的缩略图,这个方法是做过缓存处理的,不用担心每次都会向服务器发请求。
}];

13. 如何展示非全屏的报表 说明:目前不支持填报报表的非全屏展现,只支持单页分页/表单的展现

IFEntryView *entryView = [[IFEntryView alloc] initWithPath:@"app/DetailedDrillA-phone.cpt" serverUrl:@"http://www.finereporthelp.com:8889/app/ReportServer" viewType:IFEntryViewTypePage parameters:nil];
[entryView setFrame:CGRectMake(0, 64, 800, 600)];
entryView.entryViewDelegate = self;
[self.view addSubview:entryView];
[entryView doLoad];	//加载报表

使用报表视图的对象,需要实现IFEntryViewDelegate中的方法,让报表正常展示

-(void)pushHyperLink:(UIViewController *)viewController withAnimate:(BOOL)animate {
//处理报表View超级链接产生的视图控制器。
}

14. 如何支持国际化

1.打开工程,supporting files目录下新建Localizable.strings国际化基础文件,(demo里面的目前仅支持中文简体,中文繁体及英文语言环境(chinese simple,chinese traditional,english))。 详细教程见:http://blog.sina.com.cn/s/blog_7b9d64af0101jncz.html或者网上搜索ios如何国际化.

2.需要支持国际化的东西,则在对应语言里写上key和翻译就可以。例如:

NSString * myKey = NSLocalizedString(@"MY_KEY",nil);

此时,myKey这个字符串在不同语言环境下的key就是"MYKEY".然后去Localizable.strings(english)文件中添加一行"MYKEY"="my key";在Localizable.strings(chinese(simple))文件中添加一行"MYKEY"="我的关键词";同理在繁体文件中添加key对应的翻译。 在不同的语言环境下,myKey显示的文字就是"MYKEY"对应的翻译

15. 集成时APP名称怎么支持国际化

打开工程,在supporting files目录下新建文件,InfoPlist.strings(New File——Resource——String File,命名未InfoPlist.strings),右侧属性里点击Localization,勾选英文,中文简体,中文繁体。在里面添加Key:CFBundleDisplayName,并补充好对应的中英繁文字即可。

16. 如何从外部App启动帆软的数据分析

使用url scheme启动,帆软的url scheme是FineReport或者com.fr.FineReport,运行如下代码即可

启动FRApp
//注意,如果url里有中文或者//这种特殊字符,需要在生成URL之前,做一次encode([string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding])
NSURL *url = [NSURL URLWithString:@"FineReport://"];
//NSURL *url = [NSURL URLWithString:@"com.fr.FineReport://"]; //也可以这样写
//NSURL *url = [NSURL URLWithString:@"com.fr.FineReport://?serverName=test&serverUrl=xxxxxx&fr_username=a&fr_password=123"]; //传递服务器地址、服务器名、用户名、密码, 注意url特殊字符要encode
//以上参数也可以通过JSON传递,如下
//NSURL *url = [NSURL URLWithString:@"com.fr.FineReport://{\"serverName\":\"xxxxx\", \"serverUrl\":\"http://xxxxx\", \"fr_username\":\"a\", \"fr_password\":\"123\"}"]
//需要注意以下三种情况
//1. serverName已存在,并且serverUrl相同,则使用提供的用户名密码登陆
//2. serverName已存在, 但是serverUrl不同,则会提示"服务器同名"
//3. serverName不存在, 会添加该服务器,并且登陆

[[UIApplication sharedApplication] openURL:url];
 

在iOS9往后,如果想通过代码判断帆软App是否被正确安装,需要将FineReport和com.fr.FineReport加入scheme白名单中,具体见下图

17.使用微信分享,提示微信未安装


这个问题和第16点其实是一个原因,需要把微信加入白名单

18.使用微信分享,分享到微信后,微信中显示的app信息为“FRDemo”或者“数据分析”


这里首先,需要保证用户有自己的微信appid,用户可以自己去微信申请。appid里会有设置应用名称,图标等信息。

然后在这个地方改成所申请的appid

并在app启动的时候,绑定appid

19.OEM时如何去除设置里的去评分等按钮

第一步,自定义右上设置按钮

自定义设置按钮
UIBarButtonItem *setting = [[UIBarButtonItem alloc] initWithTitle:@"设置" style:UIBarButtonItemStylePlain target:self action:@selector(setting)];  
 
[IFOEMUtils setAppSettingBarButtonItem:setting];

第二步,定义设置按钮事件,打开我们内置的设置界面(不带去评分,联系我们等按钮),但是没有注销按钮(可自己实现)

打开FR设置界面
- (void) setting {
  //定义一个注销按钮
  IFFrameAppSettingItem *logoutItem = [[IFFrameAppSettingItem alloc] initWithTitle:@"注销" andAction:^(UITableViewCell *selectedCell) {
    //注销
    [IFIntegrationUtils logOut];
    //让页面消失,这里需要写一个获取当前最前端视图(当前就是设置界面)的方法,后面会有示例,也可以把设置页面在类里定义成变量能引用到。
    [[self topViewControllerWithRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController] dismissViewControllerAnimated:YES   completion:nil];
  }];
 
  //把自定义注销按钮放在数组里,后面给创建设置页面使用
  NSArray *logOutSection = [[NSArray alloc] initWithObjects:logoutItem, nil];
  NSArray *customItems = [[NSArray alloc] initWithObjects:logOutSection, nil];
 
  //定义设置页面
  IIFFrameAppSettingViewController *settingViewController; = [[IFFrameAppSettingViewController alloc] initWithCustomItems:customItems];
  
  //根据手机/Pad设置不同的弹出方式
  BOOL isPhone = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone;
  UIViewController *topViewController = [self topViewControllerWithRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController];
  if(isPhone) {
    [topViewController.navigationController pushViewController:settingViewController animated:YES];
  } else {
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingViewController];
    navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
    [topViewController presentViewController:navigationController animated:YES completion:nil];
  }
}
//获取当前顶部视图
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
  if ([rootViewController isKindOfClass:[UITabBarController class]]) {
    UITabBarController* tabBarController = (UITabBarController*)rootViewController;
    return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
  } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController* nav = (UINavigationController*)rootViewController;
    return [self topViewControllerWithRootViewController:nav.topViewController];
  } else if (rootViewController.presentedViewController) {
    UIViewController* presentedViewController = rootViewController.presentedViewController;
    if([presentedViewController isKindOfClass:[UIAlertController class]]) {
      return rootViewController;
    }
    return [self topViewControllerWithRootViewController:presentedViewController];
  } else {
    return rootViewController;
  }
}

效果图如下:

 

  • No labels