Json視圖工具

Simulator Screen Shot - iPhone 6 Plus - 2019-08-11 at 09.28.51.png

demo地址

簡介

描述

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結構展示:

  1. 一鍵壓縮/展開 : 點擊??all 展開全部唉锌,點擊??…壓縮全部(需要注意的是隅肥,如果進行了壓縮,處在插入狀態(tài)的cell袄简,將被刪除)腥放。
  2. 添加了層級的背景色、縮進等绿语。默認最大展示6個層級秃症,如果超過6個層級則跳轉(zhuǎn)到新的頁面候址,進行展示。
  3. 對類型的區(qū)分:分為Dictionary Array String Number种柑。
  4. 支持展開與收起功能岗仑,如果有子節(jié)點,則單擊可以展開\收起聚请。
  5. value的展示:一行cell 的 value默認最多展示兩行荠雕。如果超過兩行則壓縮,并在底部展示驶赏。

搜索功能:

點擊放大鏡可以進入搜索頁面

在源碼中的位置:BaseJsonViewController->BaseJsonViewMainView->BaseJsonHeaderView->BaseJsonViewSearchView

  1. 搜索關鍵詞:輸入關鍵詞舞虱,并且會自動進行搜索。

  2. 精準搜索:如果選中精準搜索母市,搜索策略將從containsString 變成 isEqualToString矾兜。

注意:不管是否為精準搜索,都區(qū)分大小寫患久。

  1. 搜索Editing:如果選中【搜Editing】按鈕椅寺,則會搜索整個json中處在Editing狀態(tài)并符合關鍵詞搜索的數(shù)據(jù)。

注意:如果有處在插入狀態(tài)的數(shù)據(jù)蒋失,這時候會自動被刪除返帕。

  1. 上一個\下一個:當搜索完成后,點擊【上一個】篙挽、【下一個】自動跳轉(zhuǎn)到相應的行荆萤。

  2. 查看總覽:跳轉(zhuǎn)到一個搜索結果總覽控制器,顯示了搜索結果的路徑及`value

  3. 展示路徑/搜索數(shù)量:當沒有搜索條件(即:沒有搜索詞 铣卡、且搜Editing處于非選中狀態(tài))時链韭,顯示的是本控制器節(jié)點的路徑。否則顯示的是搜索結果數(shù)量煮落。

  4. 展示路徑/報錯信息:具有滾動敞峭、放大功能,最大放大倍數(shù)為1倍

  5. 當搜索條件報錯時蝉仇,展示的是紅色的報錯信息旋讹。

  6. 當有搜索內(nèi)容時,展示的是當前選中的搜索結果的節(jié)點路徑轿衔,

刪除功能

側滑cell沉迹,出現(xiàn)刪除功能(注意,因為側滑功能比較多害驹,所以在iphone5上面會導致刪除功能被遮擋)

復制功能

復制功能分為兩種:

  1. 如果側滑cell對應的節(jié)點為ArrayDictionary 則會只能復制 json
  2. 如果側滑cell 對應的節(jié)點為StringNumber則可以復制jsonvalue

編輯功能

側滑cell鞭呕,并點擊編輯按鈕開啟編輯功能(下面把被編輯的節(jié)點稱為Model,把Model的父節(jié)點稱為SuperModel)。

  1. SuperModel類型對Modelkey 的影響:

  2. SuperModel點為Array類型:Model的key必須為空裙秋。

  3. SuperModelDictionary類型:Model的key必須有值琅拌。

  4. 點擊取消按鈕:取消所有修改缨伊。

  5. 點擊完成按鈕:

  6. 選中Number按鈕,轉(zhuǎn)成Numbser類型进宝,輸入的值必須為數(shù)字刻坊,否則會報錯,并在報錯位置進行顯示党晋。

  7. 選中String按鈕谭胚,轉(zhuǎn)成String類型,會有個默認值未玻,默認值為""灾而。

  8. 選中json按鈕:

    1. 如果ModelArray類型,則會把jons解析出來作為Model的子節(jié)點數(shù)據(jù)
    2. 如果ModelDictionary類型扳剿,則會直接解析Json旁趟,如果json內(nèi)包含一個對象則該對象作Model的數(shù)據(jù),把對象的Key作為Modelkey庇绽。
  9. 選中Dictionary按鈕:

    1. 如果ModelDictionary類型锡搜,則不會產(chǎn)生任何效果,否則Model清空子節(jié)點數(shù)據(jù)瞧掺,并把Model轉(zhuǎn)成Dictionary類型耕餐。
  10. 選中Array按鈕:

    如果ModelArray類型勒魔,則不會產(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)硼莽。

  1. 如果ModelDictionary則可以【插入子節(jié)點】或【插入父節(jié)點】庶溶。
    1. 【插入子節(jié)點】:
      1. 如果Model關閉狀態(tài),則自動展開Model懂鸵,并在Model字節(jié)點的第一行插入一個新的節(jié)點SubModel偏螺,這時候,SubModel處于被編輯狀態(tài)匆光。
      2. 注意:此時插入的SubModel在父節(jié)點Model無序
    2. 【插入父節(jié)點】:在Model的后面插入為SuperSubModel插入SuperSubModel
  2. 如果ModelArray類型套像,則可以【插入子節(jié)點】或【插入父節(jié)點】。
    1. 【插入子節(jié)點】:
      1. 如果Model展開狀態(tài)终息,則自動壓縮Model夺巩,并在Model字節(jié)點的第一行插入一個新的節(jié)點SubModel贞让,這時候,SubModel處于被編輯狀態(tài)柳譬。
      2. 注意:此時插入的SubModel在父節(jié)點Model有序喳张。
    2. 【插入父節(jié)點】:在Model的后面插入為SuperSubModel插入SuperSubModel
  3. 如果ModelStringNumber類型,則可以【插入父節(jié)點】美澳。在Model的后面插入為SuperSubModel插入SuperSubModel

實現(xiàn)思路

  1. json的解析
    1. 為了避免造成不必要的開銷销部,對json解析的時機做了調(diào)整:
      1. 當節(jié)點A被打開時候,才會解析A的子節(jié)點數(shù)據(jù)制跟。
      2. 在解析節(jié)點A數(shù)據(jù)時舅桩,優(yōu)先獲取緩存的A子節(jié)點數(shù)據(jù)。
      3. 在對A進行編輯插入時雨膨,對A的的子節(jié)點數(shù)據(jù)進行更新擂涛。
  2. 對視圖的展示
    1. 對與無限層級縮放的視圖來說,我們有必要把數(shù)據(jù)展平聊记。
    2. 數(shù)據(jù)中創(chuàng)建一個用于標記層級的變量歼指。來做一個無限縮放層級的假象。

實現(xiàn)細節(jié)

對于節(jié)點Model的定義

Model就代表了一個節(jié)點甥雕,所以Model的結構至關重要踩身。

主要的屬性:
  1. level:所處層級,在進行初始化時,根據(jù)父節(jié)點的level進行賦值社露。
@property (nonatomic,assign) NSInteger level;
  1. count:字節(jié)點的個數(shù)
@property (nonatomic,assign) NSInteger count;
  1. isOpen是否為打開狀態(tài)
@property (nonatomic,assign) BOOL isOpen;
  1. originData:所有子節(jié)點的原始數(shù)據(jù)(可能為nil挟阻、Array、Dictionary峭弟、Number附鸽、String)
@property (nonatomic,strong) id originData;
  1. key:如果originData為字典,則key就是originData的key瞒瘸,否則為nil
@property (nonatomic,strong) NSString *key;
  1. data: originData 轉(zhuǎn)化成的數(shù)據(jù)(可能為:nil坷备、NSString、 NSArray<BaseJsonViewStepModel>情臭、BaseJsonViewStepModel)
@property (nonatomic,strong) id data;
  1. originData:父節(jié)點( 在父節(jié)點創(chuàng)建子節(jié)點時省撑,進行的賦值)
@property (nonatomic,weak) BaseJsonViewStepModel *superPoint;
  1. type:當前節(jié)點的類型
typedef enum : NSUInteger {
    BaseJsonViewStepModelType_Dictionary,
    BaseJsonViewStepModelType_Array,
    BaseJsonViewStepModelType_Number,
    BaseJsonViewStepModelType_String,
} BaseJsonViewStepModelType;

@property (nonatomic,assign) BaseJsonViewStepModelType type;
  1. 所處的狀態(tài)
typedef enum : NSUInteger {
    BaseJsonViewStepCellStatus_Normal,
    BaseJsonViewStepCellStatus_EditingSelf,
    BaseJsonViewStepCellStatus_InsertItem,
} BaseJsonViewStepCellStatus;

@property (nonatomic,assign) BaseJsonViewStepCellStatus status;
對model的創(chuàng)建
  1. + (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;
}   
  1. + (BaseJsonViewStepModel *(^)(id)) createWithID

類方法,返回一個block俯在,block 傳入的是id類型的數(shù)據(jù)竟秫。數(shù)據(jù)可以是

  1. BaseJsonViewStepModel: 直接返回這個data。不再創(chuàng)建
  2. 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的篩選策略

  1. isSearchEditing:如果為true。
    1. 如果keynil,則搜索全部處在編輯狀態(tài)的model馒稍。
    2. 如果key有值
      1. 如果isAccurateSearch為true:搜索所有keyvalue isEqualToString key的正在編輯狀態(tài)的model
      2. 如果isAccurateSearch為true:搜索所有keyvalue 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 謝謝~

demo地址

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肆捕,一起剝皮案震驚了整個濱河市刷晋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌慎陵,老刑警劉巖眼虱,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異席纽,居然都是意外死亡捏悬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門润梯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來过牙,“玉大人,你說我怎么就攤上這事纺铭】芏ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵舶赔,是天一觀的道長扫倡。 經(jīng)常有香客問我,道長竟纳,這世上最難降的妖魔是什么撵溃? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蚁袭,結果婚禮上征懈,老公的妹妹穿的比我還像新娘。我一直安慰自己揩悄,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布鬼悠。 她就那樣靜靜地躺著删性,像睡著了一般亏娜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蹬挺,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天维贺,我揣著相機與錄音,去河邊找鬼巴帮。 笑死溯泣,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的榕茧。 我是一名探鬼主播垃沦,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼用押!你這毒婦竟也來了肢簿?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜻拨,失蹤者是張志新(化名)和其女友劉穎池充,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缎讼,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡收夸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了血崭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咱圆。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖功氨,靈堂內(nèi)的尸體忽然破棺而出序苏,到底是詐尸還是另有隱情,我是刑警寧澤忱详,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布匈睁,位于F島的核電站航唆,受9級特大地震影響糯钙,放射性物質(zhì)發(fā)生泄漏再榄。R本人自食惡果不足惜困鸥,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望猬腰。 院中可真熱鬧,春花似錦厢拭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椭蹄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翼馆,已是汗流浹背拳球。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工魔吐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嗜桌。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓相满,卻偏偏與公主長得像立美,于是被迫代替她去往敵國和親建蹄。 傳聞我的和親對象是個殘疾皇子痛单,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,103評論 1 32
  • iOS網(wǎng)絡架構討論梳理整理中谆棱。蔫劣。脉幢。 其實如果沒有APIManager這一層是沒法使用delegate的,畢竟多個單...
    yhtang閱讀 5,193評論 1 23
  • 放假是期盼已久的幸福贾陷。 然并卵。 在家閑置髓废,猶如被束之高閣的書籍巷懈,感覺被珍藏了,卻沒有用途慌洪。 必須釋放些壓力顶燕,才能...
    華客魯俊閱讀 190評論 2 5
  • CSS的全稱是什么? CSS(Cascding Style Sheet)層疊樣式表,一種聲明示的計算機語言冈爹,用來為...
    饑人谷_LEO閱讀 312評論 0 1
  • 全文 2741 字 | 建議閱讀 6 分鐘 文 | mickjoust 國慶一過涌攻,很多人又開始盼望過年了,不是嗎犯助?...
    三風mickjoust閱讀 512評論 0 22