Swiftyinsta: ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ๋ฌธ์ œ

์— ๋งŒ๋“  2019๋…„ 08์›” 07์ผ  ยท  6์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: TheM4hd1/SwiftyInsta

์ƒˆ๋กœ ๋“ฑ๋ก๋œ ์‹ ๊ทœ ์‚ฌ์šฉ์ž๋กœ ๋กœ๊ทธ์ธ์„ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค. ์›น ๋กœ๊ทธ์ธ์ด ๋•Œ๋•Œ๋กœ ๋ฌด์ž‘์œ„๋กœ ์™„๋ฃŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Instagram์€ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ œ์•ˆ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. 1๋ช…์˜ ์‚ฌ์šฉ์ž๋ฅผ ํŒ”๋กœ์šฐํ•˜๋ ค๊ณ  ํ•˜๊ณ  1๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๋‚˜๋ฅผ ํŒ”๋กœ์šฐํ–ˆ์Šต๋‹ˆ๋‹ค(ํ”ผ๋“œ๋Š” ํ‘œ์‹œ๋˜์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ). ๋Œ€๋ถ€๋ถ„ ์ด ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์›น ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์„ 2~3ํšŒ ์‹œ๋„ํ•˜๋ฉด ์ •์ƒ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • 2FA ์—†์Œ - ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ์ง์ ‘ ๋กœ๊ทธ์ธ
help wanted

๋ชจ๋“  6 ๋Œ“๊ธ€

์‹ ๊ทœ๊ฐ€์ž…์ด๋ผ๊ณ  ํ•˜๋ฉด ์›น๋ทฐ์—์„œ ๊ฐ€์ž…ํ•  ๋•Œ ํ•˜๋Š” ๊ฑด๊ฐ€์š”, ์•„๋‹ˆ๋ฉด ๋ฐฉ๊ธˆ ์ƒ์„ฑํ•œ ๊ณ„์ •์œผ๋กœ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋กœ๊ทธ์ธ ํ–ˆ์„ ๋•Œ ํ•˜๋Š” ๊ฑด๊ฐ€์š”? @canaksoy
๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜๊ณ  ๋ณต์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๐Ÿ˜Š

์–ด๋Š ์ชฝ์ด๋“  ์ฃผ์–ด์ง„ URL ๋Œ€์‹  ์ฟ ํ‚ค๋ฅผ ์ง์ ‘ ํ™•์ธํ•˜๋ฉด ์ˆ˜์ •๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์•ž์„œ ์–ธ๊ธ‰ํ•œ ์ œ์•ˆ ํŽ˜์ด์ง€์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์ฟ ํ‚ค๊ฐ€ ๋ชจ๋‘ ์„ค์ •๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •). ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ๋ณด๋‚ด๊ฒ ์Šต๋‹ˆ๋‹ค.

#76, @canaksoy๋ฅผ ํ™•์ธํ•˜์„ธ์š” ๐Ÿ’ช

์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ, ์‹ค์ œ๋กœ instagram.com ํ™•์ธํ•˜์ง€ ์•Š๊ณ  ์œ ํšจํ•œ ์ฟ ํ‚ค์— ๋Œ€ํ•ด์„œ๋งŒ ๋ชจ๋“  init ํ”„๋กœ์„ธ์Šค๋ฅผ async , ๋‹ค์ค‘ ๊ณ„์ • ์ง€์›( 2.0 ์—์„œ ์ด๊ฒƒ์„ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. UIViewController ๋˜๋Š” LoginManager ์›น ๋ณด๊ธฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

@TheM4hd1๋‹˜ ์˜ ์‹ค์ œ ๋ณ‘ํ•ฉ ์Šน์ธ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜Š

ํŒ๋ช… LoginWebView ๋‚ด๊ฐ€ ์ œ๊ฑฐ ํ•ด์š”, ๊ทธ๋ž˜์„œ ์—ฌ์ „ํžˆ, ์‹ฌ์ง€์–ด (๋‚ด๊ฐ€ ๋ชจ๋‘ ๊ทธ๊ฒƒ์„ ๋‚˜ ์ž์‹ ์„ ์‹œํ—˜ํ•˜๊ณ  ์ž์‹ ์˜ ์Šคํฌ๋ฆฐ ์ƒท์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค) ์ด์ƒ @canaksoy์— ์˜ํ•ด ๊ธฐ์ˆ  ๋œ ๊ฒฝ์šฐ ์ผ bug A์— ๋Œ€ํ•œ ๋ผ๋ฒจ์„ help wanted ํ•˜๋‚˜.
๊ทธ๋ž˜๋„ PR์€ ๋ฏธ๋ž˜์— ์ „์ฒด๋ฅผ ์ฆ๋ช…ํ•˜๋Š” ๋ฐ ์œ ์ตํ•˜๋ฏ€๋กœ imho ๋ณ‘ํ•ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜์ค‘์— ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋กโ€ฆ ์ƒˆ๋กœ์šด ๋™์ž‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
(@mkeshnoda)

class LoginViewController: UIViewController {
    var webView: InstagramLoginWebView? {
        didSet {
            oldValue?.removeFromSuperview()
            guard let webView = webView else { return }
            // add to view hierarchy (NECESSARY).
            view.addSubview(webView)
            // always request log in page when setting a new web view.
            webView.loadInstagramLogin()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // create a new `InstagramLoginWebView`.
        InstagramLoginWebView.create(with: view.bounds,
                                     completionHandler: { _, _ in /* deal with login and failures */ },
                                     returnHandler: { [weak self] in self?.webView = $0 })
    }
}

๋‚˜์ค‘์— ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋กโ€ฆ ์ƒˆ๋กœ์šด ๋™์ž‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
(@mkeshnoda)

class LoginViewController: UIViewController {
    var webView: InstagramLoginWebView? {
        didSet {
            oldValue?.removeFromSuperview()
            guard let webView = webView else { return }
            // add to view hierarchy (NECESSARY).
            view.addSubview(webView)
            // always request log in page when setting a new web view.
            webView.loadInstagramLogin()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // create a new `InstagramLoginWebView`.
        InstagramLoginWebView.create(with: view.bounds,
                                     completionHandler: { _, _ in /* deal with login and failures */ },
                                     returnHandler: { [weak self] in self?.webView = $0 })
    }
}

๋˜‘๊ฐ™์ด ํ–ˆ๋Š”๋ฐ ๋กœ๊ทธ์ธ ํ›„ completionHandler ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๐Ÿ˜ญ

์•ฝ๊ฐ„์˜ ๋””๋ฒ„๊น…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  filtered.count = 1 ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. isUserLoggedIn(instagramCookies: [HTTPCookie]?) ์ฟ ํ‚ค 2๊ฐœ๋งŒ ๋ฐ›์Šต๋‹ˆ๋‹ค.

let filtered = cookies.filter {
            !$0.value.isEmpty
                && $0.properties?[.init(rawValue: "Created")] as? TimeInterval ?? 0 > startedAt.timeIntervalSinceReferenceDate
                && ($0.name == "ds_user_id" || $0.name == "csrftoken" || $0.name == "sessionid") }
        guard filtered.count >= 3 else { return }

์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์—ด๊ณ  ํ๋ฆ„์„ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? @mkeshnoda
๋ถˆํ–‰ํžˆ๋„ ์ด 3๊ฐœ์˜ ์ฟ ํ‚ค๊ฐ€ ๋งค์šฐ ํ•„์š”ํ•˜๋ฏ€๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž ๊ทธ๋Œ€๋กœ "๋กœ๊ทธ์ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค"๋ผ๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด์ „์— ์ž‘๋™ํ–ˆ๋‹ค๋ฉด ์ง€๊ธˆ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ด์•ผ ํ•˜๋Š” ์ด์ƒํ•œ ์›์ธ์ž…๋‹ˆ๋‹ค(์ด๋ฏธ 2๊ฐœ ์ด์ƒ ํ™•์ธ๋จ). 4๊ฐœ์˜ ๋‹ค๋ฅธ ๊ณ„์ •์œผ๋กœ ํ…Œ์ŠคํŠธํ–ˆ๋Š”๋ฐ ๋ชจ๋‘ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰