PJBreedsViewController 組件開發總結

這是我另一個項目其中一個組件——品種選擇器,由於今天是週六,磨磨唧唧的造出了它。一眼看過去跟現有的通信錄樣式和操做方式基本一致,但你們也知道個人尿性,從最開始能用三方組件就用三方到如今能本身寫就本身寫。前端

由於先後端都是我本身一我的在作(創業狗就是慘 = =)因此在今天萌生了不少好玩的想法,剛把這個組建弄出來後以爲有必要跟你們分享一些好玩的事情。python

UI

先來看看 UI 樣式,git

最開始看到設計圖時,並不認爲這是一個有多少搞頭的東西,一直拖到今天。這是最終實現的成果,github

思考(一)

給到個人文案是個 .docx 格式的文檔,以下所示:shell

以前溝經過了一次,給我按照字母表順序排好就好了。最開始個人設計很是簡單,由於後端是用 python 寫的,直接從文件中讀出數據,split 一下丟入庫裏就行了,接口直接返回 idzh_name 便可,遂開幹。json

實踐(一)

# 初始化:儘可能經過 python shell 調用該方法
def init_dog_breed():
     f = open(settings.DOG_BREED_DIR, 'r')
     f_str = f.read()
     f_str_arr = f_str.split()
     for dog_name in f_str_arr:
         dog_breed(zh_name=dog_name).save()
     f.close()
複製代碼

從本地路徑讀取轉化成 .txt 文件(本人對直接讀 .docx 沒把握)後簡單的操做下入庫完事,這個方法並未暴露在接口中,並且只是第一次初始化數據時須要調用該方法。爲了方便後續產品迭代添加寵物品種信息,作了另一個簡單的方法:後端

# 新增狗品種
 def add_dog_breed(breed_name):
     dog_breed(zh_name=breed_name).save()
複製代碼

固然,也會有貓的,由於基本上差很少就不展開了。接口上這麼寫:併發

@decorator.request_methon('GET')
@decorator.request_check_args(['pet_type'])
def get_breeds(request):
    pet_type = request.GET.get('pet_type', '')
    functions = {
        'dog': dog(),
        'cat': cat()
    }

    if pet_type in functions.keys():
        json = {
            'breeds': functions[pet_type]
        }
        return utils.SuccessResponse(json, request)
    else:
        return utils.ErrorResponse('2333', '不支持該物種', request)

# 獲取全部狗品種
def dog():
    dog_breeds = dog_breed.objects.all()
    breeds = []
    for breed in dog_breeds:
        json = {
            'id': breed.pk,
            'zh_name': breed.zh_name,
        }
        breeds.append(json)
    return breeds
複製代碼

猜想後續產品可能還會引入其它寵物,畢竟現代人對寵物的需求是愈來愈奇葩了,沒有直接 if-else ,想用 switch ,但發現 python 中並無 switch 語句,查閱一番資料後,發現竟然能夠用 key-value 完成,雖然有些稍許麻煩,但第一次見還能夠把鍵值對玩成這樣!app

訪問對應接口後拿到的 JSON 格式數據以下:spa

{
    "msgCode": 666,
    "msg": {
        "breeds": [
            {
                "id": 89,
                "zh_name": "拉布拉多尋回犬"
            },
            {·
                "id": 90,
                "zh_name": "拉薩犬"
            },
            {
                "id": 91,
                "zh_name": "臘腸犬"
            },
            {
                "id": 92,
                "zh_name": "蘭波格犬"
            },
            {
                "id": 93,
                "zh_name": "獵水獺犬"
            },
        ]
    }
}
複製代碼

一切順利,看起來不錯,開始造客戶端 UI。客戶端上的實現一樣也是比較輕鬆,一個 tableView 的正常渲染流程便可。

數據渲染出來後,腦子已經在快速運轉,站起來活動活動,發現肚子有些餓,糾結了一會是食堂呢仍是餓了麼,最後由於貧窮而選擇了食堂。

思考(二)

午餐結束後,繼續幹活。開始作數據分組,思考並發現了問題所在,若是按照上午接口所返回的數據格式去作,那麼就須要端上作數據分組,把寵物品種按照 A~Z 的順序放到一個個的 section 中,這樣不但 iOS 須要作一遍,之後 Android 也要再作一遍,並且極其有可能仍是我寫,原本我就十分厭煩 Android,多花費一分鐘甚至一秒鐘都是極其不樂意的。

全部,從新思考接口返回的數據格式。能夠確保的是,數據都已經按照字母序排好了,咱們只須要對數據作分組,把第一個字的拼音的第一個字母相同的品種歸類爲一組,最後把全部組都放到一個大的列表中,序列化爲 JSON 返回便可完事。

遂又開幹!

實踐(二)

首先給品種模型新增了一個字段 group 用於標記所屬組別,中途考慮到了不想多增遷移文件,竟然腦殘的把以前生成的表給刪了,致使後邊生成遷移文件時對不上,最後又刪庫重來,真是畫蛇添足 = =。

從新把基本操做都弄完後,改造初始化數據的方法,用到了一箇中文轉拼音的庫 pinyin

# 初始化:儘可能經過 python shell 調用該方法
def init_dog_breed():
    f = open(settings.DOG_BREED_DIR, 'r')
    f_str = f.read()
    f_str_arr = f_str.split()
    # 刪除 array 中的第一個 'A'
    del f_str_arr[0]
    group = 'A'
    for dog_name in f_str_arr:
        first_cat_name = pinyin.get(dog_name, format='strip')[0:1].upper()
        if first_cat_name != group:
            group = first_cat_name
            # 切換 group 時跳過
            continue
        dog_breed(zh_name=dog_name, group=group).save()

    f.close()
複製代碼

這樣清洗過數據後,數據就十分清晰漂亮了:

+-----+-------+--------------------------------+
| id  | group | zh_name                        |
+-----+-------+--------------------------------+
|   1 | A     | 阿富汗獵犬                     |
|   2 | A     | 阿拉斯加雪橇犬                 |
|   3 | A     | 愛爾蘭梗                       |
|   4 | A     | 愛爾蘭紅白雪達犬               |
|   5 | A     | 愛爾蘭獵狼犬                   |
|   6 | A     | 愛爾蘭軟毛梗                   |
|   7 | A     | 愛爾蘭水獵犬                   |
|   8 | A     | 愛爾蘭峽谷梗                   |
+-----+-------+--------------------------------+
複製代碼

而接口,只須要進行拼接同類數據便可,

# 獲取全部狗品種
def dog():
    dog_breeds = dog_breed.objects.all()
    # 全部種類
    breeds = []
    # 當前種類名
    breed_groups = []
    group = "A"
    for breed in dog_breeds:
        if breed.group != group:
            breed_group = {
                'group': group,
                'breeds': breed_groups,
            }
            breeds.append(breed_group)
            group = breed.group
            breed_groups = []
        b_group = {
            'id': breed.pk,
            'zh_name': breed.zh_name,
        }
        breed_groups.append(b_group)
    return breeds
複製代碼

這樣,客戶端就可以拿到已經分組好的數據:

{
    "msgCode": 666,
    "msg": {
        "breeds": [
            {
                "group": "A",
                "breeds": [
                    {
                        "group": "T",
                        "breeds": [
                            {
                                "id": 137,
                                "zh_name": "田野小獵犬"
                            }
                        ]
                    },
                ]
            },
            {
                "group": "W",
                "breeds": [
                    {
                        "id": 138,
                        "zh_name": "玩具獵狐梗"
                    },
                    {
                        "id": 139,
                        "zh_name": "玩具曼徹斯特犬"
                    },
                ]
            }
        ]
    }
}
複製代碼

那客戶端接下來要作的事情稍微冗餘一些,但不復雜。首先先肯定 tableView.sections 的值,而後返回 sectionHeaderView,接着編寫 cellForRow 渲染 cell 的方法,依然是正常的 tableView 渲染流程。

剩下的就是一些其它 UI 和交互細節上的修修補補了。

思考和總結

此次作的這個組件先後端花費的時間比例大約在 7:3,主要時間都花在客戶端上,由於是第一次作相似於這種通信錄組件的開發,再加上是週六,讓本身的大腦和心情都放鬆了下來,沒有把時間抓得特別緊。

給我最大的收穫是最開始只考慮了後端處理數據的便利,而忘了前端處理數據的複雜,到後邊轉換了思惟,用前端的思惟對接口格式進行了修改,這一來一回讓本身更加明白了先後端配合是纔可以把一個東西作好,作到極致。

原文地址:PJ 的 iOS 開發之路

相關文章
相關標籤/搜索