├── .gitignore
├── .idea
├── vcs.xml
├── xcode.xml
├── modules.xml
├── misc.xml
├── workspace.xml
└── ApplicationManager.iml
├── AppBrowser.xcodeproj
├── project.xcworkspace
│ ├── xcuserdata
│ │ └── lan.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ └── contents.xcworkspacedata
├── xcuserdata
│ └── lan.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ └── AppBrowser.xcscheme
└── project.pbxproj
├── AppBrowser
├── Controller
│ ├── LANAppListViewController.h
│ ├── LANAppViewController.h
│ ├── LANProListViewController.h
│ ├── LANAppListViewController.m
│ ├── LANProListViewController.m
│ └── LANAppViewController.m
├── Common
│ ├── Category
│ │ ├── NSArray+LAN.h
│ │ ├── NSDictionary+LAN.h
│ │ ├── NSArray+LAN.m
│ │ ├── UIView+LAN.h
│ │ ├── UIView+LAN.m
│ │ └── NSDictionary+LAN.m
│ ├── RuntimeInvoker.h
│ └── RuntimeInvoker.m
├── View
│ ├── LANAppListCell.h
│ ├── LANPathDisplayView.h
│ ├── LANAppListCell.m
│ ├── LANProListCell.h
│ ├── LANProListCell.m
│ └── LANPathDisplayView.m
├── AppDelegate.h
├── main.m
├── Model
│ ├── LANAppHelper.h
│ └── LANAppHelper.m
├── Info.plist
├── Base.lproj
│ └── LaunchScreen.storyboard
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
└── AppDelegate.m
├── PrefixHeader.pch
├── LANGlobalDefine.h
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .idea/workspace.xml
3 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/xcode.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/AppBrowser.xcodeproj/project.xcworkspace/xcuserdata/lan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanvsblue/AppBrowser/HEAD/AppBrowser.xcodeproj/project.xcworkspace/xcuserdata/lan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/AppBrowser/Controller/LANAppListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/24.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 |
9 | @interface LANAppListViewController : UIViewController
10 | @end
--------------------------------------------------------------------------------
/AppBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AppBrowser/Common/Category/NSArray+LAN.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/29.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 | @interface NSArray (LAN)
9 |
10 | + (instancetype)getProperties:(Class)cls;
11 |
12 | @end
--------------------------------------------------------------------------------
/AppBrowser.xcodeproj/project.xcworkspace/xcuserdata/lan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AppBrowser/View/LANAppListCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/24.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 |
9 | @interface LANAppListCell : UITableViewCell
10 |
11 | @property(nonatomic, retain) id application;
12 |
13 | @end
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AppBrowser/Controller/LANAppViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LANAppViewController.h
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/29.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 |
10 |
11 | @interface LANAppViewController : UIViewController
12 | @property (nonatomic, retain) id application;
13 | @end
14 |
--------------------------------------------------------------------------------
/AppBrowser/Common/Category/NSDictionary+LAN.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/29.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 | #define SUPER_CLASS @"Super Class"
9 |
10 | @interface NSDictionary (LAN)
11 |
12 | + (NSDictionary *)getDictionaryFromObject:(id)obj;
13 |
14 | @end
--------------------------------------------------------------------------------
/AppBrowser/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/24.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (strong, nonatomic) UIWindow *window;
15 |
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // PrefixHeader.pch
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/24.
6 | // Copyright © 2016年 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #ifndef PrefixHeader_pch
10 | #define PrefixHeader_pch
11 |
12 | #import "LANGlobalDefine.h"
13 | #import "UIView+LAN.h"
14 | #import "RuntimeInvoker.h"
15 |
16 |
17 | #endif /* PrefixHeader_pch */
18 |
--------------------------------------------------------------------------------
/AppBrowser/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/24.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 |
13 | int main(int argc, char * argv[]) {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/AppBrowser/View/LANPathDisplayView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LANPathDisplayView.h
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/30.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 |
10 |
11 | @interface LANPathDisplayView : UIView
12 |
13 | @property (nonatomic, retain)NSString *displayPath;
14 |
15 | -(NSString *)setDisplayPath:(NSString *)disPath addPath:(NSString *)addPath;
16 |
17 | -(void)setupView;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/AppBrowser/View/LANAppListCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/24.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import "LANAppListCell.h"
7 | #import "LANAppHelper.h"
8 |
9 |
10 | @implementation LANAppListCell {
11 |
12 | }
13 |
14 | - (void)layoutSubviews {
15 | [super layoutSubviews];
16 | self.imageView.image = [LANAppHelper iconForApplication:self.application];
17 | self.textLabel.text = [LANAppHelper nameForApplication:self.application];
18 |
19 | }
20 | @end
--------------------------------------------------------------------------------
/AppBrowser/View/LANProListCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LANProListCell.h
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/30.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 |
10 |
11 | @interface LANProListCell : UITableViewCell
12 | @property(nonatomic, retain) NSString *title;
13 | @property(nonatomic, retain) NSString *subTitle;
14 | @property(nonatomic, assign) UITableViewCellAccessoryType type;
15 | @property (nonatomic, assign) NSInteger itemCount;
16 | @property(nonatomic, assign) BOOL isFavorite;
17 | @end
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/AppBrowser.xcodeproj/xcuserdata/lan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | AppBrowser.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 1A199ABA0306E42DA9CC2EFA
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AppBrowser/Controller/LANProListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LANProListViewController.h
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/29.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | @class LANPathDisplayView;
10 | typedef NS_ENUM(NSInteger,LANPropertiesType) {
11 | LANPropertiesTypeArray = 1,
12 | LANPropertiesTypeDictionary,
13 | LANPropertiesTypeKeyDict,
14 | LANPropertiesTypeValue
15 | };
16 |
17 | typedef void (^LANItemInfoFetchBlock)(UITableViewCellAccessoryType accessoryType, NSString *title, NSString *subtitle);
18 |
19 |
20 | @interface LANProListViewController : UIViewController
21 |
22 | -(id)initWithProperties:(id)properties;
23 |
24 | @property (nonatomic, retain)LANPathDisplayView *pathDisplayView;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/AppBrowser/Model/LANAppHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/24.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 |
9 | @interface LANAppHelper : NSObject
10 |
11 | // operate
12 | +(id)defaultWorkspace;
13 |
14 | +(id)allInstalledApplications;
15 |
16 | +(BOOL)openApplication:(id)application;
17 |
18 | +(BOOL)removeApplication:(id)application;
19 |
20 |
21 | // get app info
22 | +(id)nameForApplication:(id)application;
23 |
24 | +(id)iconForApplication:(id)application;
25 |
26 | +(id)vendorNameForApplication:(id)application;
27 |
28 | +(id)appTypeForApplication:(id)application;
29 |
30 | +(id)bundleIDForApplication:(id)application;
31 |
32 | +(NSDictionary *)infoForApplication:(id)application;
33 |
34 | @end
--------------------------------------------------------------------------------
/LANGlobalDefine.h:
--------------------------------------------------------------------------------
1 | //
2 | // LANGlobalDefine.h
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/24.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #ifndef LANGlobalDefine_h
10 | #define LANGlobalDefine_h
11 |
12 | //screen define
13 | #define SCREEN_BOUNDS [UIScreen mainScreen].bounds
14 | #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
15 | #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
16 |
17 | //const
18 | #define APP_NAME_KEY_PATH @"_infoDictionary.propertyList.CFBundleDisplayName"
19 | #define APP_SHORT_NAME_KEY_PATH @"localizedShortName"
20 | #define APP_BUNDLE_ID_KEY_PATH @"appState.bundleIdentifier"
21 | #define APP_PROPERTY_LIST_KEY_PATH @"_infoDictionary.propertyList"
22 |
23 | #endif /* LANGlobalDefine_h */
24 |
--------------------------------------------------------------------------------
/AppBrowser/Common/Category/NSArray+LAN.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/29.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import "NSArray+LAN.h"
7 | #import // 导入运行时文件
8 | @implementation NSArray (Extension)
9 |
10 | //返回当前类的所有属性
11 | + (instancetype)getProperties:(Class)cls{
12 |
13 | // 获取当前类的所有属性
14 | unsigned int count;// 记录属性个数
15 | objc_property_t *properties = class_copyPropertyList(cls, &count);
16 | // 遍历
17 | NSMutableArray *mArray = [NSMutableArray array];
18 | for (int i = 0; i < count; i++) {
19 |
20 | // An opaque type that represents an Objective-C declared property.
21 | // objc_property_t 属性类型
22 | objc_property_t property = properties[i];
23 | // 获取属性的名称 C语言字符串
24 | const char *cName = property_getName(property);
25 | // 转换为Objective C 字符串
26 | NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
27 | [mArray addObject:name];
28 | }
29 |
30 | return mArray.copy;
31 | }
32 |
33 |
34 | @end
--------------------------------------------------------------------------------
/AppBrowser/View/LANProListCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LANProListCell.m
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/30.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import "LANProListCell.h"
10 | #import "NSDictionary+LAN.h"
11 |
12 | @implementation LANProListCell
13 |
14 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
15 | if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]){
16 | [self initView];
17 | }
18 | return self;
19 | }
20 |
21 | -(void)initView{
22 |
23 | }
24 |
25 | -(void)layoutSubviews {
26 | [super layoutSubviews];
27 | if([self.title isEqualToString:SUPER_CLASS]){
28 | self.textLabel.font = [UIFont boldSystemFontOfSize:17];
29 | }
30 | self.textLabel.text = self.title;
31 | self.detailTextLabel.text = self.subTitle;
32 | self.accessoryType = self.type;
33 | }
34 |
35 | - (void)copy:(id)sender {
36 | [UIPasteboard generalPasteboard].string = [NSString stringWithFormat:@"%@ | %@",self.title,self.subTitle];
37 | }
38 |
39 | //-(void)favoriteItem:(id)sender{
40 | // NSLog(@"favoriteItem");
41 | //}
42 | //
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/AppBrowser/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | AppBrowser
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/AppBrowser/Common/Category/UIView+LAN.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 16/7/16.
3 | // Copyright (c) 2016 lanvsblue. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 | @interface UIView (LAN)
9 |
10 | /*
11 | * @brief 视图左侧X轴坐标
12 | * getters: UIView.frame.origin.x
13 | * setters: UIView.frame.origin.x = originX
14 | */
15 | @property (nonatomic, assign) CGFloat originX;
16 |
17 | /*
18 | * @brief 视图顶部Y轴坐标
19 | * getters: UIView.frame.origin.y
20 | * setters: UIView.frame.origin.y = originY
21 | */
22 | @property (nonatomic, assign) CGFloat originY;
23 |
24 | /*
25 | * @brief 视图右侧X轴坐标
26 | * getters: UIView.frame.origin.x + UIView.frame.size.width
27 | * setters: UIView.frame.origin.x = rightX - UIView.frame.size.width
28 | */
29 | @property (nonatomic, assign) CGFloat rightX;
30 |
31 | /*
32 | * @brief 视图下方Y轴坐标
33 | * getters: UIView.frame.origin.y + UIView.frame.size.height
34 | * setters: UIView.frame.origin.y = bottomY - UIView.frame.size.height
35 | */
36 | @property (nonatomic, assign) CGFloat bottomY;
37 |
38 | /*
39 | * @brief 视图高度
40 | * getters: UIView.frame.size.height
41 | * setters: UIView.frame.size.height = height
42 | */
43 | @property (nonatomic, assign) CGFloat height;
44 |
45 | /*
46 | * @brief 视图宽度
47 | * getters: UIView.frame.size.width
48 | * setters: UIView.frame.size.width = width
49 | */
50 |
51 |
52 | @property (nonatomic, assign)CGFloat width;
53 |
54 | /*
55 | * 获取当前view所在的viewController
56 | */
57 | @property (nonatomic, readonly) UIViewController *viewController;
58 |
59 |
60 | /*
61 | * 移除所有的子View
62 | */
63 | - (void)removeAllSubviews;
64 |
65 | /*
66 | * 移除数组中所有的子View
67 | */
68 | -(void)removeSubViews:(NSArray *)views;
69 |
70 |
71 |
72 | /*
73 | * 不响应父类的事件
74 | */
75 | -(void)noActionForSuperEvent;
76 |
77 | @end
--------------------------------------------------------------------------------
/AppBrowser/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AppBrowser/View/LANPathDisplayView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LANPathDisplayView.m
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/30.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import "LANPathDisplayView.h"
10 |
11 | @interface LANPathDisplayView()
12 |
13 | @property (nonatomic, retain)UILabel *pathLabel;
14 | @end
15 |
16 | @implementation LANPathDisplayView{
17 | NSMutableArray *_pathArray;
18 | }
19 |
20 | - (instancetype)initWithFrame:(CGRect)frame {
21 | if(self=[super initWithFrame:frame]){
22 | [self initView];
23 | _pathArray = [[NSMutableArray alloc] init];
24 | }
25 | return self;
26 | }
27 |
28 | -(void)initView{
29 | self.backgroundColor = [UIColor grayColor];
30 |
31 | self.pathLabel = [[UILabel alloc] initWithFrame:CGRectMake(5,0,self.width-5,self.height)];
32 | [self addSubview:self.pathLabel];
33 | }
34 |
35 | -(void)setupView {
36 | self.pathLabel.text = self.displayPath;
37 | self.pathLabel.font = [UIFont systemFontOfSize:12];
38 | self.pathLabel.textColor = [UIColor whiteColor];
39 | self.pathLabel.lineBreakMode = NSLineBreakByTruncatingHead;
40 | }
41 |
42 | - (void)setDisplayPath:(NSString *)displayPath {
43 | _pathArray = [[displayPath componentsSeparatedByString:@"."] mutableCopy];
44 | }
45 |
46 | - (NSString *)setDisplayPath:(NSString *)disPath addPath:(NSString *)addPath {
47 | self.displayPath = disPath;
48 | [self addPath:addPath];
49 | return self.displayPath;
50 | }
51 |
52 |
53 | -(NSString *)displayPath {
54 | return [_pathArray componentsJoinedByString:@"."];
55 | }
56 |
57 | - (NSString *)addPath:(NSString *)path {
58 | if([path hasPrefix:@"Item "]){
59 | _pathArray[_pathArray.count-1] = [NSString stringWithFormat:@"%@[%@]",_pathArray[_pathArray.count-1],[path substringFromIndex:5]];
60 | } else{
61 | [_pathArray addObject:path];
62 | }
63 | return self.displayPath;
64 | }
65 |
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/AppBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "icon@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "icon@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "idiom" : "ipad",
47 | "size" : "20x20",
48 | "scale" : "1x"
49 | },
50 | {
51 | "idiom" : "ipad",
52 | "size" : "20x20",
53 | "scale" : "2x"
54 | },
55 | {
56 | "idiom" : "ipad",
57 | "size" : "29x29",
58 | "scale" : "1x"
59 | },
60 | {
61 | "idiom" : "ipad",
62 | "size" : "29x29",
63 | "scale" : "2x"
64 | },
65 | {
66 | "idiom" : "ipad",
67 | "size" : "40x40",
68 | "scale" : "1x"
69 | },
70 | {
71 | "idiom" : "ipad",
72 | "size" : "40x40",
73 | "scale" : "2x"
74 | },
75 | {
76 | "idiom" : "ipad",
77 | "size" : "76x76",
78 | "scale" : "1x"
79 | },
80 | {
81 | "idiom" : "ipad",
82 | "size" : "76x76",
83 | "scale" : "2x"
84 | },
85 | {
86 | "idiom" : "ipad",
87 | "size" : "83.5x83.5",
88 | "scale" : "2x"
89 | }
90 | ],
91 | "info" : {
92 | "version" : 1,
93 | "author" : "xcode"
94 | }
95 | }
--------------------------------------------------------------------------------
/AppBrowser/Model/LANAppHelper.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/24.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import "LANAppHelper.h"
7 | #import "NSArray+LAN.h"
8 | #import "NSDictionary+LAN.h"
9 |
10 |
11 | @implementation LANAppHelper {
12 |
13 | }
14 | + (id)defaultWorkspace {
15 | return [@"LSApplicationWorkspace" invokeClassMethod:@"defaultWorkspace"];
16 | }
17 |
18 | + (id)allInstalledApplications {
19 | return [[self defaultWorkspace] invoke:@"allInstalledApplications"];
20 | }
21 |
22 | + (BOOL)openApplication:(id)application {
23 | return [[self defaultWorkspace] invoke:@"openApplicationWithBundleID:" args:[self bundleIdentifierForApplication:application],nil];
24 | }
25 |
26 | + (BOOL)removeApplication:(id)application {
27 |
28 | #if TARGET_IPHONE_SIMULATOR
29 | return [[self defaultWorkspace] invoke:@"uninstallApplication:withOptions:" args:[application bundleIdentifier],nil,nil];
30 | #elif TARGET_OS_IPHONE//真机
31 | return false;
32 | #endif
33 |
34 | }
35 |
36 |
37 | + (id)nameForApplication:(id)application {
38 | return [([application valueForKeyPath:APP_NAME_KEY_PATH] ?: [application valueForKeyPath:APP_SHORT_NAME_KEY_PATH]) description];
39 | }
40 |
41 | +(id)bundleIdentifierForApplication:(id)application{
42 | return [application valueForKey:@"bundleIdentifier"];
43 | }
44 |
45 | + (id)iconForApplication:(id)application {
46 | return [UIImage invoke:@"_applicationIconImageForBundleIdentifier:format:scale:"
47 | args:[application bundleIdentifier],@"",@([UIScreen mainScreen].scale),nil];
48 | }
49 |
50 | + (id)vendorNameForApplication:(id)application {
51 | return [[self appTypeForApplication:application] isEqualToString:@"System"]? @"Apple":[application valueForKey:@"vendorName"];
52 | }
53 |
54 | + (id)appTypeForApplication:(id)application {
55 | return [application valueForKey:@"applicationType"];
56 | }
57 |
58 | + (id)bundleIDForApplication:(id)application {
59 | return [application valueForKeyPath:APP_BUNDLE_ID_KEY_PATH];
60 | }
61 |
62 |
63 | +(NSDictionary *)infoForApplication:(id)application{
64 | return [NSDictionary getDictionaryFromObject:application];
65 | }
66 |
67 |
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/AppBrowser/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/24.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "LANAppListViewController.h"
11 |
12 |
13 | @interface AppDelegate ()
14 |
15 | @end
16 |
17 | @implementation AppDelegate
18 |
19 |
20 |
21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
22 | self.window = [[UIWindow alloc] initWithFrame:SCREEN_BOUNDS];
23 |
24 | LANAppListViewController *viewController = [[LANAppListViewController alloc] init];
25 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
26 |
27 | self.window.rootViewController = navigationController;
28 | [self.window makeKeyAndVisible];
29 | return YES;
30 | }
31 |
32 |
33 | - (void)applicationWillResignActive:(UIApplication *)application {
34 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
35 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
36 |
37 | }
38 |
39 |
40 | - (void)applicationDidEnterBackground:(UIApplication *)application {
41 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
42 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
43 |
44 | }
45 |
46 |
47 | - (void)applicationWillEnterForeground:(UIApplication *)application {
48 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
49 | }
50 |
51 |
52 | - (void)applicationDidBecomeActive:(UIApplication *)application {
53 | // 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.
54 | }
55 |
56 |
57 | - (void)applicationWillTerminate:(UIApplication *)application {
58 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
59 | }
60 |
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/AppBrowser/Common/RuntimeInvoker.h:
--------------------------------------------------------------------------------
1 | //
2 | // RuntimeInvoker.h
3 | // RuntimeInvoker
4 | //
5 | // Created by cyan on 16/5/27.
6 | // Copyright © 2016年 cyan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSObject (RuntimeInvoker)
12 |
13 | /**
14 | * Invoke a selector with name
15 | *
16 | * @param selector Selector name
17 | *
18 | * @return Return value
19 | */
20 | - (id)invoke:(NSString *)selector;
21 |
22 | /**
23 | * Invoke a selector with name and args
24 | *
25 | * @param selector Selector name
26 | * @param arg Arguments list (end with nil)
27 | *
28 | * @return Return value
29 | */
30 | - (id)invoke:(NSString *)selector args:(id)arg, ... ;
31 |
32 | /**
33 | * Invoke a selector with name and args
34 | *
35 | * @param selector Selector name
36 | * @param arguments Arguments list
37 | *
38 | * @return Return value
39 | */
40 | - (id)invoke:(NSString *)selector arguments:(NSArray *)arguments;
41 |
42 | /**
43 | * Invoke a selector with name (Class Method)
44 | *
45 | * @param selector Selector name
46 | *
47 | * @return Return value
48 | */
49 | + (id)invoke:(NSString *)selector;
50 |
51 | /**
52 | * Invoke a selector with name and args (Class Method)
53 | *
54 | * @param selector Selector name
55 | * @param arg Arguments list (end with nil)
56 | *
57 | * @return Return value
58 | */
59 | + (id)invoke:(NSString *)selector args:(id)arg, ... ;
60 |
61 | /**
62 | * Invoke a selector with name and args (Class Method)
63 | *
64 | * @param selector Selector name
65 | * @param arguments Arguments list
66 | *
67 | * @return Return value
68 | */
69 | + (id)invoke:(NSString *)selector arguments:(NSArray *)arguments;
70 |
71 | @end
72 |
73 |
74 | /**
75 | NSString Category for Class Method
76 | */
77 | @interface NSString (RuntimeInvoker)
78 |
79 | /**
80 | Invoke class method with NSString
81 |
82 | @param selector Selector name
83 | @return Return value
84 | */
85 | - (id)invokeClassMethod:(NSString *)selector;
86 |
87 |
88 | /**
89 | Invoke class method with NSString
90 |
91 | @param selector Selector name
92 | @param arg Arguments list (end with nil)
93 | @return Return value
94 | */
95 | - (id)invokeClassMethod:(NSString *)selector args:(id)arg, ... ;
96 |
97 |
98 | /**
99 | Invoke class method with NSString
100 |
101 | @param selector Selector name
102 | @param arguments Arguments list
103 | @return Return value
104 | */
105 | - (id)invokeClassMethod:(NSString *)selector arguments:(NSArray *)arguments;
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/AppBrowser/Common/Category/UIView+LAN.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 16/7/16.
3 | // Copyright (c) 2016 lanvsblue. All rights reserved.
4 | //
5 |
6 | #import
7 | #import "UIView+LAN.h"
8 |
9 |
10 |
11 |
12 | @implementation UIView (LAN)
13 |
14 | - (CGFloat)originX {
15 | return self.frame.origin.x;
16 | }
17 |
18 | - (void)setOriginX:(CGFloat)originX {
19 | CGRect frame = self.frame;
20 | frame.origin.x = originX;
21 | self.frame = frame;
22 | }
23 |
24 | - (CGFloat)originY {
25 | return self.frame.origin.y;
26 | }
27 |
28 | - (void)setOriginY:(CGFloat)originY {
29 | CGRect frame = self.frame;
30 | frame.origin.y = originY;
31 | self.frame = frame;
32 | }
33 |
34 | - (CGFloat)rightX {
35 | return self.frame.origin.x + self.frame.size.width;
36 | }
37 |
38 | - (void)setRightX:(CGFloat)rightX {
39 | CGRect frame = self.frame;
40 | frame.origin.x = rightX - self.frame.size.width;
41 | self.frame = frame;
42 | }
43 |
44 | - (CGFloat)bottomY {
45 | return self.frame.origin.y + self.frame.size.height;
46 | }
47 |
48 | - (void)setBottomY:(CGFloat)bottomY {
49 | CGRect frame = self.frame;
50 | frame.origin.y = bottomY - self.frame.size.height;
51 | self.frame = frame;
52 | }
53 |
54 | - (CGFloat)height {
55 | return self.frame.size.height;
56 | }
57 |
58 | - (void)setHeight:(CGFloat)height {
59 | CGRect frame = self.frame;
60 | frame.size.width = height;
61 | self.frame = frame;
62 | }
63 |
64 | - (CGFloat)width {
65 | return self.frame.size.width;
66 | }
67 |
68 | - (void)setWidth:(CGFloat)width {
69 | CGRect frame = self.frame;
70 | frame.size.width = width;
71 | self.frame = frame;
72 | }
73 |
74 | - (UIViewController *)viewController {
75 | for (UIView* next = [self superview]; next; next = next.superview) {
76 | UIResponder *nextResponder = [next nextResponder];
77 | if ([nextResponder isKindOfClass:[UIViewController class]]) {
78 | return (UIViewController *)nextResponder;
79 | }
80 | }
81 | return nil;
82 | }
83 |
84 | - (void)removeAllSubviews {
85 | while (self.subviews.count) {
86 | UIView* child = self.subviews.lastObject;
87 | [child removeFromSuperview];
88 | }
89 | }
90 |
91 | -(void)removeSubViews:(NSArray *)views{
92 | for (UIView *view in views) {
93 | [view removeFromSuperview];
94 | }
95 | }
96 |
97 | - (void)noActionForSuperEvent {
98 | UITapGestureRecognizer *forbidSuperGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil];
99 | [self addGestureRecognizer:forbidSuperGesture];
100 | }
101 |
102 |
103 | @end
--------------------------------------------------------------------------------
/AppBrowser/Common/Category/NSDictionary+LAN.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/29.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import "NSDictionary+LAN.h"
7 | #import "NSArray+LAN.h"
8 |
9 |
10 | @implementation NSDictionary (LAN)
11 | + (NSDictionary *)getDictionaryFromObject:(id)obj{
12 | NSMutableArray *superObjDic = [[NSMutableArray alloc] init];
13 | return [self getDictionary:obj objDic:superObjDic convertClass:[obj class]];
14 | }
15 |
16 | +(id)getDictionary:(id)obj objDic:(NSMutableArray *)superObjDic convertClass:(Class)convertClass{
17 |
18 | if ([obj isKindOfClass:[NSArray class]]) {
19 | NSMutableArray *subObj = [NSMutableArray array];
20 | for (id o in obj) {
21 | [subObj addObject:[self getDictionary:o objDic:superObjDic convertClass:[o class]]];
22 | }
23 | return subObj;
24 | } else if ([obj isKindOfClass:[NSDictionary class]]) {
25 | NSMutableDictionary *subObj = [NSMutableDictionary dictionary];
26 | for (id o in [obj allKeys]) {
27 | subObj[o] = [self getDictionary:obj[o] objDic:superObjDic convertClass:[obj[o] class]];
28 | }
29 | return subObj;
30 | } else if ([obj isKindOfClass:[NSURL class]]){
31 | return [obj absoluteString];
32 | } else if ([obj isKindOfClass:[NSString class]]) {
33 | return obj;
34 | } else if ([obj isKindOfClass:[NSDate class]]) {
35 | return [obj description];
36 | } else if ([obj isKindOfClass:[NSNumber class]]) {
37 | return obj;
38 | } else if ([obj isKindOfClass:[NSUUID class]]) {
39 | return [obj UUIDString];
40 | } else if ([[obj class] isSubclassOfClass:[NSObject class]] && ![obj isKindOfClass:NSClassFromString(@"OS_object")]) {
41 | //is analysis
42 | NSInteger index = [superObjDic indexOfObject:obj];
43 | if(index != NSNotFound&& [superObjDic[index] class]==convertClass){//if index found and class same
44 | return @{@"Command <<<":@(index)};
45 | } else {
46 | [superObjDic addObject:obj];
47 | }
48 |
49 | NSMutableDictionary *info = [[NSMutableDictionary alloc] init];
50 |
51 | //get all keys
52 | NSArray *allkeys = [NSArray getProperties:convertClass];
53 | for (NSString *key in allkeys) {
54 | //get value
55 | id value = [obj valueForKey:key];
56 |
57 | //show class name
58 | NSString *displayKey = [NSString stringWithFormat:@"%@ : %@",key, [value class]];
59 | info[key] = [self getDictionary:value objDic:superObjDic convertClass:[value class]];
60 | }
61 |
62 | //get super class info
63 | Class objSuperClass = [convertClass superclass];
64 | if(objSuperClass!=[NSObject class]){
65 | NSString *displayKey = [NSString stringWithFormat:@"%@ : %@",SUPER_CLASS, objSuperClass];
66 | info[SUPER_CLASS] = [self getDictionary:obj objDic:superObjDic convertClass:objSuperClass];
67 | }
68 |
69 |
70 | return info;
71 | }
72 | return nil;
73 | }
74 |
75 | @end
--------------------------------------------------------------------------------
/AppBrowser.xcodeproj/xcshareddata/xcschemes/AppBrowser.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AppBrowser(Application属性查看器,不需要越狱!!!)
2 |
3 | 不需要越狱,调用私有方法 --- 获取完整的已安装应用列表、打开和删除应用操作、应用运行时相关信息的查看。
4 |
5 | 支持iOS10.X
6 |
7 | ## 注意
8 |
9 | 目前AppBrowser不支持iOS11应用查看, 由于iOS11目前还处在Beta版, 系统API还没有稳定下来。等到[Private Header](https://github.com/nst/iOS-Runtime-Headers)更新了iOS11版本,我也会进行更新。
10 |
11 | ## 功能
12 | - [x] 已安装的应用列表
13 | - [x] 应用的详情界面 (打开应用,删除应用,应用的相关信息展示)
14 | - [x] 应用运行时信息展示(LSApplicationProxy)
15 | - [ ] 定制喜欢的字段,展示在应用详情界面
16 |
17 | ## 介绍
18 |
19 | #### 所有已安装应用列表(应用icon+应用名)
20 |
21 | > 为了提供思路,这里只用伪代码,具体的私有代码调用请查看:`AppBrowser/AppBrowser/Model/LANAppHelper.m`
22 |
23 | 获取应用实例:
24 |
25 | ```objc
26 | //首先获取 LSApplicationWorkspace 实例
27 | //对应于LANAppHelper类中的+(id)defaultWorkspace;方法:
28 | id applicationWorkspace = [LSApplicationWorkspace defaultWorkspace];
29 |
30 | //使用 LSApplicationWorkspace 获取应用列表(LSApplicationProxy对象列表)
31 | //对应于LANAppHelper类中的+(id)allInstalledApplications;方法:
32 | NSArray applicationArray = [applicationWorkspace allInstalledApplications];
33 |
34 | //取出第一个应用对象
35 | id application = applicationArray[0];
36 | ```
37 |
38 | 获取应用名和应用的icon:
39 | ```objc
40 | /*
41 | * APP_NAME_KEY_PATH 和 APP_SHORT_NAME_KEY_PATH 的定义在代码头上
42 | * 应用的名字有可能出现在两个地方:
43 | * 在桌面上显示的普通应用的应用名来自info.plist文件中的CFBundleDisplayName字段
44 | * 在桌面的部分系统应用显示的是localizedShortName
45 | * 对应于LANAppHelper类中的+(id)nameForApplication:(id)application;方法:
46 | */
47 |
48 | #define APP_NAME_KEY_PATH @"_infoDictionary.propertyList.CFBundleDisplayName"
49 | #define APP_SHORT_NAME_KEY_PATH @"localizedShortName"
50 |
51 | NSString *applicationName = [application valueForKeyPath:APP_NAME_KEY_PATH] ?:
52 | [application valueForKeyPath:APP_SHORT_NAME_KEY_PATH];
53 |
54 | /*
55 | * 应用的图片可以调用UIImage的私用方法:_applicationIconImageForBundleIdentifier:format:scale:
56 | * 传入BundleID,格式,缩放大小
57 | * 对应于LANAppHelper类中的+(id)iconForApplication:(id)application;方法:
58 | */
59 | UIImage *applicationImage = [UIImage _applicationIconImageForBundleIdentifier:[application bundleIdentifier]
60 | format:@""
61 | scale:@([UIScreen mainScreen].scale)];
62 | ```
63 | 应用列表界面展示:
64 |
65 | 
66 |
67 | #### 应用运行时详情
68 |
69 | 打开应用:
70 | ```objc
71 | //对应于LANAppHelper类中的+ (BOOL)openApplication:(id)application方法:
72 | [applicationWorkspace openApplicationWithBundleID:[application bundleIdentifier]];
73 | ```
74 |
75 | 卸载应用:
76 | ```objc
77 | //对应于LANAppHelper类中的+ (BOOL)removeApplication:(id)application方法:
78 | [applicationWorkspace uninstallApplication:[application bundleIdentifier] withOptions:nil];
79 | ```
80 |
81 | 获取info.plist文件:
82 | ```objc
83 | //info.plist文件实例化以后就是_infoDictionary属性,位置在[LSApplicationProxy superClass],也就是在LSBundleProxy类中
84 | #define APP_PROPERTY_LIST_KEY_PATH @"_infoDictionary.propertyList"
85 | ```
86 | 应用运行时详情界面展示:
87 |
88 | 
89 |
90 | * 右上角,从左往右第一个按钮用来打开应用;第二个按钮用来卸载这个应用
91 | * INFO按钮用来解析并显示出对应的LSApplicationProxy类
92 |
93 | #### 树形展示LSApplicationProxy类
94 | 通过算法,将LSApplicationProxy类,转换成了字典。
95 |
96 | 转换规则是:属性名为key,属性值为value,如果value是一个可解析的类(除了NSString,NSNumber...等等)或者是个数组或字典,则继续递归解析。
97 | 并且会找到superClass的属性并解析,superClass如果也符合解析原则,也会进入递归解析。
98 |
99 | 具体算法可以查看 LANAppHelper.m文件中的
100 | ```objc
101 | +(NSDictionary *)infoForApplication:(id)application;
102 | ```
103 | 
104 |
105 | ## 功能演示
106 |
107 | #### 已安装的应用列表
108 | 
109 |
110 | #### 应用详情页
111 | 
112 |
113 | #### 打开应用
114 | 
115 |
116 | #### 卸载应用
117 | 
118 |
119 | #### 应用属性列表
120 | 
121 |
122 | ## 参考及引用
123 | * [iOS-Runtime-Headers](https://github.com/nst/iOS-Runtime-Headers)
124 | * [Retriever](https://github.com/cyanzhong/Retriever)
125 | * [RuntimeInvoker](https://github.com/cyanzhong/RuntimeInvoker)
126 |
--------------------------------------------------------------------------------
/AppBrowser/Controller/LANAppListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by 蓝布鲁 on 2016/11/24.
3 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
4 | //
5 |
6 | #import "LANAppListViewController.h"
7 | #import "LANAppHelper.h"
8 | #import "LANAppListCell.h"
9 | #import "LANAppViewController.h"
10 | #import "NSArray+LAN.h"
11 |
12 | @interface LANAppListViewController()
13 |
14 | @property (nonatomic, retain)UITableView *tableView;
15 | @property (nonatomic, retain)UISearchController *searchController;
16 |
17 | @end
18 |
19 | @implementation LANAppListViewController {
20 | NSArray *_installedAppArray;
21 | NSMutableArray *_list;
22 | }
23 |
24 | -(void)viewWillAppear:(BOOL)animated {
25 | [super viewWillAppear:animated];
26 |
27 | [self refresh];
28 | }
29 |
30 | - (void)viewDidLoad {
31 | [super viewDidLoad];
32 | self.title = @"Installed App(0)";
33 |
34 | //setup view in controller
35 | [self setupView];
36 |
37 | //get data & refresh tableView
38 | [self refresh];
39 | }
40 |
41 | -(void)setupView{
42 |
43 | //init tableView
44 | self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
45 | self.tableView.delegate = self;
46 | self.tableView.dataSource = self;
47 | [self.view addSubview:self.tableView];
48 |
49 | //init searchController
50 | self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
51 | self.searchController.searchResultsUpdater = self;
52 | self.searchController.dimsBackgroundDuringPresentation = false;
53 | self.tableView.tableHeaderView = self.searchController.searchBar;
54 |
55 | //init refreshControl
56 | UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
57 | refreshControl.backgroundColor = [UIColor groupTableViewBackgroundColor];
58 | [refreshControl addTarget:self
59 | action:@selector(didRefreshControlValueChanged:)
60 | forControlEvents:UIControlEventValueChanged];
61 | [self.tableView addSubview:refreshControl];
62 |
63 |
64 | }
65 |
66 | -(void)refresh{
67 | _installedAppArray = [[LANAppHelper allInstalledApplications] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
68 | NSString *name1 = [LANAppHelper nameForApplication:obj1];
69 | NSString *name2 = [LANAppHelper nameForApplication:obj2];
70 | return [name1 compare:name2 options:NSCaseInsensitiveSearch];
71 | }];
72 | _list = [_installedAppArray mutableCopy];
73 |
74 | self.title = [NSString stringWithFormat:@"Installed App(%d)",_installedAppArray.count];
75 |
76 | [self.tableView reloadData];
77 | }
78 |
79 | - (void)didRefreshControlValueChanged:(UIRefreshControl *)sender {
80 | [self refresh];
81 | [sender performSelector:@selector(endRefreshing) withObject:nil afterDelay:1.5];
82 | }
83 |
84 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
85 | return _list.count;
86 | }
87 |
88 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
89 | LANAppListCell *cell = [tableView cellForRowAtIndexPath:indexPath];
90 | if (cell==nil){
91 | cell = [[LANAppListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"];
92 | cell.application = _list[indexPath.row];
93 | }
94 | return cell;
95 | }
96 |
97 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
98 | [tableView deselectRowAtIndexPath:indexPath animated:true];
99 | NSObject *application = _list[indexPath.row];
100 |
101 | LANAppViewController *appViewController = [[LANAppViewController alloc] init];
102 | appViewController.application = application;
103 | self.searchController.active = NO;
104 | self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Installed App" style:UIBarButtonItemStylePlain target:nil action:nil];
105 | [self.navigationController pushViewController:appViewController animated:true];
106 |
107 | // NSLog(@"class name:%@,properties:%@",NSStringFromClass([application class]),[NSArray getProperties:[application class]]);
108 | // NSLog(@"class name:%@,properties:%@",NSStringFromClass([application superclass]),[NSArray getProperties:[application superclass]]);
109 | // NSLog(@"class name:%@,properties:%@",NSStringFromClass([[application superclass] superclass]),[NSArray getProperties:[[application superclass] superclass]]);
110 | }
111 |
112 | - (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
113 | _list = [[NSMutableArray alloc] init];
114 | NSString *searchText = searchController.searchBar.text.lowercaseString;
115 | if(searchText.length==0){
116 | _list = [_installedAppArray mutableCopy];
117 | [self.tableView reloadData];
118 | } else{
119 | for (id application in _installedAppArray) {
120 | NSString *appName = [LANAppHelper nameForApplication:application];
121 | if([appName.lowercaseString containsString:searchText]){
122 | [_list addObject:application];
123 | }
124 | }
125 | [self.tableView reloadData];
126 | }
127 | }
128 |
129 |
130 | @end
131 |
--------------------------------------------------------------------------------
/AppBrowser/Controller/LANProListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LANProListViewController.m
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/29.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import "LANProListViewController.h"
10 | #import "LANProListCell.h"
11 | #import "LANPathDisplayView.h"
12 | #import "NSDictionary+LAN.h"
13 |
14 | @interface LANProListViewController ()
15 |
16 | @property(nonatomic, retain) UITableView *tableView;
17 |
18 |
19 | @end
20 |
21 | @implementation LANProListViewController{
22 | NSDictionary * _properties;
23 | NSArray *_allKeys;
24 | }
25 |
26 | - (id)initWithProperties:(id)properties {
27 | if(self=[super init]){
28 | if([properties isKindOfClass:[NSDictionary class]]){
29 | _allKeys = [properties allKeys];
30 | _properties = properties;
31 | } else if ([properties isKindOfClass:[NSArray class]]){
32 | _allKeys = properties;
33 | }
34 |
35 | //sort keys
36 | _allKeys = [_allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
37 | if([obj1 isKindOfClass:[NSString class]]){
38 |
39 | //top item is super class
40 | if([obj1 isEqualToString:SUPER_CLASS]){
41 | return NSOrderedAscending;
42 | } else if([obj2 isEqualToString:SUPER_CLASS]){
43 | return NSOrderedDescending;
44 | }
45 | return [obj1 compare:obj2 options:NSCaseInsensitiveSearch];
46 | } else if ([obj1 isKindOfClass:[NSNumber class]]){
47 | return [obj1 compare:obj2];
48 | }
49 | return NSOrderedSame;
50 |
51 | }];
52 | }
53 |
54 | [self initDisplayView];
55 | return self;
56 | }
57 |
58 |
59 | - (void)viewDidLoad {
60 | [super viewDidLoad];
61 | //init tableview
62 | self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,SCREEN_HEIGHT-20) style:UITableViewStylePlain];
63 | self.tableView.dataSource = self;
64 | self.tableView.delegate = self;
65 | [self.view addSubview:self.tableView];
66 |
67 | [self.pathDisplayView setupView];
68 | [self.view addSubview:self.pathDisplayView];
69 |
70 | //init menu
71 | // UIMenuItem *favoriteItem = [[UIMenuItem alloc] initWithTitle:@"Favorite" action:@selector(favoriteItem:)];
72 | // UIMenuController *menuController = [UIMenuController sharedMenuController];
73 | // [menuController setMenuItems:@[favoriteItem]];
74 | // [menuController update];
75 | }
76 |
77 | -(void)initDisplayView{
78 | //init pathDisplayView
79 | self.pathDisplayView = [[LANPathDisplayView alloc] initWithFrame:CGRectMake(0,SCREEN_HEIGHT-20,SCREEN_WIDTH,20)];
80 | }
81 |
82 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
83 | return _allKeys.count;
84 | }
85 |
86 | - (LANPropertiesType)infoTypeAtIndexPath:(NSIndexPath *)indexPath {
87 | id key = _allKeys[indexPath.row];
88 | id value = _properties[key];
89 | if ([value isKindOfClass:NSDictionary.class]) {
90 | return LANPropertiesTypeDictionary;
91 | } else if ([value isKindOfClass:NSArray.class]) {
92 | return LANPropertiesTypeArray;
93 | } else if ([key isKindOfClass:NSDictionary.class]) {
94 | return LANPropertiesTypeKeyDict;
95 | } else {
96 | return LANPropertiesTypeValue;
97 | }
98 | }
99 |
100 | - (void)fetchInfoWithIndexPath:(NSIndexPath *)indexPath completionHandler:(LANItemInfoFetchBlock)block {
101 | id key = _allKeys[indexPath.row];
102 | LANPropertiesType type = [self infoTypeAtIndexPath:indexPath];
103 | if (type == LANPropertiesTypeValue) {
104 | block(UITableViewCellAccessoryNone, [key description], [_properties[key] description] ?: @"");
105 | } else {
106 | NSString *title;
107 | if (type == LANPropertiesTypeKeyDict) {
108 | title = [NSString stringWithFormat:@"Item %d", (int)indexPath.row];
109 | } else {
110 | title = [key description];
111 | }
112 | block(UITableViewCellAccessoryDisclosureIndicator, title, [NSString stringWithFormat:@"%d items", _properties ? [_properties[key] count] : [key count]]);
113 | }
114 | }
115 |
116 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
117 | __block LANProListCell *cell = [tableView cellForRowAtIndexPath:indexPath];
118 | if(cell==nil){
119 | [self fetchInfoWithIndexPath:indexPath completionHandler:^(UITableViewCellAccessoryType accessoryType, NSString *title, NSString *subtitle) {
120 | if(accessoryType==UITableViewCellAccessoryDisclosureIndicator){
121 | cell = [[LANProListCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"CellID"];
122 | } else{
123 | cell = [[LANProListCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"CellID"];
124 | }
125 | cell.title = title;
126 | cell.subTitle = subtitle;
127 | cell.type = accessoryType;
128 |
129 | }];
130 |
131 | }
132 | return cell;
133 | }
134 |
135 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
136 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
137 | id key = _allKeys[indexPath.row];
138 | if ([self infoTypeAtIndexPath:indexPath] != LANPropertiesTypeValue) {
139 | id info = _properties ? _properties[key] : key;
140 | LANProListViewController *infoController = [[LANProListViewController alloc] initWithProperties:info];
141 | [self fetchInfoWithIndexPath:indexPath completionHandler:^(UITableViewCellAccessoryType accessoryType, NSString *title, NSString *subtitle) {
142 | infoController.title = title;
143 | [infoController.pathDisplayView setDisplayPath:self.pathDisplayView.displayPath addPath:title];
144 | }];
145 | [self.navigationController pushViewController:infoController animated:YES];
146 | }
147 | }
148 |
149 | - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
150 | return true;
151 | }
152 |
153 | - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
154 | return (action==@selector(copy:)||action==@selector(favoriteItem:));
155 | }
156 |
157 | - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
158 |
159 | }
160 |
161 |
162 |
163 |
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/AppBrowser/Controller/LANAppViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LANAppViewController.m
3 | // AppBrowser
4 | //
5 | // Created by 蓝布鲁 on 2016/11/29.
6 | // Copyright (c) 2016 lanvsblueCO. All rights reserved.
7 | //
8 |
9 | #import "LANAppViewController.h"
10 | #import "LANAppHelper.h"
11 | #import "LANProListViewController.h"
12 | #import "LANPathDisplayView.h"
13 | #import "LANProListCell.h"
14 |
15 | @interface LANAppViewController ()
16 |
17 | @property(nonatomic, retain) UIImageView *imageView;
18 | @property (nonatomic, retain) UITableView *tableView;
19 |
20 | @end
21 |
22 | @implementation LANAppViewController{
23 | NSDictionary *_infoDictionary;
24 | NSArray *_allKeys;
25 | }
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 | self.title = [LANAppHelper nameForApplication:self.application];
30 | self.view.backgroundColor = [UIColor whiteColor];
31 |
32 | [self setupView];
33 |
34 | //refresh
35 | [self refresh];
36 |
37 |
38 | }
39 |
40 |
41 |
42 | - (void)setupView {
43 |
44 | //setup navigation item
45 | [self setupNavigation];
46 |
47 | //setup header view
48 | [self setupHeaderView];
49 |
50 | //setup property tableView
51 | [self setupTableView];
52 |
53 | }
54 |
55 | -(void)setupNavigation{
56 | UIBarButtonItem *removeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
57 | target:self
58 | action:@selector(removeApp)];
59 |
60 | UIBarButtonItem *openItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
61 | target:self
62 | action:@selector(openApp)];
63 | self.navigationItem.rightBarButtonItems = @[removeItem, openItem];
64 | }
65 |
66 | -(void)setupHeaderView{
67 | //header view
68 | UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,64,SCREEN_WIDTH,150)];
69 | headerView.layer.borderWidth = 0.2;
70 | headerView.layer.borderColor = [UIColor lightGrayColor].CGColor;
71 |
72 | UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
73 | UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
74 | effectView.frame = CGRectMake(0,0,headerView.width,headerView.height);
75 | [headerView addSubview:effectView];
76 |
77 | [self.view addSubview:headerView];
78 |
79 | //image of application
80 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(15,15,headerView.height-30,headerView.height-30)];
81 | imageView.image = [LANAppHelper iconForApplication:self.application];
82 | [headerView addSubview:imageView];
83 |
84 | //app name
85 | UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(imageView.rightX+15,imageView.originY,0,0)];
86 | nameLabel.font = [UIFont systemFontOfSize:15];
87 | nameLabel.text = [LANAppHelper nameForApplication:self.application];
88 | [nameLabel sizeToFit];
89 | [headerView addSubview:nameLabel];
90 |
91 | //vendor name
92 | UILabel *vendorLabel = [[UILabel alloc] initWithFrame:CGRectMake(imageView.rightX+15,nameLabel.bottomY+5,0,0)];
93 | vendorLabel.text = [LANAppHelper vendorNameForApplication:self.application]?[LANAppHelper vendorNameForApplication:self.application]:@" ";
94 | vendorLabel.font = [UIFont systemFontOfSize:12];
95 | vendorLabel.textColor = [UIColor grayColor];
96 | vendorLabel.numberOfLines = 0;
97 | [vendorLabel sizeToFit];
98 | [headerView addSubview:vendorLabel];
99 |
100 | //bundle identifier
101 | UILabel *bundleLabel = [[UILabel alloc] initWithFrame:CGRectMake(imageView.rightX+15,vendorLabel.bottomY+5,0,0)];
102 | bundleLabel.text = [LANAppHelper bundleIDForApplication:self.application];
103 | bundleLabel.font = [UIFont systemFontOfSize:12];
104 | bundleLabel.textColor = [UIColor grayColor];
105 | [bundleLabel sizeToFit];
106 | [headerView addSubview:bundleLabel];
107 |
108 | //properties
109 | UIButton *propertiesButton = [UIButton buttonWithType:UIButtonTypeSystem];
110 | propertiesButton.frame = CGRectMake(headerView.rightX-60-15,imageView.bottomY-30,60,30);
111 | [propertiesButton setTitle:@"INFO" forState:UIControlStateNormal];
112 | [propertiesButton setTitleColor:[UIColor colorWithRed:0.08 green:0.49 blue:0.98 alpha:1.00] forState:UIControlStateNormal];
113 | propertiesButton.layer.masksToBounds = true;
114 | propertiesButton.layer.cornerRadius = 3;
115 | propertiesButton.layer.borderColor = [UIColor colorWithRed:0.08 green:0.49 blue:0.98 alpha:1.00].CGColor;
116 | propertiesButton.layer.borderWidth = 1;
117 | propertiesButton.layer.shadowOffset = CGSizeZero;
118 | [propertiesButton addTarget:self action:@selector(propertiesButtonTapped) forControlEvents:UIControlEventTouchUpInside];
119 | [headerView addSubview:propertiesButton];
120 | }
121 |
122 | -(void)setupTableView{
123 | self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,150+64,SCREEN_WIDTH,self.view.height-150-64)
124 | style:UITableViewStyleGrouped];
125 | self.tableView.delegate = self;
126 | self.tableView.dataSource = self;
127 | [self.view addSubview:self.tableView];
128 | }
129 |
130 | -(void)refresh{
131 | //get info.plist
132 | _infoDictionary = [self.application valueForKeyPath:APP_PROPERTY_LIST_KEY_PATH];
133 | _allKeys = [_infoDictionary.allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
134 | if([obj1 isKindOfClass:[NSString class]]){
135 | return [obj1 compare:obj2 options:NSCaseInsensitiveSearch];
136 | } else if ([obj1 isKindOfClass:[NSNumber class]]){
137 | return [obj1 compare:obj2];
138 | }
139 | return NSOrderedSame;
140 | }];
141 | }
142 |
143 | - (LANPropertiesType)infoTypeAtIndexPath:(NSIndexPath *)indexPath {
144 | id key = _allKeys[indexPath.row];
145 | id value = _infoDictionary[key];
146 | if ([value isKindOfClass:NSDictionary.class]) {
147 | return LANPropertiesTypeDictionary;
148 | } else if ([value isKindOfClass:NSArray.class]) {
149 | return LANPropertiesTypeArray;
150 | } else if ([key isKindOfClass:NSDictionary.class]) {
151 | return LANPropertiesTypeKeyDict;
152 | } else {
153 | return LANPropertiesTypeValue;
154 | }
155 | }
156 |
157 | - (void)fetchInfoWithIndexPath:(NSIndexPath *)indexPath completionHandler:(LANItemInfoFetchBlock)block {
158 | id key = _allKeys[indexPath.row];
159 | LANPropertiesType type = [self infoTypeAtIndexPath:indexPath];
160 | if (type == LANPropertiesTypeValue) {
161 | block(UITableViewCellAccessoryNone, [key description], [_infoDictionary[key] description] ?: @"");
162 | } else {
163 | NSString *title;
164 | if (type == LANPropertiesTypeKeyDict) {
165 | title = [NSString stringWithFormat:@"Item %d", (int)indexPath.row];
166 | } else {
167 | title = [key description];
168 | }
169 | block(UITableViewCellAccessoryDisclosureIndicator, title, [NSString stringWithFormat:@"%d items", _infoDictionary ? [_infoDictionary[key] count] : [key count]]);
170 | }
171 | }
172 |
173 | - (void)removeApp {
174 | //if it is simulator , can be uninstall
175 |
176 | #if TARGET_OS_SIMULATOR
177 | [LANAppHelper removeApplication:self.application];
178 | [self.navigationController popViewControllerAnimated:true];
179 | #elif TARGET_OS_IPHONE
180 |
181 |
182 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Uninstall failed"
183 | message:@"It only can be used on simulator"
184 | preferredStyle:UIAlertControllerStyleAlert];
185 |
186 | UIAlertAction *done = [UIAlertAction actionWithTitle:@"Done"
187 | style:UIAlertActionStyleDefault
188 | handler:^(UIAlertAction *action) {
189 |
190 | }];
191 | [alert addAction:done];
192 | #endif
193 |
194 | }
195 |
196 | - (void)openApp {
197 | [LANAppHelper openApplication:self.application];
198 | }
199 |
200 | -(void)propertiesButtonTapped{
201 | LANProListViewController *controller = [[LANProListViewController alloc]
202 | initWithProperties:[LANAppHelper infoForApplication:self.application]];
203 | controller.pathDisplayView.displayPath = @"LSApplicationProxy";
204 | controller.title = @"LSApplicationProxy";
205 | [self.navigationController pushViewController:controller animated:true];
206 | }
207 |
208 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
209 | return _infoDictionary.count;
210 | }
211 |
212 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
213 | return 1;
214 | }
215 |
216 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
217 | UIView *header = [[UIView alloc] init];
218 | UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(20,20,200,20)];
219 | headerLabel.text = @"info.plist";
220 | headerLabel.font = [UIFont systemFontOfSize:15];
221 | headerLabel.textColor = [UIColor grayColor];
222 | [header addSubview:headerLabel];
223 | return header;
224 | }
225 |
226 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
227 | return 50;
228 | }
229 |
230 |
231 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
232 | __block LANProListCell *cell = [tableView cellForRowAtIndexPath:indexPath];
233 | if(cell==nil){
234 | [self fetchInfoWithIndexPath:indexPath completionHandler:^(UITableViewCellAccessoryType accessoryType, NSString *title, NSString *subtitle) {
235 | if(accessoryType==UITableViewCellAccessoryDisclosureIndicator){
236 | cell = [[LANProListCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"CellID"];
237 | } else{
238 | cell = [[LANProListCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"CellID"];
239 | }
240 | cell.title = title;
241 | cell.subTitle = subtitle;
242 | cell.type = accessoryType;
243 |
244 | }];
245 |
246 | }
247 | return cell;
248 | }
249 |
250 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
251 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
252 | id key = _allKeys[indexPath.row];
253 | if ([self infoTypeAtIndexPath:indexPath] != LANPropertiesTypeValue) {
254 | id info = _infoDictionary;
255 | LANProListViewController *infoController = [[LANProListViewController alloc] initWithProperties:info];
256 | [self fetchInfoWithIndexPath:indexPath completionHandler:^(UITableViewCellAccessoryType accessoryType, NSString *title, NSString *subtitle) {
257 | infoController.title = title;
258 | [infoController.pathDisplayView setDisplayPath:@"_infoDictionary.propertyList" addPath:title];
259 | }];
260 | [self.navigationController pushViewController:infoController animated:YES];
261 | }
262 | }
263 |
264 |
265 | @end
266 |
--------------------------------------------------------------------------------
/AppBrowser/Common/RuntimeInvoker.m:
--------------------------------------------------------------------------------
1 | //
2 | // RuntimeInvoker.m
3 | // RuntimeInvoker
4 | //
5 | // Created by cyan on 16/5/27.
6 | // Copyright © 2016年 cyan. All rights reserved.
7 | //
8 |
9 | #import "RuntimeInvoker.h"
10 | #import
11 |
12 | #define _DEFINE_ARRAY(arg) \
13 | NSMutableArray *array = [NSMutableArray arrayWithObject:arg];\
14 | va_list args;\
15 | va_start(args, arg);\
16 | id next = nil;\
17 | while ((next = va_arg(args,id))) {\
18 | [array addObject:next];\
19 | }\
20 | va_end(args);\
21 |
22 | #pragma mark - NSMethodSignature Category
23 |
24 | // Objective-C type encoding: http://nshipster.com/type-encodings/
25 | typedef NS_ENUM(NSInteger, RIMethodArgumentType) {
26 | RIMethodArgumentTypeUnknown = 0,
27 | RIMethodArgumentTypeChar,
28 | RIMethodArgumentTypeInt,
29 | RIMethodArgumentTypeShort,
30 | RIMethodArgumentTypeLong,
31 | RIMethodArgumentTypeLongLong,
32 | RIMethodArgumentTypeUnsignedChar,
33 | RIMethodArgumentTypeUnsignedInt,
34 | RIMethodArgumentTypeUnsignedShort,
35 | RIMethodArgumentTypeUnsignedLong,
36 | RIMethodArgumentTypeUnsignedLongLong,
37 | RIMethodArgumentTypeFloat,
38 | RIMethodArgumentTypeDouble,
39 | RIMethodArgumentTypeBool,
40 | RIMethodArgumentTypeVoid,
41 | RIMethodArgumentTypeCharacterString,
42 | RIMethodArgumentTypeCGPoint,
43 | RIMethodArgumentTypeCGSize,
44 | RIMethodArgumentTypeCGRect,
45 | RIMethodArgumentTypeUIEdgeInsets,
46 | RIMethodArgumentTypeObject,
47 | RIMethodArgumentTypeClass
48 | };
49 |
50 | @implementation NSMethodSignature (RuntimeInvoker)
51 |
52 | /**
53 | * Get type of return value
54 | *
55 | * @return Return value type
56 | */
57 | - (RIMethodArgumentType)returnType {
58 | return [NSMethodSignature argumentTypeWithEncode:[self methodReturnType]];
59 | }
60 |
61 | /**
62 | * Type encoding for argument
63 | *
64 | * @param encode Encode for argument
65 | *
66 | * @return RIMethodArgumentType
67 | */
68 | + (RIMethodArgumentType)argumentTypeWithEncode:(const char *)encode {
69 |
70 | if (strcmp(encode, @encode(char)) == 0) {
71 | return RIMethodArgumentTypeChar;
72 | } else if (strcmp(encode, @encode(int)) == 0) {
73 | return RIMethodArgumentTypeInt;
74 | } else if (strcmp(encode, @encode(short)) == 0) {
75 | return RIMethodArgumentTypeShort;
76 | } else if (strcmp(encode, @encode(long)) == 0) {
77 | return RIMethodArgumentTypeLong;
78 | } else if (strcmp(encode, @encode(long long)) == 0) {
79 | return RIMethodArgumentTypeLongLong;
80 | } else if (strcmp(encode, @encode(unsigned char)) == 0) {
81 | return RIMethodArgumentTypeUnsignedChar;
82 | } else if (strcmp(encode, @encode(unsigned int)) == 0) {
83 | return RIMethodArgumentTypeUnsignedInt;
84 | } else if (strcmp(encode, @encode(unsigned short)) == 0) {
85 | return RIMethodArgumentTypeUnsignedShort;
86 | } else if (strcmp(encode, @encode(unsigned long)) == 0) {
87 | return RIMethodArgumentTypeUnsignedLong;
88 | } else if (strcmp(encode, @encode(unsigned long long)) == 0) {
89 | return RIMethodArgumentTypeUnsignedLongLong;
90 | } else if (strcmp(encode, @encode(float)) == 0) {
91 | return RIMethodArgumentTypeFloat;
92 | } else if (strcmp(encode, @encode(double)) == 0) {
93 | return RIMethodArgumentTypeDouble;
94 | } else if (strcmp(encode, @encode(BOOL)) == 0) {
95 | return RIMethodArgumentTypeBool;
96 | } else if (strcmp(encode, @encode(void)) == 0) {
97 | return RIMethodArgumentTypeVoid;
98 | } else if (strcmp(encode, @encode(char *)) == 0) {
99 | return RIMethodArgumentTypeCharacterString;
100 | } else if (strcmp(encode, @encode(id)) == 0) {
101 | return RIMethodArgumentTypeObject;
102 | } else if (strcmp(encode, @encode(Class)) == 0) {
103 | return RIMethodArgumentTypeClass;
104 | } else if (strcmp(encode, @encode(CGPoint)) == 0) {
105 | return RIMethodArgumentTypeCGPoint;
106 | } else if (strcmp(encode, @encode(CGSize)) == 0) {
107 | return RIMethodArgumentTypeCGSize;
108 | } else if (strcmp(encode, @encode(CGRect)) == 0) {
109 | return RIMethodArgumentTypeCGRect;
110 | } else if (strcmp(encode, @encode(UIEdgeInsets)) == 0) {
111 | return RIMethodArgumentTypeUIEdgeInsets;
112 | } else {
113 | return RIMethodArgumentTypeUnknown;
114 | }
115 | }
116 |
117 | /**
118 | * Get type of argument at index
119 | *
120 | * @param index Argument index
121 | *
122 | * @return Return value type
123 | */
124 | - (RIMethodArgumentType)argumentTypeAtIndex:(NSInteger)index {
125 | const char *encode = [self getArgumentTypeAtIndex:index];
126 | return [NSMethodSignature argumentTypeWithEncode:encode];
127 | }
128 |
129 | /**
130 | * Setup arguments for invocation
131 | *
132 | * @param arguments Arguments
133 | *
134 | * @return NSInvocation
135 | */
136 | - (NSInvocation *)invocationWithArguments:(NSArray *)arguments {
137 |
138 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:self];
139 |
140 | NSAssert(arguments == nil || [arguments isKindOfClass:[NSArray class]], @"# RuntimeInvoker # arguments is not an array");
141 |
142 | [arguments enumerateObjectsUsingBlock:^(id _Nonnull argument, NSUInteger idx, BOOL * _Nonnull stop) {
143 |
144 | NSInteger index = idx + 2; // start with 2
145 | RIMethodArgumentType type = [self argumentTypeAtIndex:index];
146 |
147 | switch (type) {
148 | case RIMethodArgumentTypeChar: {
149 | char value = [argument charValue];
150 | [invocation setArgument:&value atIndex:index];
151 | } break;
152 | case RIMethodArgumentTypeInt: {
153 | int value = [argument intValue];
154 | [invocation setArgument:&value atIndex:index];
155 | } break;
156 | case RIMethodArgumentTypeShort: {
157 | short value = [argument shortValue];
158 | [invocation setArgument:&value atIndex:index];
159 | } break;
160 | case RIMethodArgumentTypeLong: {
161 | long value = [argument longValue];
162 | [invocation setArgument:&value atIndex:index];
163 | } break;
164 | case RIMethodArgumentTypeLongLong: {
165 | long long value = [argument longLongValue];
166 | [invocation setArgument:&value atIndex:index];
167 | } break;
168 | case RIMethodArgumentTypeUnsignedChar: {
169 | unsigned char value = [argument unsignedCharValue];
170 | [invocation setArgument:&value atIndex:index];
171 | } break;
172 | case RIMethodArgumentTypeUnsignedInt: {
173 | unsigned int value = [argument unsignedIntValue];
174 | [invocation setArgument:&value atIndex:index];
175 | } break;
176 | case RIMethodArgumentTypeUnsignedShort: {
177 | unsigned short value = [argument unsignedShortValue];
178 | [invocation setArgument:&value atIndex:index];
179 | } break;
180 | case RIMethodArgumentTypeUnsignedLong: {
181 | unsigned long value = [argument unsignedLongValue];
182 | [invocation setArgument:&value atIndex:index];
183 | } break;
184 | case RIMethodArgumentTypeUnsignedLongLong: {
185 | unsigned long long value = [argument unsignedLongLongValue];
186 | [invocation setArgument:&value atIndex:index];
187 | } break;
188 | case RIMethodArgumentTypeFloat: {
189 | float value = [argument floatValue];
190 | [invocation setArgument:&value atIndex:index];
191 | } break;
192 | case RIMethodArgumentTypeDouble: {
193 | double value = [argument doubleValue];
194 | [invocation setArgument:&value atIndex:index];
195 | } break;
196 | case RIMethodArgumentTypeBool: {
197 | BOOL value = [argument boolValue];
198 | [invocation setArgument:&value atIndex:index];
199 | } break;
200 | case RIMethodArgumentTypeVoid: {
201 |
202 | } break;
203 | case RIMethodArgumentTypeCharacterString: {
204 | const char *value = [argument UTF8String];
205 | [invocation setArgument:&value atIndex:index];
206 | } break;
207 | case RIMethodArgumentTypeObject: {
208 | [invocation setArgument:&argument atIndex:index];
209 | } break;
210 | case RIMethodArgumentTypeClass: {
211 | Class value = [argument class];
212 | [invocation setArgument:&value atIndex:index];
213 | } break;
214 |
215 | default: break;
216 | }
217 | }];
218 |
219 | return invocation;
220 | }
221 |
222 | @end
223 |
224 | #pragma mark - NSInvocation Category
225 |
226 | @implementation NSInvocation (RuntimeInvoker)
227 |
228 | /**
229 | * Invoke a selector
230 | *
231 | * @param target Target
232 | * @param selector Selector
233 | * @param type Return value type
234 | *
235 | * @return Return value
236 | */
237 | - (id)invoke:(id)target selector:(SEL)selector returnType:(RIMethodArgumentType)type {
238 | self.target = target;
239 | self.selector = selector;
240 | [self invoke];
241 | return [self returnValueForType:type];
242 | }
243 |
244 | /**
245 | * Boxing returnType of NSMethodSignature
246 | *
247 | * @param signature Signature
248 | *
249 | * @return Boxed value
250 | */
251 | - (id)returnValueForType:(RIMethodArgumentType)type {
252 |
253 | __unsafe_unretained id returnValue;
254 |
255 | switch (type) {
256 | case RIMethodArgumentTypeChar: {
257 | char value;
258 | [self getReturnValue:&value];
259 | returnValue = @(value);
260 | } break;
261 | case RIMethodArgumentTypeInt: {
262 | int value;
263 | [self getReturnValue:&value];
264 | returnValue = @(value);
265 | } break;
266 | case RIMethodArgumentTypeShort: {
267 | short value;
268 | [self getReturnValue:&value];
269 | returnValue = @(value);
270 | } break;
271 | case RIMethodArgumentTypeLong: {
272 | long value;
273 | [self getReturnValue:&value];
274 | returnValue = @(value);
275 | } break;
276 | case RIMethodArgumentTypeLongLong: {
277 | long long value;
278 | [self getReturnValue:&value];
279 | returnValue = @(value);
280 | } break;
281 | case RIMethodArgumentTypeUnsignedChar: {
282 | unsigned char value;
283 | [self getReturnValue:&value];
284 | returnValue = @(value);
285 | } break;
286 | case RIMethodArgumentTypeUnsignedInt: {
287 | unsigned int value;
288 | [self getReturnValue:&value];
289 | returnValue = @(value);
290 | } break;
291 | case RIMethodArgumentTypeUnsignedShort: {
292 | unsigned short value;
293 | [self getReturnValue:&value];
294 | returnValue = @(value);
295 | } break;
296 | case RIMethodArgumentTypeUnsignedLong: {
297 | unsigned long value;
298 | [self getReturnValue:&value];
299 | returnValue = @(value);
300 | } break;
301 | case RIMethodArgumentTypeUnsignedLongLong: {
302 | unsigned long long value;
303 | [self getReturnValue:&value];
304 | returnValue = @(value);
305 | } break;
306 | case RIMethodArgumentTypeFloat: {
307 | float value;
308 | [self getReturnValue:&value];
309 | returnValue = @(value);
310 | } break;
311 | case RIMethodArgumentTypeDouble: {
312 | double value;
313 | [self getReturnValue:&value];
314 | returnValue = @(value);
315 | } break;
316 | case RIMethodArgumentTypeBool: {
317 | BOOL value;
318 | [self getReturnValue:&value];
319 | returnValue = @(value);
320 | } break;
321 | case RIMethodArgumentTypeCharacterString: {
322 | const char *value;
323 | [self getReturnValue:&value];
324 | returnValue = [NSString stringWithUTF8String:value];
325 | } break;
326 | case RIMethodArgumentTypeCGPoint: {
327 | CGPoint value;
328 | [self getReturnValue:&value];
329 | returnValue = [NSValue valueWithCGPoint:value];
330 | } break;
331 | case RIMethodArgumentTypeCGSize: {
332 | CGSize value;
333 | [self getReturnValue:&value];
334 | returnValue = [NSValue valueWithCGSize:value];
335 | } break;
336 | case RIMethodArgumentTypeCGRect: {
337 | CGRect value;
338 | [self getReturnValue:&value];
339 | returnValue = [NSValue valueWithCGRect:value];
340 | } break;
341 | case RIMethodArgumentTypeUIEdgeInsets: {
342 | UIEdgeInsets value;
343 | [self getReturnValue:&value];
344 | returnValue = [NSValue valueWithUIEdgeInsets:value];
345 | } break;
346 | case RIMethodArgumentTypeObject:
347 | case RIMethodArgumentTypeClass:
348 | [self getReturnValue:&returnValue];
349 | break;
350 | default: break;
351 | }
352 | return returnValue;
353 | }
354 |
355 | @end
356 |
357 | #pragma mark - NSObject Category
358 |
359 | @implementation NSObject (RuntimeInvoker)
360 |
361 | id _invoke(id target, NSString *selector, NSArray *arguments) {
362 | SEL sel = NSSelectorFromString(selector);
363 | NSMethodSignature *signature = [target methodSignatureForSelector:sel];
364 | if (signature) {
365 | NSInvocation *invocation = [signature invocationWithArguments:arguments];
366 | id returnValue = [invocation invoke:target selector:sel returnType:signature.returnType];
367 | return returnValue;
368 | } else {
369 | NSLog(@"# RuntimeInvoker # selector: \"%@\" NOT FOUND", selector);
370 | return nil;
371 | }
372 | }
373 |
374 | - (id)invoke:(NSString *)selector arguments:(NSArray *)arguments {
375 | return _invoke(self, selector, arguments);
376 | }
377 |
378 | - (id)invoke:(NSString *)selector {
379 | return [self invoke:selector arguments:nil];
380 | }
381 |
382 | - (id)invoke:(NSString *)selector args:(id)arg, ... {
383 | _DEFINE_ARRAY(arg);
384 | return [self invoke:selector arguments:array];
385 | }
386 |
387 | + (id)invoke:(NSString *)selector {
388 | return [self.class invoke:selector arguments:nil];
389 | }
390 |
391 | + (id)invoke:(NSString *)selector args:(id)arg, ... {
392 | _DEFINE_ARRAY(arg);
393 | return [self.class invoke:selector arguments:array];
394 | }
395 |
396 | + (id)invoke:(NSString *)selector arguments:(NSArray *)arguments {
397 | return _invoke(self.class, selector, arguments);
398 | }
399 |
400 | @end
401 |
402 | @implementation NSString (RuntimeInvoker)
403 |
404 | - (id)invokeClassMethod:(NSString *)selector {
405 | return [self invokeClassMethod:selector arguments:nil];
406 | }
407 |
408 | - (id)invokeClassMethod:(NSString *)selector args:(id)arg, ... {
409 | _DEFINE_ARRAY(arg);
410 | return [self invokeClassMethod:selector arguments:array];
411 | }
412 |
413 | - (id)invokeClassMethod:(NSString *)selector arguments:(NSArray *)arguments {
414 | return [NSClassFromString(self) invoke:selector arguments:arguments];
415 | }
416 |
417 | @end
418 |
--------------------------------------------------------------------------------
/AppBrowser.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1A199041E0466BA5F9BB1F11 /* LANAppHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A19967D98091DBB5C8E1D46 /* LANAppHelper.m */; };
11 | 1A1990D3CA98281F7798BAC2 /* UIView+LAN.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A19989C3C9A63560335D2F7 /* UIView+LAN.m */; };
12 | 1A19913A21A77F3698BA5F22 /* NSArray+LAN.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A199660E6CFB68AE2207409 /* NSArray+LAN.m */; };
13 | 1A19913DBC063139E455FB1B /* LANProListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A199577A796360041C4F1F3 /* LANProListCell.m */; };
14 | 1A1991AFE54A0FC9CD0473DD /* NSDictionary+LAN.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1997EB459C56D2C64D0018 /* NSDictionary+LAN.m */; };
15 | 1A19920A9D1DEA3ECAF17675 /* LANAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A19965D34B7914B70421EC7 /* LANAppViewController.m */; };
16 | 1A199231ED464FE2CBF0BB1E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A199F9CD9029FC50A3D78D1 /* AppDelegate.m */; };
17 | 1A1992BE7D796198EBC175C1 /* LANAppListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1994DDC19CA7384C38B140 /* LANAppListCell.m */; };
18 | 1A19937BC28F8488AE04D9DF /* LANAppListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A199ABBB88F0D9A2797316F /* LANAppListViewController.m */; };
19 | 1A1994D0A04E9C345A89F2F9 /* RuntimeInvoker.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1992DE59F4730B2B128E84 /* RuntimeInvoker.m */; };
20 | 1A1996B5FF33C7D3AF28939E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1A199CE6A084BA342C2CF69B /* Info.plist */; };
21 | 1A199771F6938A6F6D1FE478 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A199EF5E749068E073330A0 /* LaunchScreen.storyboard */; };
22 | 1A1997C74B30FDB729B998D3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1999B9E8A8D4DC813E38C8 /* main.m */; };
23 | 1A1997C9B7D6A71B93067E79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1992578298797C6C033A18 /* Assets.xcassets */; };
24 | 1A199B633E5859BFA2F9840F /* LANPathDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1991B514F189D87CFE5C47 /* LANPathDisplayView.m */; };
25 | 1A199D4C0656B11F435557BF /* LANProListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A199E76C44E5E0A79320D94 /* LANProListViewController.m */; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXFileReference section */
29 | 1A199070418BA7768EFF524C /* AppBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; };
30 | 1A1990F733EAD68BE39C7606 /* LANAppViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LANAppViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
31 | 1A1991B514F189D87CFE5C47 /* LANPathDisplayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = LANPathDisplayView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
32 | 1A1992578298797C6C033A18 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
33 | 1A1992DE59F4730B2B128E84 /* RuntimeInvoker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeInvoker.m; sourceTree = ""; };
34 | 1A19947893E0B5F6EE991C44 /* LANPathDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LANPathDisplayView.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
35 | 1A1994965A43007728F16861 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
36 | 1A1994DDC19CA7384C38B140 /* LANAppListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LANAppListCell.m; sourceTree = ""; };
37 | 1A199577A796360041C4F1F3 /* LANProListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = LANProListCell.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
38 | 1A19959F2A916B842D7E2CF7 /* LANProListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LANProListCell.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
39 | 1A19965D34B7914B70421EC7 /* LANAppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = LANAppViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
40 | 1A199660E6CFB68AE2207409 /* NSArray+LAN.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+LAN.m"; sourceTree = ""; };
41 | 1A19967D98091DBB5C8E1D46 /* LANAppHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LANAppHelper.m; sourceTree = ""; };
42 | 1A19972B4AFD6BBBAE33FA37 /* LANGlobalDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LANGlobalDefine.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
43 | 1A1997478E74D7F61A16DC70 /* LANAppHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LANAppHelper.h; sourceTree = ""; };
44 | 1A1997EB459C56D2C64D0018 /* NSDictionary+LAN.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+LAN.m"; sourceTree = ""; };
45 | 1A1998933E55A45AA0CAAF17 /* LANAppListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LANAppListViewController.h; sourceTree = ""; };
46 | 1A19989C3C9A63560335D2F7 /* UIView+LAN.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+LAN.m"; sourceTree = ""; };
47 | 1A1998AEA713F2260D109C6C /* NSDictionary+LAN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+LAN.h"; sourceTree = ""; };
48 | 1A1999B9E8A8D4DC813E38C8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
49 | 1A199ABBB88F0D9A2797316F /* LANAppListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LANAppListViewController.m; sourceTree = ""; };
50 | 1A199B075D8374A60D616BBA /* LANProListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LANProListViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
51 | 1A199B95CA3359E5E928B5A9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
52 | 1A199C1950487A700143D855 /* LANAppListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LANAppListCell.h; sourceTree = ""; };
53 | 1A199CE6A084BA342C2CF69B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; };
54 | 1A199D3A36FDA81D6E83E757 /* RuntimeInvoker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeInvoker.h; sourceTree = ""; };
55 | 1A199D735C4AC99AF7291BB3 /* NSArray+LAN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+LAN.h"; sourceTree = ""; };
56 | 1A199E76C44E5E0A79320D94 /* LANProListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = LANProListViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
57 | 1A199F8538322DC9F6BB3C74 /* UIView+LAN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+LAN.h"; sourceTree = ""; };
58 | 1A199F9CD9029FC50A3D78D1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
59 | 3F4BE5E31DE6E4A400A93B5A /* PrefixHeader.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = PrefixHeader.pch; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | 1A199E7B40982D21C790F4E0 /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | /* End PBXFrameworksBuildPhase section */
71 |
72 | /* Begin PBXGroup section */
73 | 1A1994AAC5272E8BD9F27C4F /* View */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 1A1994DDC19CA7384C38B140 /* LANAppListCell.m */,
77 | 1A199C1950487A700143D855 /* LANAppListCell.h */,
78 | 1A19959F2A916B842D7E2CF7 /* LANProListCell.h */,
79 | 1A199577A796360041C4F1F3 /* LANProListCell.m */,
80 | 1A19947893E0B5F6EE991C44 /* LANPathDisplayView.h */,
81 | 1A1991B514F189D87CFE5C47 /* LANPathDisplayView.m */,
82 | );
83 | path = View;
84 | sourceTree = "";
85 | };
86 | 1A1995E0721C4EE08AFF6EF1 /* Controller */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 1A1998933E55A45AA0CAAF17 /* LANAppListViewController.h */,
90 | 1A199ABBB88F0D9A2797316F /* LANAppListViewController.m */,
91 | 1A1990F733EAD68BE39C7606 /* LANAppViewController.h */,
92 | 1A19965D34B7914B70421EC7 /* LANAppViewController.m */,
93 | 1A199B075D8374A60D616BBA /* LANProListViewController.h */,
94 | 1A199E76C44E5E0A79320D94 /* LANProListViewController.m */,
95 | );
96 | path = Controller;
97 | sourceTree = "";
98 | };
99 | 1A1996DC38201052FBB6A32F /* Category */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 1A199F8538322DC9F6BB3C74 /* UIView+LAN.h */,
103 | 1A19989C3C9A63560335D2F7 /* UIView+LAN.m */,
104 | 1A199660E6CFB68AE2207409 /* NSArray+LAN.m */,
105 | 1A199D735C4AC99AF7291BB3 /* NSArray+LAN.h */,
106 | 1A1997EB459C56D2C64D0018 /* NSDictionary+LAN.m */,
107 | 1A1998AEA713F2260D109C6C /* NSDictionary+LAN.h */,
108 | );
109 | path = Category;
110 | sourceTree = "";
111 | };
112 | 1A1997F53AF87C2858BE40A7 /* Common */ = {
113 | isa = PBXGroup;
114 | children = (
115 | 1A1996DC38201052FBB6A32F /* Category */,
116 | 1A199D3A36FDA81D6E83E757 /* RuntimeInvoker.h */,
117 | 1A1992DE59F4730B2B128E84 /* RuntimeInvoker.m */,
118 | );
119 | path = Common;
120 | sourceTree = "";
121 | };
122 | 1A1999410672D29B8FEC961F /* Products */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 1A199070418BA7768EFF524C /* AppBrowser.app */,
126 | );
127 | name = Products;
128 | sourceTree = "";
129 | };
130 | 1A1999BB55A35AAF4BFA9264 /* AppBrowser */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 1A199CE6A084BA342C2CF69B /* Info.plist */,
134 | 1A1992578298797C6C033A18 /* Assets.xcassets */,
135 | 1A199EF5E749068E073330A0 /* LaunchScreen.storyboard */,
136 | 1A199FE804FA083FADEC3983 /* Supporting Files */,
137 | 1A199B95CA3359E5E928B5A9 /* AppDelegate.h */,
138 | 1A199F9CD9029FC50A3D78D1 /* AppDelegate.m */,
139 | 1A1995E0721C4EE08AFF6EF1 /* Controller */,
140 | 1A1997F53AF87C2858BE40A7 /* Common */,
141 | 1A199D78CC9E036892E450AA /* Model */,
142 | 1A1994AAC5272E8BD9F27C4F /* View */,
143 | );
144 | path = AppBrowser;
145 | sourceTree = "";
146 | };
147 | 1A199B0251663A8FA17404C3 = {
148 | isa = PBXGroup;
149 | children = (
150 | 3F4BE5E31DE6E4A400A93B5A /* PrefixHeader.pch */,
151 | 1A1999410672D29B8FEC961F /* Products */,
152 | 1A1999BB55A35AAF4BFA9264 /* AppBrowser */,
153 | 1A19972B4AFD6BBBAE33FA37 /* LANGlobalDefine.h */,
154 | );
155 | sourceTree = "";
156 | };
157 | 1A199D78CC9E036892E450AA /* Model */ = {
158 | isa = PBXGroup;
159 | children = (
160 | 1A19967D98091DBB5C8E1D46 /* LANAppHelper.m */,
161 | 1A1997478E74D7F61A16DC70 /* LANAppHelper.h */,
162 | );
163 | path = Model;
164 | sourceTree = "";
165 | };
166 | 1A199FE804FA083FADEC3983 /* Supporting Files */ = {
167 | isa = PBXGroup;
168 | children = (
169 | 1A1999B9E8A8D4DC813E38C8 /* main.m */,
170 | );
171 | name = "Supporting Files";
172 | sourceTree = "";
173 | };
174 | /* End PBXGroup section */
175 |
176 | /* Begin PBXNativeTarget section */
177 | 1A199ABA0306E42DA9CC2EFA /* AppBrowser */ = {
178 | isa = PBXNativeTarget;
179 | buildConfigurationList = 1A1998425D1B08BE3DC10E8B /* Build configuration list for PBXNativeTarget "AppBrowser" */;
180 | buildPhases = (
181 | 1A1991C4D5037AA720D67B81 /* Sources */,
182 | 1A199E7B40982D21C790F4E0 /* Frameworks */,
183 | 1A1996F3029634F03EE89CF2 /* Resources */,
184 | );
185 | buildRules = (
186 | );
187 | dependencies = (
188 | );
189 | name = AppBrowser;
190 | productName = ApplicationManager;
191 | productReference = 1A199070418BA7768EFF524C /* AppBrowser.app */;
192 | productType = "com.apple.product-type.application";
193 | };
194 | /* End PBXNativeTarget section */
195 |
196 | /* Begin PBXProject section */
197 | 1A199A8FE21D4DA332F0F482 /* Project object */ = {
198 | isa = PBXProject;
199 | attributes = {
200 | CLASSPREFIX = LAN;
201 | ORGANIZATIONNAME = lanvsblueCO.;
202 | };
203 | buildConfigurationList = 1A1999ECC1DE83EE7CC8A61F /* Build configuration list for PBXProject "AppBrowser" */;
204 | compatibilityVersion = "Xcode 8.0";
205 | developmentRegion = English;
206 | hasScannedForEncodings = 0;
207 | knownRegions = (
208 | en,
209 | );
210 | mainGroup = 1A199B0251663A8FA17404C3;
211 | productRefGroup = 1A1999410672D29B8FEC961F /* Products */;
212 | projectDirPath = "";
213 | projectRoot = "";
214 | targets = (
215 | 1A199ABA0306E42DA9CC2EFA /* AppBrowser */,
216 | );
217 | };
218 | /* End PBXProject section */
219 |
220 | /* Begin PBXResourcesBuildPhase section */
221 | 1A1996F3029634F03EE89CF2 /* Resources */ = {
222 | isa = PBXResourcesBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | 1A1996B5FF33C7D3AF28939E /* Info.plist in Resources */,
226 | 1A1997C9B7D6A71B93067E79 /* Assets.xcassets in Resources */,
227 | 1A199771F6938A6F6D1FE478 /* LaunchScreen.storyboard in Resources */,
228 | );
229 | runOnlyForDeploymentPostprocessing = 0;
230 | };
231 | /* End PBXResourcesBuildPhase section */
232 |
233 | /* Begin PBXSourcesBuildPhase section */
234 | 1A1991C4D5037AA720D67B81 /* Sources */ = {
235 | isa = PBXSourcesBuildPhase;
236 | buildActionMask = 2147483647;
237 | files = (
238 | 1A1997C74B30FDB729B998D3 /* main.m in Sources */,
239 | 1A199231ED464FE2CBF0BB1E /* AppDelegate.m in Sources */,
240 | 1A19937BC28F8488AE04D9DF /* LANAppListViewController.m in Sources */,
241 | 1A1990D3CA98281F7798BAC2 /* UIView+LAN.m in Sources */,
242 | 1A199041E0466BA5F9BB1F11 /* LANAppHelper.m in Sources */,
243 | 1A1994D0A04E9C345A89F2F9 /* RuntimeInvoker.m in Sources */,
244 | 1A1992BE7D796198EBC175C1 /* LANAppListCell.m in Sources */,
245 | 1A19920A9D1DEA3ECAF17675 /* LANAppViewController.m in Sources */,
246 | 1A19913A21A77F3698BA5F22 /* NSArray+LAN.m in Sources */,
247 | 1A1991AFE54A0FC9CD0473DD /* NSDictionary+LAN.m in Sources */,
248 | 1A199D4C0656B11F435557BF /* LANProListViewController.m in Sources */,
249 | 1A19913DBC063139E455FB1B /* LANProListCell.m in Sources */,
250 | 1A199B633E5859BFA2F9840F /* LANPathDisplayView.m in Sources */,
251 | );
252 | runOnlyForDeploymentPostprocessing = 0;
253 | };
254 | /* End PBXSourcesBuildPhase section */
255 |
256 | /* Begin PBXVariantGroup section */
257 | 1A199EF5E749068E073330A0 /* LaunchScreen.storyboard */ = {
258 | isa = PBXVariantGroup;
259 | children = (
260 | 1A1994965A43007728F16861 /* Base */,
261 | );
262 | name = LaunchScreen.storyboard;
263 | sourceTree = "";
264 | };
265 | /* End PBXVariantGroup section */
266 |
267 | /* Begin XCBuildConfiguration section */
268 | 1A19937A0CF58CBC2B2AB597 /* Debug */ = {
269 | isa = XCBuildConfiguration;
270 | buildSettings = {
271 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
272 | DEVELOPMENT_TEAM = MXJL78S842;
273 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
274 | GCC_PREFIX_HEADER = PrefixHeader.pch;
275 | INFOPLIST_FILE = AppBrowser/Info.plist;
276 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
277 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
278 | PRODUCT_BUNDLE_IDENTIFIER = com.lanvsblue.AppBrowser;
279 | PRODUCT_NAME = "$(TARGET_NAME)";
280 | TARGETED_DEVICE_FAMILY = 1;
281 | };
282 | name = Debug;
283 | };
284 | 1A199709F4C3D1D2449008A9 /* Release */ = {
285 | isa = XCBuildConfiguration;
286 | buildSettings = {
287 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
288 | DEVELOPMENT_TEAM = MXJL78S842;
289 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
290 | GCC_PREFIX_HEADER = PrefixHeader.pch;
291 | INFOPLIST_FILE = AppBrowser/Info.plist;
292 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
294 | PRODUCT_BUNDLE_IDENTIFIER = com.lanvsblue.AppBrowser;
295 | PRODUCT_NAME = "$(TARGET_NAME)";
296 | TARGETED_DEVICE_FAMILY = 1;
297 | };
298 | name = Release;
299 | };
300 | 1A1998BEFADADFF82EA8605C /* Debug */ = {
301 | isa = XCBuildConfiguration;
302 | buildSettings = {
303 | ALWAYS_SEARCH_USER_PATHS = NO;
304 | CLANG_ANALYZER_NONNULL = YES;
305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
306 | CLANG_CXX_LIBRARY = "libc++";
307 | CLANG_ENABLE_MODULES = YES;
308 | CLANG_ENABLE_OBJC_ARC = YES;
309 | CLANG_WARN_BOOL_CONVERSION = YES;
310 | CLANG_WARN_CONSTANT_CONVERSION = YES;
311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
312 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
313 | CLANG_WARN_EMPTY_BODY = YES;
314 | CLANG_WARN_ENUM_CONVERSION = YES;
315 | CLANG_WARN_INFINITE_RECURSION = YES;
316 | CLANG_WARN_INT_CONVERSION = YES;
317 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
318 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
319 | CLANG_WARN_UNREACHABLE_CODE = YES;
320 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
321 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
322 | COPY_PHASE_STRIP = NO;
323 | DEBUG_INFORMATION_FORMAT = dwarf;
324 | ENABLE_STRICT_OBJC_MSGSEND = YES;
325 | ENABLE_TESTABILITY = YES;
326 | GCC_C_LANGUAGE_STANDARD = gnu99;
327 | GCC_DYNAMIC_NO_PIC = NO;
328 | GCC_NO_COMMON_BLOCKS = YES;
329 | GCC_OPTIMIZATION_LEVEL = 0;
330 | GCC_PREPROCESSOR_DEFINITIONS = (
331 | "DEBUG=1",
332 | "$(inherited)",
333 | );
334 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
335 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
336 | GCC_WARN_UNDECLARED_SELECTOR = YES;
337 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
338 | GCC_WARN_UNUSED_FUNCTION = YES;
339 | GCC_WARN_UNUSED_VARIABLE = YES;
340 | IPHONEOS_DEPLOYMENT_TARGET = 10.1;
341 | MTL_ENABLE_DEBUG_INFO = YES;
342 | ONLY_ACTIVE_ARCH = YES;
343 | SDKROOT = iphoneos;
344 | TARGETED_DEVICE_FAMILY = "1,2";
345 | };
346 | name = Debug;
347 | };
348 | 1A199C3B61232BAACC376987 /* Release */ = {
349 | isa = XCBuildConfiguration;
350 | buildSettings = {
351 | ALWAYS_SEARCH_USER_PATHS = NO;
352 | CLANG_ANALYZER_NONNULL = YES;
353 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
354 | CLANG_CXX_LIBRARY = "libc++";
355 | CLANG_ENABLE_MODULES = YES;
356 | CLANG_ENABLE_OBJC_ARC = YES;
357 | CLANG_WARN_BOOL_CONVERSION = YES;
358 | CLANG_WARN_CONSTANT_CONVERSION = YES;
359 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
360 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
361 | CLANG_WARN_EMPTY_BODY = YES;
362 | CLANG_WARN_ENUM_CONVERSION = YES;
363 | CLANG_WARN_INFINITE_RECURSION = YES;
364 | CLANG_WARN_INT_CONVERSION = YES;
365 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
366 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
367 | CLANG_WARN_UNREACHABLE_CODE = YES;
368 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
369 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
370 | COPY_PHASE_STRIP = NO;
371 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
372 | ENABLE_NS_ASSERTIONS = NO;
373 | ENABLE_STRICT_OBJC_MSGSEND = YES;
374 | GCC_C_LANGUAGE_STANDARD = gnu99;
375 | GCC_NO_COMMON_BLOCKS = YES;
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 10.1;
383 | MTL_ENABLE_DEBUG_INFO = NO;
384 | SDKROOT = iphoneos;
385 | TARGETED_DEVICE_FAMILY = "1,2";
386 | VALIDATE_PRODUCT = YES;
387 | };
388 | name = Release;
389 | };
390 | /* End XCBuildConfiguration section */
391 |
392 | /* Begin XCConfigurationList section */
393 | 1A1998425D1B08BE3DC10E8B /* Build configuration list for PBXNativeTarget "AppBrowser" */ = {
394 | isa = XCConfigurationList;
395 | buildConfigurations = (
396 | 1A19937A0CF58CBC2B2AB597 /* Debug */,
397 | 1A199709F4C3D1D2449008A9 /* Release */,
398 | );
399 | defaultConfigurationIsVisible = 0;
400 | defaultConfigurationName = Release;
401 | };
402 | 1A1999ECC1DE83EE7CC8A61F /* Build configuration list for PBXProject "AppBrowser" */ = {
403 | isa = XCConfigurationList;
404 | buildConfigurations = (
405 | 1A1998BEFADADFF82EA8605C /* Debug */,
406 | 1A199C3B61232BAACC376987 /* Release */,
407 | );
408 | defaultConfigurationIsVisible = 0;
409 | defaultConfigurationName = Release;
410 | };
411 | /* End XCConfigurationList section */
412 | };
413 | rootObject = 1A199A8FE21D4DA332F0F482 /* Project object */;
414 | }
415 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
92 |
93 |
94 |
95 |
96 | true
97 | DEFINITION_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 | project
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 | 1479977957989
238 |
239 |
240 | 1479977957989
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
--------------------------------------------------------------------------------
/.idea/ApplicationManager.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
--------------------------------------------------------------------------------