Как организовать данные при заполнении UICollectionView с изображениями, используя Firebase - PullRequest
0 голосов
/ 25 октября 2018

Я новичок в Swift, и в целом пишу код и работаю над проектом, в котором я хотел бы создать UICollectionView, заполненный изображениями из Firebase.

Каждый раздел UICollectionView будеткатегория, и каждая категория будет содержать изображения, связанные с этой категорией.Каждый UICollectionView принадлежит родителю, и мне нужно отслеживать, у какого родителя есть какие категории и какие изображения находятся в каждой категории.

Для отслеживания родителей, категорий и изображений я настроилБаза данных Firebase следующим образом (родительский элемент-чаша, названия фруктов в качестве категорий и ключи - это ссылки на данные изображений, хранящиеся в других местах базы данных):

"bowl" : {
        "apple" : {
            "-LOM1R4EH9nszjJp0Va5" : true,
            "-LOM1aRZT2XCE-6fvLBK" : true,
            "-LOM1hSTmRY6wGrWMvIo" : true,
            "-LOM1xnvKE6lc7fizomh" : true
        },
        "banana" : {
            "-LOLmQWLXXyiCUwDBwID" : true
        },
        "pear" : {
            "-LOLHakW-EtqevCeHfzl" : true,
            "-LOM2DBGGuX5VQLmBz46" : true
        },
        "orange" : {
            "-LOM26_pm6lbJ1D6hVPB" : true
        }
    }

Раздел данных изображениябаза данных выглядит следующим образом:

    "image" : {
        "fruit" : {
            "-LOLHakW-EtqevCeHfzl" : {
                "description" : "round orange",
                "imageURL" : "https://firebasestorage.googleapis.com/1/image1"
            },
            "-LOLmQWLXXyiCUwDBwID" : {
                "description" : "big banana",
                "imageURL" : "https://firebasestorage.googleapis.com/1/image2"
            },
            "-LOM1R4EH9nszjJp0Va5" : {
                "description" : "small apple",
                "imageURL" : "https://firebasestorage.googleapis.com/1/image3"
            }
        }
    }

Подход, который я пытался использовать, состоит в том, чтобы создать словарь с ключами изображения в нем, а затем перебрать ключи изображения, чтобы получить данные изображения, связанные с каждым ключом (например, imageURL), а затем используйте imageURL для загрузки изображений и заполнения UICollectionView.

Я создал структуру, как показано ниже, для преобразования данных изображения:

struct FruitPicture {
        let imageURL: String
        let description: String
        init(imageURL: String, description: String) {
            self.imageURL = imageURL
            self.description = description
        }
        init?(snapshot: DataSnapshot) {
            guard
                let value = snapshot.value as? [String: AnyObject],
                let imageURL = value["imageURL"] as? String,
                let description = value["description"] as? String else {
                    return nil
            }
            self.imageURL = imageURL
            self.description = description
        }
        func toAnyObject() -> Any {
            return [
                "imageURL": imageURL,
                "description": description
            ]
        }
    }

Я смог собрать imageURL и заполнить UICollectionView, но он не включает подробности о категории, и поэтомуar задействовал множество манипуляций с данными с помощью снимков, словарей, массивов, массивов словарей и т. д. из одной конфигурации в другую и обратно, и теперь я застрял и запутался.

Я начал смотреть на использование нескольких структур и вложение одного в другое, вот так, но я запутался во всем и часами трачу никуда:

struct Picture {
    var url: URL
    var image: UIImage?
}

struct PictureCategory {
    var name: String
    var pictures: [Picture]
}

Я надеялся на какой-нибудь совет,или дорожная карта, или детали того, как вы подходите к этому, или некоторый пример кода, или что-нибудь, чтобы указать мне правильное направление.Спасибо.

Редактировать, чтобы добавить больше информации

Спасибо, Iraniya, ваш ответ был очень полезным и помог мне рассмотреть вещи по-другому, я действительно ценю это.

Следуя вашим советам, я написал следующее, в котором боулинг создает снимок метаданных изображения (например, фрукт и ключи, связанные с этим фруктом), а затем использует эти ключи для создания снимка данных изображения.(например, ключ, imageURL, описание).Затем я преобразую оба снимка в словари и возвращаю словари методу, который вызвал его:

// GET DATA
static func getPicData(forKey bowlKey: String, completion: @escaping ([String : [Any]], [String : [FruitPicture]]) -> Void) {

    var imageMetaDict: [String : [Any]] = [:]
    var imageDataDict: [String : [FruitPicture]] = [:]

    // DEFINE DATABASE TARGET
    let ref = Database.database().reference().child("meta").child("bowl").child(bowlKey).child("fruit")

    // GET DATA INTO SNAPSHOT AND TRANSFORM INTO DICTIONARY
    ref.observeSingleEvent(of: .value, with: { (snapshot) in
        guard let dict = snapshot.value as? [String:[String:Any]] else {
            return completion([:],[:])
        }

        // DEFINE DISPATCH GROUP
        let dispatchGroup = DispatchGroup()

        // ITERATAE THROUGH DICTIONARY
        for (categoryObject, fruitData) in dict {

            // CREATE ARRAY TO STORE ITEMS
            var itemArray = [String]()

            // ITERATE THROUGH ITEMS IN FRUIT DATA
            for item in fruitData {

                // APPEND ITEM.KEY TO ITEM ARRAY
                itemArray.append(item.key)

                // ENTER DISPATCH GROUP
                dispatchGroup.enter()

                // USE ITEM.KEY TO GATHER IMAGE DATA
                Service.viewPicData(forKey: item.key) { (fruitItem) in
                        if let fruitItem = fruitItem {
                            imageDataDict[item.key] = [fruitItem]
                        }
                    // EXIT DISPATCH GROUP
                        dispatchGroup.leave()
                    }
            }

            // STORE ARRAY IN DICTIONARY UNDER FRUIT CATEGORY KEY
            imageMetaDict[categoryObject] = itemArray

        }

        // RETURN COMPLETION
        dispatchGroup.notify(queue: .main, execute: {
            completion(imageMetaDict, imageDataDict)
        })
    })
}

Каждый словарь выглядит примерно так:

imageMetaDict

[
"apple": ["-LOM1R4EH9nszjJp0Va5", "-LOM1xnvKE6lc7fizomh", "-LOM1hSTmRY6wGrWMvIo", "-LOM1aRZT2XCE-6fvLBK"],
"pear": ["-LOLHakW-EtqevCeHfzl", "-LOM2DBGGuX5VQLmBz46"], 
"banana": ["-LOLmQWLXXyiCUwDBwID"], 
"orange": ["-LOM26_pm6lbJ1D6hVPB"]
]

imageDataDict

 [
 "-LOM26_pm6lbJ1D6hVPB": [myApp.FruitPicture(imageURL: "https://firebasestorage.googleapis.com/1/image1", description: "pear 1")],
 "-LOM2DBGGuX5VQLmBz46": [myApp.FruitPicture(imageURL: "https://firebasestorage.googleapis.com/1/image2", description: "banana 1")],
 "-LOLmQWLXXyiCUwDBwID": [myApp.FruitPicture(imageURL: "https://firebasestorage.googleapis.com/1/image3", description: "apple 1")]
 ]

Это на правильном пути с тем, что вы предлагаете?

Из того, что я понимаю, следующие шаги:

  1. Создание массива фруктовых ключей, отсортированных по алфавиту
  2. Используйте fruit.keys для получения image.keys из 'imageMetaDict'
  3. Используйте эти image.keysдля поиска данных изображения (imageURL и т. д.) в 'imageDataDict'
  4. Преобразуйте все эти данные в новый FruitDict, который содержит fruitCategory -> [fruitObject]

Это похоже?на что вы предлагали?Я рад услышать любые ваши советы, код или предложения, которые вы мне до сих пор очень помогли!

1 Ответ

0 голосов
/ 25 октября 2018

Для хранения изображений Создайте хеш-карту imageDict (словарь) с ключом, который вы получаете от ключа firebase в изображении - >> fruits, например: "-LOLHakW-EtqevCeHfzl" со значением, которое вы получаете, или уже созданной структурой, теперь, когдазаполнение фруктов -> яблоко получает ключ из вашего массива чаши или dict, а затем использует этот же ключ, чтобы получить изображение из imagesDict dict (hashmap, который вы только что создали ранее

сейчас, пока храните данные в базе данных, убедитесь, что каждое изображение имеетуникальные ключи и сохраните этот же ключ в своей чаше -> apple-> image таким образом, чтобы им было быстро и легко управлять, поскольку данные изображения и данные о фруктах отображаются с помощью ключа, который вы получаете при сохранении нового изображения :-), если вам нравитсяРешение, которое я могу объяснить более подробно :-) # HappyCoding

Пример

узел firebase

"bowl" : {
        "apple" : {
            "-LOLHakW-EtqevCeHfzl" : true,
            "--LOLmQWLXXyiCUwDBwID" : false,
        }
    }


"image" : {
        "fruit" : {
            "-LOLHakW-EtqevCeHfzl" : {
                "description" : "round orange",
                "imageURL" : "https://firebasestorage.googleapis.com/1/image1"
            },
            "-LOLmQWLXXyiCUwDBwID" : {
                "description" : "big banana",
                "imageURL" : "https://firebasestorage.googleapis.com/1/image2"
            }
        }
    }

ImageDict

"-LOLHakW-EtqevCeHfzl":{
                        "description" : "round orange",
                        "imageURL" : "https://firebasestorage.googleapis.com/1/image1"
                       },
 "-LOLmQWLXXyiCUwDBwID" : {
                        "description" : "big banana",
                        "imageURL" : "https://firebasestorage.googleapis.com/1/image2"
                    }

или

{"-LOLHakW-EtqevCeHfzl":imageStruct1,
"-LOLmQWLXXyiCUwDBwID" :imageStruct2}

теперь для отображения изображения при заполнении яблока

var keys = boul["apple"].allKeys;
if(boul["apple"][keys[0]]){ //value is true show image 
  var imageUrl = imageDict[keys[0]["imageURL"]; //if using dict
  //or
  var image = imageDict[key[0]].imageURL //if using struct

}

Теперь для хранения родительских элементов, категорий и деталей изображения создайте Dict с именем fruitsDict или что-то еще с помощью dict в стороне от другого, делающего ключ в качестве фруктового имени, например: «яблоко»: {яблоки Детали, такие как цена изображения и т. д.}, но если вы заинтересованы только в хранении изображений, просто создайте список изображений, которые имеют истинное значение, например: «яблоко»: [ключ1, key2 ...];(ключи, которые вы получаете от imageDict.

Теперь на основе ваших требований, таких как

  1. Показать все категории !!, затем создайте все категории из fruitDict, используйте их в качестве источника данных и используйте imageDict и fruitsDict для деталей
  2. Показать только определенную категорию, например, основанную на сезонных фруктах, затем составить список этих фруктов и показать те, которые основаны на imageDict и fruiteDict

    HappyCoding: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...