簡介
描述
BaseJsonViewController
是一個用OC
編寫的提供了搜索
人灼、插入
焦辅、編輯
客年、查看路徑
坊罢、復制json/value
等功能的Json
可視化編輯工具烤黍。
由于網(wǎng)絡數(shù)據(jù)請求下來后知市,
APP
端對json
原數(shù)據(jù)的展示并不明朗。 修改網(wǎng)絡數(shù)據(jù)只能通過Charles
等抓包工具實現(xiàn)速蕊,受到的限制太多嫂丙,所以誕生了在APP
端直接對json
進行查看、修改的Json
視圖工具:BaseJsonViewController
规哲。后續(xù)會對
BaseJsonViewController
進行持續(xù)的更新優(yōu)化跟啤,歡迎使用。
主要功能
json結構展示:
- 一鍵壓縮/展開 : 點擊
??all
展開全部唉锌,點擊??…
壓縮全部(需要注意的是隅肥,如果進行了壓縮,處在插入狀態(tài)的cell袄简,將被刪除)腥放。 - 添加了層級的背景色、縮進等绿语。默認最大展示6個層級秃症,如果超過6個層級則跳轉(zhuǎn)到新的頁面候址,進行展示。
- 對類型的區(qū)分:分為
Dictionary
Array
String
Number
种柑。 - 支持展開與收起功能岗仑,如果有子節(jié)點,則單擊可以展開\收起聚请。
- value的展示:一行cell 的 value默認最多展示兩行荠雕。如果超過兩行則壓縮,并在底部展示驶赏。
搜索功能:
點擊放大鏡可以進入搜索頁面
在源碼中的位置:BaseJsonViewController
->BaseJsonViewMainView
->BaseJsonHeaderView
->BaseJsonViewSearchView
搜索關鍵詞:輸入關鍵詞舞虱,并且會自動進行搜索。
精準搜索:如果選中精準搜索母市,搜索策略將從
containsString
變成isEqualToString
矾兜。注意:不管是否為精準搜索,都區(qū)分大小寫患久。
- 搜索Editing:如果選中【搜Editing】按鈕椅寺,則會搜索整個
json
中處在Editing
狀態(tài)并符合關鍵詞搜索的數(shù)據(jù)。注意:如果有處在
插入狀態(tài)
的數(shù)據(jù)蒋失,這時候會自動被刪除返帕。
上一個\下一個:當搜索完成后,點擊【上一個】篙挽、【下一個】自動跳轉(zhuǎn)到相應的行荆萤。
查看總覽:跳轉(zhuǎn)到一個搜索結果總覽控制器,顯示了搜索結果的路徑及`value
展示路徑/搜索數(shù)量:當沒有搜索條件(即:沒有
搜索詞
铣卡、且搜Editing
處于非選中狀態(tài))時链韭,顯示的是本控制器節(jié)點的路徑。否則顯示的是搜索結果數(shù)量煮落。展示路徑/報錯信息:具有滾動敞峭、放大功能,最大放大倍數(shù)為1倍
當搜索條件報錯時蝉仇,展示的是紅色的報錯信息旋讹。
當有搜索內(nèi)容時,展示的是當前選中的搜索結果的節(jié)點路徑轿衔,
刪除功能
側滑cell沉迹,出現(xiàn)刪除功能(注意,因為側滑功能比較多害驹,所以在iphone5
上面會導致刪除功能被遮擋)
復制功能
復制功能分為兩種:
- 如果側滑
cell
對應的節(jié)點為Array
或Dictionary
則會只能復制json
- 如果側滑
cell
對應的節(jié)點為String
或Number
則可以復制json
與value
編輯功能
側滑cell
鞭呕,并點擊編輯
按鈕開啟編輯功能(下面把被編輯的節(jié)點稱為Model
,把Model
的父節(jié)點稱為SuperModel
)。
SuperModel
類型對Model
的key
的影響:
SuperModel
點為Array
類型:Model的key
必須為空裙秋。
SuperModel
為Dictionary
類型:Model的key
必須有值琅拌。點擊取消按鈕:取消所有修改缨伊。
點擊完成按鈕:
選中
Number
按鈕,轉(zhuǎn)成Numbser
類型进宝,輸入的值必須為數(shù)字刻坊,否則會報錯,并在報錯位置進行顯示党晋。選中
String
按鈕谭胚,轉(zhuǎn)成String
類型,會有個默認值未玻,默認值為""
灾而。選中
json
按鈕:
- 如果
Model
為Array
類型,則會把jons
解析出來作為Model
的子節(jié)點數(shù)據(jù)- 如果
Model
為Dictionary
類型扳剿,則會直接解析Json
旁趟,如果json
內(nèi)包含一個對象則該對象作Model
的數(shù)據(jù),把對象的Key
作為Model
的key
庇绽。選中
Dictionary
按鈕:
- 如果
Model
為Dictionary
類型锡搜,則不會產(chǎn)生任何效果,否則Model
清空子節(jié)點數(shù)據(jù)瞧掺,并把Model
轉(zhuǎn)成Dictionary
類型耕餐。選中
Array
按鈕:如果
Model
為Array
類型勒魔,則不會產(chǎn)生任何效果榆浓,否則Model
清空子節(jié)點數(shù)據(jù),并把Model
轉(zhuǎn)成Array
類型宣吱。
插入功能
側滑cell
哼转,并點擊插入
按鈕開啟編輯功能
注意:如果在插入
的節(jié)點
沒有點擊完成的情況下明未,對節(jié)點
的父節(jié)點
執(zhí)行收起
操作,會自動刪除剛剛插入的節(jié)點
注意:如果插入節(jié)點
的父節(jié)
點為Dictionary
類型,插入的節(jié)點
在父節(jié)點
中的順序
不固定
把被編輯的節(jié)點稱為
Model
。把
Model
的父節(jié)點稱為SuperModel
释簿。把
Model
插入的子節(jié)點稱為SubModel
亚隅。把
SuperModel
插入的子節(jié)點稱為SuperSubModel
)硼莽。
- 如果
Model
為Dictionary
則可以【插入子節(jié)點】或【插入父節(jié)點】庶溶。
- 【插入子節(jié)點】:
- 如果
Model
為關閉
狀態(tài),則自動展開Model
懂鸵,并在Model
字節(jié)點的第一行插入一個新的節(jié)點SubModel
偏螺,這時候,SubModel
處于被編輯狀態(tài)
匆光。- 注意:此時插入的
SubModel
在父節(jié)點Model
無序- 【插入父節(jié)點】:在
Model
的后面插入為SuperSubModel
插入SuperSubModel
- 如果
Model
為Array
類型套像,則可以【插入子節(jié)點】或【插入父節(jié)點】。
- 【插入子節(jié)點】:
- 如果
Model
為展開
狀態(tài)终息,則自動壓縮Model
夺巩,并在Model
字節(jié)點的第一行插入一個新的節(jié)點SubModel
贞让,這時候,SubModel
處于被編輯狀態(tài)
柳譬。- 注意:此時插入的
SubModel
在父節(jié)點Model
有序喳张。- 【插入父節(jié)點】:在
Model
的后面插入為SuperSubModel
插入SuperSubModel
- 如果
Model
為String
或Number
類型,則可以【插入父節(jié)點】美澳。在Model
的后面插入為SuperSubModel
插入SuperSubModel
實現(xiàn)思路
- 對
json
的解析- 為了避免造成不必要的開銷销部,對
json
解析的時機做了調(diào)整:- 當節(jié)點
A
被打開時候,才會解析A
的子節(jié)點數(shù)據(jù)制跟。 - 在解析節(jié)點
A
數(shù)據(jù)時舅桩,優(yōu)先獲取緩存的A
子節(jié)點數(shù)據(jù)。 - 在對
A
進行編輯
或插入
時雨膨,對A
的的子節(jié)點數(shù)據(jù)進行更新擂涛。
- 當節(jié)點
- 為了避免造成不必要的開銷销部,對
- 對視圖的展示
- 對與無限層級縮放的視圖來說,我們有必要把數(shù)據(jù)展平聊记。
- 數(shù)據(jù)中創(chuàng)建一個用于標記層級的變量歼指。來做一個無限縮放層級的假象。
實現(xiàn)細節(jié)
對于節(jié)點Model的定義
Model
就代表了一個節(jié)點甥雕,所以Model
的結構至關重要踩身。
主要的屬性:
- level:所處層級,在進行初始化時,根據(jù)父節(jié)點的
level
進行賦值社露。
@property (nonatomic,assign) NSInteger level;
- count:字節(jié)點的個數(shù)
@property (nonatomic,assign) NSInteger count;
- isOpen是否為打開狀態(tài)
@property (nonatomic,assign) BOOL isOpen;
- originData:所有子節(jié)點的原始數(shù)據(jù)(可能為nil挟阻、Array、Dictionary峭弟、Number附鸽、String)
@property (nonatomic,strong) id originData;
- key:如果originData為字典,則key就是originData的key瞒瘸,否則為nil
@property (nonatomic,strong) NSString *key;
- data: originData 轉(zhuǎn)化成的數(shù)據(jù)(可能為:nil坷备、NSString、 NSArray<BaseJsonViewStepModel>情臭、BaseJsonViewStepModel)
@property (nonatomic,strong) id data;
- originData:父節(jié)點( 在父節(jié)點創(chuàng)建子節(jié)點時省撑,進行的賦值)
@property (nonatomic,weak) BaseJsonViewStepModel *superPoint;
- type:當前節(jié)點的類型
typedef enum : NSUInteger {
BaseJsonViewStepModelType_Dictionary,
BaseJsonViewStepModelType_Array,
BaseJsonViewStepModelType_Number,
BaseJsonViewStepModelType_String,
} BaseJsonViewStepModelType;
@property (nonatomic,assign) BaseJsonViewStepModelType type;
- 所處的狀態(tài)
typedef enum : NSUInteger {
BaseJsonViewStepCellStatus_Normal,
BaseJsonViewStepCellStatus_EditingSelf,
BaseJsonViewStepCellStatus_InsertItem,
} BaseJsonViewStepCellStatus;
@property (nonatomic,assign) BaseJsonViewStepCellStatus status;
對model的創(chuàng)建
+ (BaseJsonViewStepModel *) createStepModelWithOriginData: (id) data andKey: (NSString *)key
/**
創(chuàng)建 一個model
@param data 原始的子節(jié)點數(shù)據(jù)
@param key 創(chuàng)建出的model對應的key
@return model
*/
+ (BaseJsonViewStepModel *) createStepModelWithOriginData: (id) data andKey: (NSString *)key{
BaseJsonViewStepModel *model = [BaseJsonViewStepModel new];
model.originData = data;
model.key = key;
return model;
}
+ (BaseJsonViewStepModel *(^)(id)) createWithID
類方法,返回一個
block
俯在,block
傳入的是id類型的數(shù)據(jù)竟秫。數(shù)據(jù)可以是
BaseJsonViewStepModel
: 直接返回這個data。不再創(chuàng)建NSString
:先轉(zhuǎn)成字典跷乐,然后創(chuàng)建model
使用方法
BaseJsonViewStepModel.createWithId(data);
+ (BaseJsonViewStepModel *(^)(id)) createWithID {
return ^(id data) {
BaseJsonViewStepModel *model;
if ([data isKindOfClass:BaseJsonViewStepModel.class]) {
model = data;
}
if ([data isKindOfClass:NSString.class]) {
NSDictionary *dic = BaseJsonViewManager.convertToDicWithJson(data);
if (dic) {
model = BaseJsonViewManager.convertToStepModelWithDic(dic);
}
}
if (!model) {
model = [BaseJsonViewStepModel createStepModelWithOriginData:data andKey:@""];
}
return model;
};
}
搜索功能
搜索功能將會搜索出 所有的符合條件的model肥败,并返回一個數(shù)組
isSearchEditing
的篩選策略
- isSearchEditing:如果為true。
- 如果
key
為nil
,則搜索全部處在編輯狀態(tài)的model馒稍。- 如果
key
有值
- 如果
isAccurateSearch
為true:搜索所有key
或value
isEqualToString
key
的正在編輯狀態(tài)的model
- 如果
isAccurateSearch
為true:搜索所有key
或value
containsString
key
的正在編輯狀態(tài)的model
/**
搜索
@param key 搜索 關鍵字
@param isAccurateSearch 是否為精準搜索(如果選中精準搜索皿哨,搜索策略將從`containsString` 變成 `isEqualToString`。不管是否為精準搜索纽谒,都區(qū)分大小寫)
@param isSearchEditing 是否搜索正在編輯狀態(tài)的model
@return 搜索結果
*/
- (NSMutableArray <BaseJsonViewStepModel *>*) searchWithKey:(NSString *)key andIsAccurateSearch: (BOOL) isAccurateSearch andIsSearchEditing:(BOOL) isSearchEditing {
SBaseJsonViewStepSearchModelConfig config;
config.isSearchEditing = isSearchEditing;
config.isAccurateSearch = isAccurateSearch;
config.key = key;
config.model = self;
return BaseJsonViewStepSearchModel.getResultWithSearchConfig(config);
}
刪除功能
從父節(jié)點移除本節(jié)點
這個功能主要是找到originData中相同的元素往史,進行刪除。
- (void) removeFromeSuper {
if ([self.superPoint.originData isKindOfClass:NSArray.class]) {
NSArray *array = self.superPoint.originData;
NSMutableArray *arrayM = [[NSMutableArray alloc]initWithArray:array];
[arrayM removeObject:self.originData];
self.superPoint.originData = arrayM;
}
if ([self.superPoint.originData isKindOfClass:NSDictionary.class]) {
NSDictionary *dic = self.superPoint.originData;
NSMutableDictionary *dicM = [[NSMutableDictionary alloc]initWithDictionary:dic];
NSString *key = self.key;
if (key.length > 0) {
dicM[self.key] = nil;
}
self.superPoint.originData = dicM;
}
[self.superPoint reloadDataWitOriginDataProperty];
}
插入節(jié)點
根據(jù)原始數(shù)據(jù)插入節(jié)點佛舱,并返回BaseJsonViewStepErrorModel
椎例。
BaseJsonViewStepErrorModel
記錄了插入時的錯誤信息
/**
插入一個節(jié)點
@param key 節(jié)點的key
@param originData 節(jié)點的原始子節(jié)點y數(shù)據(jù)
@param index 插入的位置
@return 插入報錯的model
*/
- (BaseJsonViewStepErrorModel *) insertWithKey: (NSString *)key
andOriginData: (id) originData
andIndex:(NSInteger) index;
根據(jù)model插入節(jié)點,并返回BaseJsonViewStepErrorModel
请祖。
BaseJsonViewStepErrorModel
記錄了插入時的錯誤信息
/**
插入一個Model
@param model 準備插入的 節(jié)點 model
@param index 插入的位置
@return 錯誤信息
*/
- (BaseJsonViewStepErrorModel *) insertWithModel: (BaseJsonViewStepModel *) model
andIndex:(NSInteger) index;
最后
彩蛋:點擊title
會復制當前Controller展示的json數(shù)據(jù)呦~
工具剛剛成型订歪,很多需要修改的地方,希望大家勇于提bug 謝謝~