Простые вопросы новичка в swift (с опытом теоритическим)


#1

Добрый день, сообщество.
Смотрел, смотрел курсы и понял, всё интересно и классно, но хочу попробовать своё приложение сделать. Упрощать и писать калькулятор не хочу, лучше посложней, чтобы захватить максимум востребуемого и получить максимум своего опыта (без курсов и примеров с данного портала никуда, за это отдельное спасибо!!!).

Вернусь к тебе моего обращения.
в первом приложении будет задействована

  1. Будет использоваться база данных.
  2. Авторизация через социальные сети, почтовые аккаунты (в общем, через oauth 2)
  3. Камера
  4. Ну и TableView =)

По сути у меня вопросы и простба в помощи (подсказки) по первым двум пунктам, дабы мне не тратить время и не изобретать велосипед.

  1. Пункт первый
    Облачные БД платные, каждый отдельный сервис стоит дополнительных денег и платить лишнее, или наоборот что-то не докупить и не понимать почему не работает не хочется, поэтому к вам вопрос:
    какие сервисы мне нужно заказывать (желательно как они называется, ибо я реально новичок в этом).
    Как я вижу - нужна сама БД и API (ибо напрямую к БД обращатся…говорят нельзя). Так ли это?
    Склоняюсь больше к MS Azure, Amazone или Google.

  2. Пункт второй
    Авторизация по протокому oauth2… сведения (ключи, почта, имя) тоже же будут писаться в БД? Тут что спросить не знаю, но наверное пока и нечего, кроме как каким сервисом воспользоваться для этого…

Понимаю, что возможно вам ответить будет трудно мне, так как не сильно и понятно о чем речь, но как бы есть вопросы и кратно попрошу вас ответить (без воды и лишних вопросов).
О том что вы напишите поищу информацию, разберусь с информацией и тогда конкретно смогу задать вопрос.
Спасибо Вам больше, с наступающим!!!

PS Перекроет ли мои потребности, предположим parse?


#2

Parse хватит за глаза, можете еще посмотреть в сторону firebase. Azure не умеет нормально отправлять уведомления (как в скайпе например, просто не приходят). AWS наверно будет слишком сложен для новичка.

В БД хранятся токены.


#3

Спасибо за ответ!
Только по какой-то причине никак не получается установить.
Ставил на Ubuntu 14.04 server и на 16.*
В браузере не открывается по порту 1337 ничего.


#4

Покажите ваш index.js


#5

Спасибо за желание помочь.
Методом проб и ошибок нашел в тем проблема.
Пока настраивал в локальной сети у меня было прописано везде 127.0.0.1 (loclhost), но как только исправил на адрес локальной сети (192.168.88.) - заработало.
Дальше столкнулся с проблемой, что не работает из вне (порты пробросил).
После этого исправил 192.168.88.
на внешний адрес в конфигах - всё взлетело.

Но позже нашел готовую сборку parse server - bitnami - на голую убунту развернул с помощью их установочного скрипта. Работает. Теперь буду разбираться как с этим работать.


#6

Из урока по тэйбл вью ловлю ошибку, но никак не пойму где что исправить.
Помогите плиз, заменяя код из “готово” не помогает найти ошибку…
Error “Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)”

fatal error: unexpectedly found nil while unwrapping an Optional value

Про ошибку читал, знаю из-за чего появляется, но понять сейчас не могу что не так…

https://yadi.sk/d/_sFfNlWa38CoNi


#7

print(“привет (restaurant?.location)”)
но учтите что переменная restaurant у вас пустая - и дальше код которие ее использует не работает. Как ето исправить ? - ( так на глаз ) кидайте данние с предидущего контролера в етот - через prepare тогда хоть строчка print - будет в консоль виводить - “привет Уфа”


#8

Она не должна быть пустая. Она заполняется в файле: EateriesTableViewController.swift
var restaurants: [Restaurant] = [
Restaurant(name: “Ogonёk Grill&Bar”, type: “ресторан”, location: “Уфа”, image: “ogonek.jpg”, isVisited: false),

в уроке точно также и там УФА выводится. Код один и тот же… поэтому и прошу ткнуть носом меня в кусок кода где у меня записано не как в уроке…
ссылка на проект из урока:
https://yadi.sk/d/862XSwJk38FF4h


#9

ошибка в контролере с картой , как я понимаю
Ви ж не пишете даже что делаете или как проверяете что ошибка вилетает … может еще где-то есть , но я тут нашел


#10

То что вы показали на скриншоте - об этом и пишу и с этого и начал.
Restaurant.location не имеет значение, хотя должно его иметь.
Почему так происходит я не знаю, поэтому и обращаюсь к сообществу.

Как вылетает не написал, виноват:
Запускаем - выбираем ресторан и нажимаем на значок (кнопку) карты.


#11

Спасибо за помощь! Утро вечера мудрёнее.
Ошибка в была в prepare. Название segue в prepare и в stroyboard не совпадало.
Исправил, заработало!


#12

День добрый.
Вот ковыряюсь и два дня уже думаю над одним вопросом:
как проверять авторизован ли пользователь или нет?
Сейчас реализован вход через FB, позже добавлю ВК и Google.
Но вот не пойму по какому принципу проверять - сейчас залогиненный пользователь или нет.
Например, авторизовался через FB - есть время жизни токена, токен поменялся… по какому принципу понимать что новый токен пришел на смену старому? Да и, вообще, свернул человек приложение, оно по какой-то причине разлогинилось - приложение должно проверить текущий статус пользователя… но вот никак я не могу сообразить каким образом… Написал сумбурно, но надеюсь вы меня поймете

import UIKit
import FBSDKLoginKit
import Parse

class ViewController: UIViewController {

var dict : [String : AnyObject]!
var tokens : String = ""

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func btnFBLoginPressed(_ sender: AnyObject) {
    let fbLoginManager = FBSDKLoginManager()
    fbLoginManager.logIn(withReadPermissions: ["public_profile"], from: self) { (result, error) in
        if (error == nil){
            let fbloginresult : FBSDKLoginManagerLoginResult = result!

            print(fbloginresult)
            print(fbloginresult.token.tokenString! as Any)
            
            self.tokens = fbloginresult.token.tokenString!
            if fbloginresult.grantedPermissions != nil {
                if(fbloginresult.grantedPermissions.contains("public_profile"))
                {
                    self.getFBUserData()
                    //fbLoginManager.logOut()
                }
            }
        }
    }
}

// func currentUser () {
//
// }

func getFBUserData(){
    if((FBSDKAccessToken.current()) != nil){
        FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
            if (error == nil){
                self.dict = result as! [String : AnyObject]
                print(result!)
                print(self.dict)
                print(self.dict["last_name"]!)
                print(self.dict["first_name"]!)
                print(self.dict["email"]!)
                self.recordUserToParse()
            }
        })
    }
}


func recordUserToParse() {
    let user = PFUser()
    user.username = String(describing:(dict["first_name"]))
    user.email = dict["email"] as! String!
    user["token"] = tokens
    user.password = tokens
    
    do { print(tokens)
        user.signUpInBackground()
        print("[eqyz")
    } catch let error as NSError {
        print("sign up failed: \(error.localizedDescription)")
    }
}

}


#13

К сожалению и к счастью, в очередной раз решаю вопрос сам.
Для проверки - залогинен или нет (через соц сеть) - отправляю запрос получить один из параметров (Имя, например), если вс] ок, то значит залогинен. Если нет, то на авторизацию отправляю.


#14

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


#15

Например static table view и чтоб била стрелочка ето свойство ячейки Accessory - Disclousure Indicator


#16

Столкнулся с еще одной проблемкой с Parse.
Есть два мака (на обоих кодю и тестирую). Есть Parse (снаружи в серверной стоит).
Parse подключен по внешнему ip - тут все работает исправно.
Логинюсь в приложение только через FB пока.
Проблема в следующем:
порядок действий:

  1. Пользователь в парсе удален, таблица сессий очищена.
  2. На маке№1 запускаю запускаю проект (симулятор) - логинюсь, все происходит успешно, пользователь создается, сессия появляется в соответствующей таблице. Тут проблем нет.
  3. Останавливаю проект (кнопка стоп в xcode), запускаю заново - все хорошо - пользователь залогинен, ошибок в консоле нет. Останавливаю проект, закрываю xcode
  4. Достаю мак№2 - запускаю этот же проект (синхронизация через icloud, все идентично). Просит авторизоваться.
    Нажимаю логин через FB, подтверждаю и попадаю в приложение.
    В консоле вижу ошибку:
    2017-03-14 09:28:18.800 fbLoginApp[4024:5987112] [Error]: Account already exists for this username. (Code: 202, Version: 1.14.2)
    на сервере Парсе вижу ошибку:
    2017-03-14T06:28:24.471Z - Error generating response. ParseError {
    code: 202,
    message: ‘Account already exists for this username.’ }
  5. Останавливаю проект на Маке№2 - запускаю проект - снова не залогинен. Логинуюсь и снова ошибки как в пункте выше.
  6. Если запустить снова на Маке№1 - проблемы нет.

Если начать этот алгоритм заново (пользователь удален, но стартуем с Мака№2) - то все повтроряется тоже самое, только маки меняются местами.
Если удалить толкьо из “session” запись, то проблема тоже остается.

Подскажите, почему так происходит?
Как я понимаю - не работает что-то типа мультилогина… или как?

    let config = ParseClientConfiguration(block: { (ParseMutableClientConfiguration) -> Void in
        ParseMutableClientConfiguration.applicationId = "id"
        ParseMutableClientConfiguration.server = "http://109.*.*.*:8080/parse"
        ParseMutableClientConfiguration.clientKey = "key"
        //ParseMutableClientConfiguration.isLocalDatastoreEnabled = true
        //PFUser.enableRevocableSessionInBackground()
    })
    Parse.initialize(with: config)
    PFUser.enableAutomaticUser()

#17

Так, кажется понял в чем проблема… почти понял…
При логине пользователя я постоянно записываю как нового пользователя, поэтому он и ругается…
Оставил только код с авторизацией через FB (без получения сведений о пользователе).
Создается новая запись в БД при каждом логине.

То есть после авторизации мне нужна проверять существует ли пользователь уже в базе или нет.
Если существует, то ищем пользователя в базе (???) по токену (???) ?
Если не нашли, то создаем нового. Верно?

Вот не понимаю как сравнить полученный токен от FB и записанный у меня в базе.
И по результату после этого как объявить, что PFuser.current() это именно тот пользователь, которого мы нашли по токену?


#18

Ничего проще не оказалось как для соц сетей использовать в качестве логина/пароля получаемые от нее не изменные данные.
do {
try PFUser.logIn(withUsername: ***, password: ***)
}
catch _ {
// no error
}


#19

Теперь при выполнении кода:
userImageFile.getDataInBackground({ (imageData, error) -> Void in
if (error == nil) {
let image = UIImage(data:imageData! )
self.photoImage.image = image
} else {
print(" типа офибка (error)")
}
})
}

Получаю:
Warning: A long-running operation is being executed on the main thread. Break on warnBlockingOperationOnMainThread() to debug.

(Error Domain=Parse Code=100 “Could not connect to the server.” UserInfo={code=100, NSLocalizedDescription=Could not connect to the server., originalError=Error Domain=NSURLErrorDomain Code=-1004 “Could not connect to the server.” UserInfo={NSUnderlyingError=0x60800005f0e0 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 “(null)” UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=http://127.0.0.1:8080/parse/files/54a6f9e41172cda3154b48b5e92ce625fa0bbd4c/dc31dd29fa3ad6a0c41de7f3f7a0e723_file.bin, NSErrorFailingURLKey=http://127.0.0.1:8080/parse/files/54a6f9e41172cda3154b48b5e92ce625fa0bbd4c/dc31dd29fa3ad6a0c41de7f3f7a0e723_file.bin, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=61, NSLocalizedDescription=Could not connect to the server.}, temporary=1, error=Could not connect to the server., NSUnderlyingError=0x608000257d00 {Error Domain=NSURLErrorDomain Code=-1004 “Could not connect to the server.” UserInfo={NSUnderlyingError=0x60800005f0e0 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 “(null)” UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=http://127.0.0.1:8080/parse/files/54a6f9e41172cda3154b48b5e92ce625fa0bbd4c/dc31dd29fa3ad6a0c41de7f3f7a0e723_file.bin, NSErrorFailingURLKey=http://127.0.0.1:8080/parse/files/54a6f9e41172cda3154b48b5e92ce625fa0bbd4c/dc31dd29fa3ad6a0c41de7f3f7a0e723_file.bin, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=61, NSLocalizedDescription=Could not connect to the server.}}})

В настройках прописал внешний адрес, а не localhost.
Не понимаю в чем проблема… подскажите, пожалуйста.


#20

Вот снял на видео