git.iko.soy/dashared/GDproject
on master help sign in
Not working authentication
commitc621bf184f6269b9fde313883449a548a0f60e1b authorDarya Rednikina <rednikina.com@yandex.ru> dateSat 11 May 2019, 00:42 (7 years ago) parent8825e4d
11 files changed+829−87
GDproject.xcodeproj/project.pbxproj+16−4 GDproject/Base.lproj/Main.storyboard+243 GDproject/Controller/Coordinators/LogInCoordinator.swift+36−8 GDproject/Controller/Coordinators/ProfileCoordinator.swift+7−3 GDproject/Controller/Log In/CodeViewController.swift+105 GDproject/Controller/Log In/FacultyTableViewController.swift+87 GDproject/Controller/Log In/InititalsViewCell.swift+23 GDproject/Controller/Log In/LogInCoordinator1.swift−48 GDproject/Controller/Log In/LogInViewController.swift+4−4 GDproject/Controller/Log In/RegisterTableViewController.swift+145 GDproject/Simple model/Model.swift+163−20
GDproject.xcodeproj/project.pbxproj+16−4
@@ -13,6 +13,10 @@
1313 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123E37A4221F1B3200F6E42A /* LogInViewController.swift */; };
1414 123E37A7221F1DD700F6E42A /* MainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123E37A6221F1DD700F6E42A /* MainController.swift */; };
1515 124CC7032221C00C009DF531 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124CC7022221C00C009DF531 /* Model.swift */; };
16+ 125A9A8A2285C3DA00513E2A /* CodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125A9A892285C3DA00513E2A /* CodeViewController.swift */; };
17+ 125A9A8E2286068A00513E2A /* RegisterTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125A9A8D2286068A00513E2A /* RegisterTableViewController.swift */; };
18+ 125A9A90228609C500513E2A /* InititalsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125A9A8F228609C500513E2A /* InititalsViewCell.swift */; };
19+ 125A9A922286100800513E2A /* FacultyTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125A9A912286100800513E2A /* FacultyTableViewController.swift */; };
1620 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57C22171D2A008A3575 /* ProfileViewController.swift */; };
1721 125BD57F22171D73008A3575 /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57E22171D73008A3575 /* Extentions.swift */; };
1822 125BD5812217314A008A3575 /* NewsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD5802217314A008A3575 /* NewsVC.swift */; };
@@ -23,7 +27,6 @@
2327 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
2428 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
2529 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */; };
26− 1291BE3622218DBF009D3F23 /* LogInCoordinator1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE3522218DBF009D3F23 /* LogInCoordinator1.swift */; };
2730 129320042279B4270035C7B3 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320032279B4270035C7B3 /* MessagesViewController.swift */; };
2831 129320072279B5690035C7B3 /* MessagesCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320062279B5690035C7B3 /* MessagesCoordinator.swift */; };
2932 129320092279C3B50035C7B3 /* PeopleToWriteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */; };
@@ -108,6 +111,10 @@
108111 123E37A4221F1B3200F6E42A /* LogInViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInViewController.swift; sourceTree = "<group>"; };
109112 123E37A6221F1DD700F6E42A /* MainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainController.swift; sourceTree = "<group>"; };
110113 124CC7022221C00C009DF531 /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
114+ 125A9A892285C3DA00513E2A /* CodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeViewController.swift; sourceTree = "<group>"; };
115+ 125A9A8D2286068A00513E2A /* RegisterTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterTableViewController.swift; sourceTree = "<group>"; };
116+ 125A9A8F228609C500513E2A /* InititalsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InititalsViewCell.swift; sourceTree = "<group>"; };
117+ 125A9A912286100800513E2A /* FacultyTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacultyTableViewController.swift; sourceTree = "<group>"; };
111118 125BD57C22171D2A008A3575 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
112119 125BD57E22171D73008A3575 /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
113120 125BD5802217314A008A3575 /* NewsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsVC.swift; sourceTree = "<group>"; };
@@ -118,7 +125,6 @@
118125 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
119126 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
120127 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarCoordinator.swift; sourceTree = "<group>"; };
121− 1291BE3522218DBF009D3F23 /* LogInCoordinator1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInCoordinator1.swift; sourceTree = "<group>"; };
122128 129320032279B4270035C7B3 /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
123129 129320062279B5690035C7B3 /* MessagesCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesCoordinator.swift; sourceTree = "<group>"; };
124130 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PeopleToWriteViewController.swift; path = GDproject/Controller/Messages/PeopleToWriteViewController.swift; sourceTree = SOURCE_ROOT; };
@@ -216,8 +222,11 @@
216222 1291BE3722218DC4009D3F23 /* Log In */ = {
217223 isa = PBXGroup;
218224 children = (
225+ 125A9A912286100800513E2A /* FacultyTableViewController.swift */,
226+ 125A9A8F228609C500513E2A /* InititalsViewCell.swift */,
227+ 125A9A8D2286068A00513E2A /* RegisterTableViewController.swift */,
228+ 125A9A892285C3DA00513E2A /* CodeViewController.swift */,
219229 123E37A4221F1B3200F6E42A /* LogInViewController.swift */,
220− 1291BE3522218DBF009D3F23 /* LogInCoordinator1.swift */,
221230 );
222231 path = "Log In";
223232 sourceTree = "<group>";
@@ -425,11 +434,11 @@
425434 files = (
426435 129320072279B5690035C7B3 /* MessagesCoordinator.swift in Sources */,
427436 124CC7032221C00C009DF531 /* Model.swift in Sources */,
437+ 125A9A90228609C500513E2A /* InititalsViewCell.swift in Sources */,
428438 1220FF94227C41270092C6BC /* TaggsSelectionViewController.swift in Sources */,
429439 12F3D6B0224106F700A69214 /* TabbarController.swift in Sources */,
430440 12E36DD522156559006FCDD7 /* MyStackView.swift in Sources */,
431441 12D7D137221D78E800B35452 /* Channel.swift in Sources */,
432− 1291BE3622218DBF009D3F23 /* LogInCoordinator1.swift in Sources */,
433442 1210A0BB223940310080686D /* SimplifiedChannelsList.swift in Sources */,
434443 125BD5812217314A008A3575 /* NewsVC.swift in Sources */,
435444 12E36DB72214400A006FCDD7 /* Post.swift in Sources */,
@@ -440,10 +449,13 @@
440449 1261BB9E227B793D003898CF /* ChatInfoViewController.swift in Sources */,
441450 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */,
442451 1298810B227F13840032ACA3 /* DialogCell.swift in Sources */,
452+ 125A9A922286100800513E2A /* FacultyTableViewController.swift in Sources */,
453+ 125A9A8E2286068A00513E2A /* RegisterTableViewController.swift in Sources */,
443454 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */,
444455 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */,
445456 125BD57F22171D73008A3575 /* Extentions.swift in Sources */,
446457 12D7D133221C321600B35452 /* ChannelListController.swift in Sources */,
458+ 125A9A8A2285C3DA00513E2A /* CodeViewController.swift in Sources */,
447459 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */,
448460 129320092279C3B50035C7B3 /* PeopleToWriteViewController.swift in Sources */,
449461 12BA4B9B224101A400DF93D7 /* ApplicationCoordinator.swift in Sources */,
GDproject/Base.lproj/Main.storyboard+243
@@ -231,6 +231,249 @@
231231 </objects>
232232 <point key="canvasLocation" x="2799" y="1979"/>
233233 </scene>
234+ <!--Code View Controller-->
235+ <scene sceneID="VW5-ny-vaB">
236+ <objects>
237+ <viewController storyboardIdentifier="CodeViewController" id="Lz1-1J-ywG" customClass="CodeViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
238+ <view key="view" contentMode="scaleToFill" id="Rud-1x-pKL">
239+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
240+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
241+ <subviews>
242+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enter the code you received via mail" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hE6-cQ-NbO">
243+ <rect key="frame" x="50" y="47" width="275.5" height="20.5"/>
244+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
245+ <nil key="textColor"/>
246+ <nil key="highlightedColor"/>
247+ </label>
248+ <stackView opaque="NO" contentMode="scaleToFill" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="2Gj-pC-RZ2">
249+ <rect key="frame" x="37.5" y="99" width="300" height="58"/>
250+ <subviews>
251+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="744-t1-YNn">
252+ <rect key="frame" x="0.0" y="0.0" width="40" height="58"/>
253+ <nil key="textColor"/>
254+ <fontDescription key="fontDescription" type="system" pointSize="45"/>
255+ <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
256+ </textField>
257+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="jcR-jp-s7a">
258+ <rect key="frame" x="52" y="0.0" width="40" height="58"/>
259+ <nil key="textColor"/>
260+ <fontDescription key="fontDescription" type="system" pointSize="45"/>
261+ <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
262+ </textField>
263+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="YKO-0M-KD8">
264+ <rect key="frame" x="104" y="0.0" width="40" height="58"/>
265+ <nil key="textColor"/>
266+ <fontDescription key="fontDescription" type="system" pointSize="45"/>
267+ <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
268+ </textField>
269+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="SmG-Ae-oOs">
270+ <rect key="frame" x="156" y="0.0" width="40" height="58"/>
271+ <nil key="textColor"/>
272+ <fontDescription key="fontDescription" type="system" pointSize="45"/>
273+ <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
274+ </textField>
275+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vaP-rO-NZW">
276+ <rect key="frame" x="208" y="0.0" width="40" height="58"/>
277+ <nil key="textColor"/>
278+ <fontDescription key="fontDescription" type="system" pointSize="45"/>
279+ <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
280+ </textField>
281+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="qDh-32-HSn">
282+ <rect key="frame" x="260" y="0.0" width="40" height="58"/>
283+ <nil key="textColor"/>
284+ <fontDescription key="fontDescription" type="system" pointSize="45"/>
285+ <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
286+ </textField>
287+ </subviews>
288+ <constraints>
289+ <constraint firstItem="YKO-0M-KD8" firstAttribute="width" secondItem="744-t1-YNn" secondAttribute="width" id="E7r-rk-4Mb"/>
290+ <constraint firstItem="SmG-Ae-oOs" firstAttribute="width" secondItem="744-t1-YNn" secondAttribute="width" id="Hkd-L6-qkf"/>
291+ <constraint firstItem="qDh-32-HSn" firstAttribute="width" secondItem="744-t1-YNn" secondAttribute="width" id="Koj-e5-Dof"/>
292+ <constraint firstItem="vaP-rO-NZW" firstAttribute="width" secondItem="744-t1-YNn" secondAttribute="width" id="Vzl-ZY-3yI"/>
293+ <constraint firstItem="jcR-jp-s7a" firstAttribute="width" secondItem="744-t1-YNn" secondAttribute="width" id="bDe-cA-CGi"/>
294+ <constraint firstAttribute="width" constant="300" id="gWy-t0-k14"/>
295+ </constraints>
296+ </stackView>
297+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lCU-OF-giE">
298+ <rect key="frame" x="0.0" y="617" width="375" height="50"/>
299+ <subviews>
300+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AMw-Yp-yMs">
301+ <rect key="frame" x="327" y="8" width="32" height="30"/>
302+ <state key="normal" title="Next"/>
303+ <connections>
304+ <action selector="whereToGoNext:" destination="Lz1-1J-ywG" eventType="touchUpInside" id="1OA-n8-Gky"/>
305+ </connections>
306+ </button>
307+ </subviews>
308+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
309+ <constraints>
310+ <constraint firstAttribute="bottom" secondItem="AMw-Yp-yMs" secondAttribute="bottom" constant="12" id="7qy-qR-6jm"/>
311+ <constraint firstItem="AMw-Yp-yMs" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="lCU-OF-giE" secondAttribute="leading" constant="20" symbolic="YES" id="Bqz-qr-CNW"/>
312+ <constraint firstAttribute="height" constant="50" id="Dyu-H3-S3f"/>
313+ <constraint firstAttribute="trailing" secondItem="AMw-Yp-yMs" secondAttribute="trailing" constant="16" id="N19-bz-XCw"/>
314+ <constraint firstItem="AMw-Yp-yMs" firstAttribute="top" secondItem="lCU-OF-giE" secondAttribute="top" constant="8" id="u6d-3F-1Y5"/>
315+ </constraints>
316+ </view>
317+ </subviews>
318+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
319+ <constraints>
320+ <constraint firstItem="hE6-cQ-NbO" firstAttribute="top" secondItem="xwd-51-foC" secondAttribute="top" constant="27" id="8Gx-SH-Pc0"/>
321+ <constraint firstItem="2Gj-pC-RZ2" firstAttribute="top" secondItem="hE6-cQ-NbO" secondAttribute="bottom" constant="31.5" id="DEY-u8-rFj"/>
322+ <constraint firstItem="lCU-OF-giE" firstAttribute="leading" secondItem="xwd-51-foC" secondAttribute="leading" id="HFt-0X-LMb"/>
323+ <constraint firstItem="lCU-OF-giE" firstAttribute="trailing" secondItem="xwd-51-foC" secondAttribute="trailing" id="Z71-jX-S5Q"/>
324+ <constraint firstItem="2Gj-pC-RZ2" firstAttribute="centerX" secondItem="xwd-51-foC" secondAttribute="centerX" id="aSr-QZ-LuB"/>
325+ <constraint firstItem="hE6-cQ-NbO" firstAttribute="centerX" secondItem="xwd-51-foC" secondAttribute="centerX" id="oFz-CS-SSk"/>
326+ <constraint firstItem="lCU-OF-giE" firstAttribute="bottom" secondItem="xwd-51-foC" secondAttribute="bottom" id="vMF-KP-eIa"/>
327+ </constraints>
328+ <viewLayoutGuide key="safeArea" id="xwd-51-foC"/>
329+ </view>
330+ <connections>
331+ <outlet property="bottomConstraint" destination="vMF-KP-eIa" id="a15-El-XZs"/>
332+ <outlet property="f1" destination="744-t1-YNn" id="kaQ-nt-ubz"/>
333+ <outlet property="f2" destination="jcR-jp-s7a" id="tjD-L6-nis"/>
334+ <outlet property="f3" destination="YKO-0M-KD8" id="QHg-UM-Bta"/>
335+ <outlet property="f4" destination="SmG-Ae-oOs" id="bwy-JB-My7"/>
336+ <outlet property="f5" destination="vaP-rO-NZW" id="rNh-iH-648"/>
337+ <outlet property="f6" destination="qDh-32-HSn" id="h4g-QY-abI"/>
338+ </connections>
339+ </viewController>
340+ <placeholder placeholderIdentifier="IBFirstResponder" id="y6E-3d-hPA" userLabel="First Responder" sceneMemberID="firstResponder"/>
341+ </objects>
342+ <point key="canvasLocation" x="4381.6000000000004" y="1961.4692653673164"/>
343+ </scene>
344+ <!--Register Table View Controller-->
345+ <scene sceneID="h6T-rh-iCS">
346+ <objects>
347+ <tableViewController storyboardIdentifier="RegisterTableViewController" id="gZg-8R-SiJ" customClass="RegisterTableViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
348+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="yDm-gG-Zw0">
349+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
350+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
351+ <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
352+ <prototypes>
353+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="cell111" textLabel="bby-bf-qyX" style="IBUITableViewCellStyleDefault" id="Ybe-Vg-GR0">
354+ <rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
355+ <autoresizingMask key="autoresizingMask"/>
356+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Ybe-Vg-GR0" id="OZG-F0-QqJ">
357+ <rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
358+ <autoresizingMask key="autoresizingMask"/>
359+ <subviews>
360+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Add faculty" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bby-bf-qyX">
361+ <rect key="frame" x="16" y="0.0" width="324" height="43.5"/>
362+ <autoresizingMask key="autoresizingMask"/>
363+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
364+ <nil key="textColor"/>
365+ <nil key="highlightedColor"/>
366+ </label>
367+ </subviews>
368+ </tableViewCellContentView>
369+ </tableViewCell>
370+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="facultyCell" textLabel="8Xf-Sx-eEe" detailTextLabel="Vjg-Il-F07" style="IBUITableViewCellStyleSubtitle" id="xJW-zY-MeC">
371+ <rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
372+ <autoresizingMask key="autoresizingMask"/>
373+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="xJW-zY-MeC" id="hnt-oe-CHh">
374+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
375+ <autoresizingMask key="autoresizingMask"/>
376+ <subviews>
377+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Add faculty" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8Xf-Sx-eEe">
378+ <rect key="frame" x="16" y="5" width="87" height="20.5"/>
379+ <autoresizingMask key="autoresizingMask"/>
380+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
381+ <nil key="textColor"/>
382+ <nil key="highlightedColor"/>
383+ </label>
384+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Vjg-Il-F07">
385+ <rect key="frame" x="16" y="25.5" width="44" height="14.5"/>
386+ <autoresizingMask key="autoresizingMask"/>
387+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
388+ <nil key="textColor"/>
389+ <nil key="highlightedColor"/>
390+ </label>
391+ </subviews>
392+ </tableViewCellContentView>
393+ </tableViewCell>
394+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="nameCell" id="VPG-zq-xMh" customClass="InititalsViewCell" customModule="GDproject" customModuleProvider="target">
395+ <rect key="frame" x="0.0" y="143.5" width="375" height="44"/>
396+ <autoresizingMask key="autoresizingMask"/>
397+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VPG-zq-xMh" id="jrO-rB-x0c">
398+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
399+ <autoresizingMask key="autoresizingMask"/>
400+ <subviews>
401+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="hwQ-St-DAp">
402+ <rect key="frame" x="16" y="7" width="343" height="30"/>
403+ <constraints>
404+ <constraint firstAttribute="height" constant="30" id="QXw-Sf-Hnk"/>
405+ </constraints>
406+ <nil key="textColor"/>
407+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
408+ <textInputTraits key="textInputTraits"/>
409+ </textField>
410+ </subviews>
411+ <constraints>
412+ <constraint firstAttribute="bottom" secondItem="hwQ-St-DAp" secondAttribute="bottom" constant="6.5" id="3Kb-PR-ZPu"/>
413+ <constraint firstItem="hwQ-St-DAp" firstAttribute="top" secondItem="jrO-rB-x0c" secondAttribute="top" constant="7" id="CyQ-kQ-mce"/>
414+ <constraint firstAttribute="trailing" secondItem="hwQ-St-DAp" secondAttribute="trailing" constant="16" id="HKq-mF-8h9"/>
415+ <constraint firstItem="hwQ-St-DAp" firstAttribute="leading" secondItem="jrO-rB-x0c" secondAttribute="leading" constant="16" id="NoW-FW-Q6L"/>
416+ </constraints>
417+ </tableViewCellContentView>
418+ <connections>
419+ <outlet property="initialsTextField" destination="hwQ-St-DAp" id="VU3-m6-FnI"/>
420+ </connections>
421+ </tableViewCell>
422+ </prototypes>
423+ <connections>
424+ <outlet property="dataSource" destination="gZg-8R-SiJ" id="OVm-5H-nyP"/>
425+ <outlet property="delegate" destination="gZg-8R-SiJ" id="khe-nG-0w4"/>
426+ </connections>
427+ </tableView>
428+ </tableViewController>
429+ <placeholder placeholderIdentifier="IBFirstResponder" id="0cS-ao-ZWH" userLabel="First Responder" sceneMemberID="firstResponder"/>
430+ </objects>
431+ <point key="canvasLocation" x="5925.6000000000004" y="2041.529235382309"/>
432+ </scene>
433+ <!--Faculty Table View Controller-->
434+ <scene sceneID="WcK-wN-L0e">
435+ <objects>
436+ <tableViewController storyboardIdentifier="FacultyTableViewController" id="wiz-jF-9HF" customClass="FacultyTableViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
437+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="Iny-a7-zjv">
438+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
439+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
440+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
441+ <prototypes>
442+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="F" textLabel="mSQ-7c-C8A" detailTextLabel="YuF-0p-znr" style="IBUITableViewCellStyleSubtitle" id="Otu-BR-9o9">
443+ <rect key="frame" x="0.0" y="28" width="375" height="44"/>
444+ <autoresizingMask key="autoresizingMask"/>
445+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Otu-BR-9o9" id="2Vm-f8-txH">
446+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
447+ <autoresizingMask key="autoresizingMask"/>
448+ <subviews>
449+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="mSQ-7c-C8A">
450+ <rect key="frame" x="16" y="5" width="33.5" height="20.5"/>
451+ <autoresizingMask key="autoresizingMask"/>
452+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
453+ <nil key="textColor"/>
454+ <nil key="highlightedColor"/>
455+ </label>
456+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="YuF-0p-znr">
457+ <rect key="frame" x="16" y="25.5" width="44" height="14.5"/>
458+ <autoresizingMask key="autoresizingMask"/>
459+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
460+ <nil key="textColor"/>
461+ <nil key="highlightedColor"/>
462+ </label>
463+ </subviews>
464+ </tableViewCellContentView>
465+ </tableViewCell>
466+ </prototypes>
467+ <connections>
468+ <outlet property="dataSource" destination="wiz-jF-9HF" id="db0-qR-UJy"/>
469+ <outlet property="delegate" destination="wiz-jF-9HF" id="i3e-Uc-EfR"/>
470+ </connections>
471+ </tableView>
472+ </tableViewController>
473+ <placeholder placeholderIdentifier="IBFirstResponder" id="Kkr-Cr-ZiV" userLabel="First Responder" sceneMemberID="firstResponder"/>
474+ </objects>
475+ <point key="canvasLocation" x="6804" y="2044"/>
476+ </scene>
234477 <!--Simplified Channels List-->
235478 <scene sceneID="gAa-jy-vpG">
236479 <objects>
GDproject/Controller/Coordinators/LogInCoordinator.swift+36−8
@@ -10,6 +10,8 @@ import UIKit
1010
1111class LogInCoordinator: BaseCoordinator {
1212
13+ let storyboard = UIStoryboard(name: "Main", bundle: nil)
14+
1315 var didEndFlow: (()->())?
1416 var window: UIWindow!
1517 var navigationController: UINavigationController?
@@ -22,20 +24,46 @@ class LogInCoordinator: BaseCoordinator {
2224
2325 override func start(){
2426 let logInVC = LogInViewController()
25− logInVC.authenticate = { [weak self] (id) in
27+ logInVC.authenticate = { [weak self, weak logInVC] (email) in
2628
27− Model.authenticate(with: id) {
28− (res) in
29+ Model.authenticate(with: email) { [weak self]
30+ (authStatus) in
31+
32+ print(authStatus.userStatus)
2933
30− if (res) {
31− DataStorage.standard.setUserKey(with: id)
32− self?.didEndFlow?()
34+ if (authStatus.userStatus == "invalid") {
35+ logInVC?.mailTextField.text = "invalid"
3336 }
34− else {
35− DataStorage.standard.setUserKey(with: 0)
37+ else if (authStatus.userStatus == "canRegister") { // register form
38+ self?.presentRegisterVC()
39+ } else { // validation code
40+ self?.presentViewControllerForCodeInput()
3641 }
3742 }
3843 }
44+
3945 navigationController?.pushViewController(logInVC, animated: false)
4046 }
47+
48+ func presentViewControllerForCodeInput()
49+ {
50+ let vc = storyboard.instantiateViewController(withIdentifier: "CodeViewController") as! CodeViewController
51+ self.navigationController?.pushViewController(vc, animated: true)
52+ vc.onSuccessLogIn = {
53+ [weak self] in self?.didEndFlow?()
54+ }
55+ }
56+
57+ func presentRegisterVC(){
58+
59+ let vc1 = storyboard.instantiateViewController(withIdentifier: "RegisterTableViewController") as! RegisterTableViewController
60+
61+ vc1.onRegistration = { [weak self] in
62+ self?.presentViewControllerForCodeInput()
63+ }
64+
65+ self.navigationController?.pushViewController(vc1, animated: true)
66+ }
67+
68+
4169}
GDproject/Controller/Coordinators/ProfileCoordinator.swift+7−3
@@ -27,9 +27,13 @@ class ProfileCoordinator: BaseCoordinator {
2727 let storyboard = UIStoryboard(name: "Main", bundle: nil)
2828 let profile = storyboard.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
2929
30− profile.logOut = { [weak self] in
31− DataStorage.standard.setIsLoggedIn(value: false, with: 0)
32− self?.didEndSession?()
30+ profile.logOut = {
31+ Model.logout() {
32+ [weak self] in
33+
34+ DataStorage.standard.setIsLoggedIn(value: false, with: 0)
35+ self?.didEndSession?()
36+ }
3337 }
3438
3539 profile.onSettings = { [weak self, weak storyboard] in
GDproject/Controller/Log In/CodeViewController.swiftnew file+105
@@ -0,0 +1,105 @@
1+//
2+// CodeViewController.swift
3+// GDproject
4+//
5+// Created by cstore on 10/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class CodeViewController: UIViewController {
12+
13+ @IBOutlet weak var f1: UITextField!
14+ @IBOutlet weak var f2: UITextField!
15+ @IBOutlet weak var f3: UITextField!
16+ @IBOutlet weak var f4: UITextField!
17+ @IBOutlet weak var f5: UITextField!
18+ @IBOutlet weak var f6: UITextField!
19+
20+ var onSuccessLogIn: (()->())?
21+
22+ override func viewDidLoad() {
23+ super.viewDidLoad()
24+ setUpConstraint()
25+
26+ f1.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .touchUpInside)
27+ f2.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .touchUpInside)
28+ f3.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .touchUpInside)
29+ f4.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .touchUpInside)
30+ f5.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .touchUpInside)
31+ f6.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .touchUpInside)
32+ }
33+
34+ override func viewWillAppear(_ animated: Bool) {
35+ super.viewWillAppear(animated)
36+
37+ f1.becomeFirstResponder()
38+ }
39+
40+ @objc func textFiledDidChange(textField: UITextField) {
41+ let text = textField.text
42+
43+ // only 1 char
44+ if text?.utf16.count == 1 {
45+ switch textField {
46+ case f1:
47+ f2.becomeFirstResponder()
48+ case f2:
49+ f3.becomeFirstResponder()
50+ case f3:
51+ f4.becomeFirstResponder()
52+ case f4:
53+ f5.becomeFirstResponder()
54+ case f5:
55+ f6.becomeFirstResponder()
56+ case f6:
57+ f6.resignFirstResponder()
58+ default:
59+ break
60+ }
61+ }
62+ }
63+
64+
65+ @IBOutlet weak var bottomConstraint: NSLayoutConstraint!
66+
67+ @IBAction func whereToGoNext(_ sender: UIButton)
68+ {
69+ let code = "\(f1.text!)\(f2.text!)\(f3.text!)\(f4.text!)\(f5.text!)\(f6.text!)"
70+ if let codeToInt = Int(code)
71+ {
72+ Model.verify(with: codeToInt) { _ in
73+ // if everything is okay we can authemticicate
74+ // Model.authemticiateMe
75+ Model.authenticateMe { [weak self] (res) in
76+ if res {
77+ self?.onSuccessLogIn?()
78+ } else {
79+ print("sosi")
80+ }
81+ }
82+ }
83+ }
84+ }
85+
86+ func setUpConstraint(){
87+ // for keyboard notifications
88+ NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillShowNotification, object: nil)
89+
90+ NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillHideNotification, object: nil)
91+ }
92+
93+ @objc func handleKeyboardNotifications(notification: NSNotification){
94+ if let userInfo = notification.userInfo {
95+ // UIKeyboardFrameEndUserInfoKey
96+ let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
97+ bottomConstraint.constant = notification.name == UIResponder.keyboardWillShowNotification ? keyBoardFrame.height - self.view.safeAreaInsets.bottom : 0
98+
99+ UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
100+ self.view.layoutIfNeeded()
101+ })
102+ }
103+ }
104+
105+}
GDproject/Controller/Log In/FacultyTableViewController.swiftnew file+87
@@ -0,0 +1,87 @@
1+//
2+// FacultyTableViewController.swift
3+// GDproject
4+//
5+// Created by cstore on 10/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol ChosenFactulty: class {
12+ func onChooseFaculty(faculty: Model.Faculty)
13+}
14+
15+class FacultyTableViewController: UITableViewController {
16+
17+ weak var delegate: ChosenFactulty?
18+
19+ var currentFaculties: [Model.Faculty] = []{
20+ didSet {
21+ tableView.reloadData()
22+ }
23+ }
24+
25+ var isFiltering: Bool {
26+ return searchController.isActive && !searchBarIsEmpty()
27+ }
28+
29+ func searchBarIsEmpty() -> Bool {
30+ return searchController.searchBar.text?.isEmpty ?? true
31+ }
32+
33+ var searchController = UISearchController(searchResultsController: nil)
34+
35+ override func viewDidLoad() {
36+ super.viewDidLoad()
37+
38+ self.navigationItem.title = "Faculties"
39+ self.navigationItem.searchController = searchController
40+ self.navigationItem.hidesSearchBarWhenScrolling = false
41+ searchController.obscuresBackgroundDuringPresentation = false
42+
43+ setUpTimer()
44+ }
45+
46+ func setUpTimer(){
47+ Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (timer) in
48+ DispatchQueue.main.async { [weak self] in
49+
50+ if self!.isFiltering {
51+ Model.searchFaculty(string: (self?.searchController.searchBar.text)!) { [weak self] in
52+ self?.currentFaculties = $0
53+ }
54+ }
55+ }
56+ }
57+ }
58+
59+
60+ // MARK: - Table view data source
61+
62+ override func numberOfSections(in tableView: UITableView) -> Int {
63+ return 1
64+ }
65+
66+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
67+ return currentFaculties.count
68+ }
69+
70+
71+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
72+ {
73+ let cell = tableView.dequeueReusableCell(withIdentifier: "F", for: indexPath)
74+
75+ cell.textLabel?.text = currentFaculties[indexPath.row].name
76+ cell.detailTextLabel?.text = currentFaculties[indexPath.row].campusName
77+ cell.selectionStyle = .none
78+
79+ return cell
80+ }
81+
82+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
83+ delegate?.onChooseFaculty(faculty: currentFaculties[indexPath.row])
84+ self.navigationController?.popViewController(animated: true)
85+ }
86+
87+}
GDproject/Controller/Log In/InititalsViewCell.swiftnew file+23
@@ -0,0 +1,23 @@
1+//
2+// InititalsViewCell.swift
3+// GDproject
4+//
5+// Created by cstore on 10/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class InititalsViewCell: UITableViewCell {
12+
13+ @IBOutlet weak var initialsTextField: UITextField!
14+
15+ override func awakeFromNib() {
16+ super.awakeFromNib()
17+ // Initialization code
18+ }
19+
20+ func fill(with name: String){
21+ initialsTextField.text = name
22+ }
23+}
GDproject/Controller/Log In/LogInCoordinator1.swiftdeleted−48
@@ -1,48 +0,0 @@
1−////
2−//// LogInCoordinator.swift
3−//// GDproject
4−////
5−//// Created by cstore on 23/02/2019.
6−//// Copyright © 2019 drHSE. All rights reserved.
7−////
8−//
9−//import UIKit
10−//
11−//class LogInCoordinator{
12−//
13−// private weak var navigationController: UINavigationController?
14−// private var window: UIWindow!
15−// // MARK:- Init
16−// init(navigationController: UINavigationController, window: UIWindow) {
17−// self.navigationController = navigationController
18−// self.window = window
19−// }
20−//
21−// func start(){
22−// showLogInPage()
23−// }
24−//
25−// // MARK: - Private implementation
26−//// private func showStatusPage(){
27−//// let controller = TabbarCoordinator(window: window)
28−//// controller.start()
29−//// }
30−//
31−// private func showLogInPage(){
32−// let controller = UIStoryboard.makeLogIn()
33−//
34−// controller.onLogIn = {
35−// (id) in Model.authenticate(with: id) {
36−// (res) in
37−//
38−// if (res) { DataStorage.standard.setUserKey(with: id) }
39−// else { DataStorage.standard.setUserKey(with: 0) }
40−//
41−// controller.authenticateSucceeded = res
42−// }
43−// }
44−//
45−// navigationController?.pushViewController(controller, animated: false)
46−// }
47−//
48−//}
GDproject/Controller/Log In/LogInViewController.swift+4−4
@@ -14,7 +14,7 @@ import Result
1414
1515class LogInViewController: UIViewController {
1616
17− var authenticate: ((Int)->())?
17+ var authenticate: ((String)->())?
1818
1919 let logInLabel: UILabel = {
2020 let label = UILabel()
@@ -45,7 +45,7 @@ class LogInViewController: UIViewController {
4545 }()
4646
4747 @objc func handleTap(){
48− authenticate?(Int(mailTextField.text!)!)
48+ authenticate?(mailTextField.text!)
4949 }
5050
5151 private lazy var keyboardBar = UIView()
@@ -72,14 +72,14 @@ class LogInViewController: UIViewController {
7272 // configure keyboardBar components
7373 keyboardBar.addSubview(logInButton)
7474 logInButton.height(50)
75− logInButton.leftToSuperview(view.leftAnchor, offset: 16, relation: .equal, isActive: true)
75+ logInButton.rightToSuperview(view.rightAnchor, offset: 16, relation: .equal, isActive: true)
7676
7777 }
7878
7979 func logicOfLogInInputValidation() -> ((String?)->()) {
8080
8181 let logic: ((String?)->()) = { [weak self] (someText) in
82− if let text = someText, !text.isEmpty, let _ = Int(text) {
82+ if let text = someText, !text.isEmpty {
8383 self?.logInButton.isEnabled = true
8484 } else {
8585 self?.logInButton.isEnabled = false
GDproject/Controller/Log In/RegisterTableViewController.swiftnew file+145
@@ -0,0 +1,145 @@
1+//
2+// RegisterTableViewController.swift
3+// GDproject
4+//
5+// Created by cstore on 10/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class RegisterTableViewController: UITableViewController, ChosenFactulty
12+{
13+
14+ func onChooseFaculty(faculty: Model.Faculty) {
15+ self.faculty = faculty
16+ tableView.reloadData()
17+ }
18+
19+
20+ var onRegistration: (()->())?
21+
22+ var faculty: Model.Faculty?
23+ var user: Model.NewRegistration = Model.NewRegistration(email: "dyurednikina@edu.hse.ru", firstName: nil, middleName: nil, lastName: nil, faculty: nil)
24+
25+ override func viewDidLoad()
26+ {
27+ super.viewDidLoad()
28+
29+ tableView.keyboardDismissMode = .interactive
30+ navigationItem.title = user.email
31+ navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(endRegistration))
32+ }
33+
34+ @objc func endRegistration()
35+ {
36+ updateUser()
37+ guard let faculty = faculty else { return }
38+
39+ user.faculty = faculty.url
40+
41+ Model.register(object: user)
42+ { [weak self] in
43+ self?.onRegistration?()
44+ }
45+
46+ }
47+ // MARK: - Table view data source
48+
49+ override func numberOfSections(in tableView: UITableView) -> Int {
50+ return 2
51+ }
52+
53+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
54+
55+ switch section {
56+ case 0:
57+ return 3
58+ default:
59+ if let _ = faculty {
60+ return 2
61+ } else {
62+ return 1
63+ }
64+ }
65+ }
66+
67+ override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
68+ {
69+ switch section {
70+ case 0:
71+ return "Initials"
72+ default:
73+ return "Faculty"
74+ }
75+ }
76+
77+
78+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
79+ {
80+ switch indexPath.section {
81+ case 0:
82+ let cell = tableView.dequeueReusableCell(withIdentifier: "nameCell", for: indexPath) as! InititalsViewCell
83+ switch indexPath.row{
84+ case 0:
85+ if let name = user.firstName {
86+ cell.fill(with: name)
87+ } else {
88+ cell.initialsTextField.placeholder = "First name"
89+ }
90+ case 1:
91+ if let name = user.middleName {
92+ cell.fill(with: name)
93+ } else {
94+ cell.initialsTextField.placeholder = "Middle name"
95+ }
96+ default:
97+ if let name = user.lastName {
98+ cell.fill(with: name)
99+ } else {
100+ cell.initialsTextField.placeholder = "Last name"
101+ }
102+ }
103+ cell.selectionStyle = .none
104+ return cell
105+ default:
106+ switch indexPath.row {
107+ case 0:
108+ let cell = tableView.dequeueReusableCell(withIdentifier: "cell111", for: indexPath)
109+ cell.selectionStyle = .none
110+ return cell
111+ default:
112+ let cell = tableView.dequeueReusableCell(withIdentifier: "facultyCell", for: indexPath)
113+ cell.textLabel?.text = faculty!.name
114+ cell.detailTextLabel?.text = faculty!.campusName
115+ cell.selectionStyle = .none
116+ return cell
117+ }
118+ }
119+ }
120+
121+
122+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
123+ if indexPath.section == 1 && indexPath.row == 0 {
124+
125+ updateUser()
126+
127+ let vc = storyboard?.instantiateViewController(withIdentifier: "FacultyTableViewController") as! FacultyTableViewController
128+
129+ vc.delegate = self
130+
131+ self.navigationController?.pushViewController(vc, animated: true)
132+ }
133+ }
134+
135+ func updateUser(){
136+ guard let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? InititalsViewCell else {return}
137+ guard let cell1 = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? InititalsViewCell else {return}
138+ guard let cell2 = tableView.cellForRow(at: IndexPath(row: 2, section: 0)) as? InititalsViewCell else {return}
139+
140+ user.firstName = cell.initialsTextField.text!
141+ user.middleName = cell1.initialsTextField.text!
142+ user.lastName = cell2.initialsTextField.text!
143+ }
144+
145+}
GDproject/Simple model/Model.swift+163−20
@@ -14,20 +14,27 @@ class Model{
1414
1515 static let invalidTocken = 498
1616
17− static var hashTagTree: CompletionTree?
17+ static var hashTagTree: CompletionTree?
1818
1919 private static var isValidTocken: ((Int)->())? = { responce in
2020 print(responce)
2121 if responce == invalidTocken {
22− DataStorage.standard.setIsLoggedIn(value: false, with: 0)
23− (UIApplication.shared.delegate as! AppDelegate).relaunch()
22+ Model.logout {
23+ print("Logout Is Successful")
24+ DataStorage.standard.setIsLoggedIn(value: false, with: 0)
25+ (UIApplication.shared.delegate as! AppDelegate).relaunch()
26+ }
2427 }
2528 }
2629
2730 private static let baseUrl = "https://valera-denis.herokuapp.com"
2831 static let decoder = JSONDecoder()
29−
32+
33+ static let authMeURL = URL(string: "\(baseUrl)/authentication/me")!
34+ static let registerMeURL = URL(string: "\(baseUrl)/authentication/register")!
35+ static let authVerifyURL = URL(string: "\(baseUrl)/authentication/verify")!
3036 static let authenticationURL = URL(string:"\(baseUrl)/authentication/login")!
37+ static let logOutURL = URL(string:"\(baseUrl)/authentication/logout")!
3138 static let postsLastURL = URL(string:"\(baseUrl)/posts/last")!
3239 static let postsForUserURL = URL(string:"\(baseUrl)/posts/forUser")!
3340 static let postsPublishURL = URL(string:"\(baseUrl)/posts/publish")!
@@ -49,6 +56,7 @@ class Model{
4956 static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
5057 static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
5158 static let messagesGetUserChatURL = URL(string: "\(baseUrl)/messages/get/userChat")!
59+ static let facultySearchURL = URL(string: "\(baseUrl)/faculty/search")!
5260
5361
5462 struct QueryPosts<T: Codable>: Codable {
@@ -183,41 +191,147 @@ class Model{
183191 }
184192 }
185193
186− static func authenticate(with id: Int, completion: @escaping ((Bool)->())) {
194+ struct AuthStatus: Codable {
195+ var userStatus: String
187196
188− let json: [String:Any] = ["authenticationId" : id]
189− let jsonData = try? JSONSerialization.data(withJSONObject: json)
197+ init(){
198+ userStatus = "invalid"
199+ }
200+ }
201+
202+ static func logout(completion: @escaping (()->())){
203+ var request = URLRequest(url: logOutURL)
204+ request.httpMethod = "POST"
205+
206+ AF.request(request).response { (responce) in
207+ isValidTocken?(responce.response?.statusCode ?? 498)
208+
209+ completion()
210+ }
211+ }
212+
213+ /*
214+ "email": "vchernyshev@hse.ru",
215+ "middleName": "Algebrovich",
216+ "lastName": "Leonidov",
217+ "faculty": "cs.hse.ru/dse",
218+ "firstName": "Seva"
219+ */
220+
221+ struct NewRegistration: Codable{
222+ var email: String
223+ var firstName: String?
224+ var middleName: String?
225+ var lastName: String?
226+ var faculty: String?
227+ }
228+
229+ static func register(object: NewRegistration, completion: @escaping (()->())) {
230+ var request = URLRequest(url: registerMeURL)
231+ request.httpBody = try? JSONEncoder().encode(object)
190232
191− var request = URLRequest(url: authenticationURL)
192233 request.httpMethod = "POST"
234+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
193235
194− // insert json data to the request
195− request.httpBody = jsonData
236+ AF.request(request).response { (responce) in
237+
238+ guard let code = responce.response?.statusCode else { return }
239+ isValidTocken?(code)
240+
241+ if code == 204 {
242+ let fields = responce.response?.allHeaderFields as? [String :String]
243+
244+ let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: responce.response!.url!)
245+
246+ HTTPCookieStorage.shared.setCookie(cookies[0])
247+
248+ completion()
249+ }
250+ }
251+ }
252+
253+ // true only if everything is good
254+ static func verify(with code: Int, completion: @escaping ((Bool)->())){
255+ var request = URLRequest(url: authVerifyURL)
256+ request.httpMethod = "POST"
257+ request.httpBody = "\(code)".data(using: .utf8)
196258 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
197259
198260 AF.request(request).response { (responce) in
199261
200− guard let realResponse = responce.response, realResponse.statusCode == 200 else
201− {
202− print("Not a 200 response")
203− completion(false)
204− return
262+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
263+ isValidTocken?(statusCode)
264+
265+ if statusCode == 204 {
266+ // at this point cookies are set
267+ let fields = responce.response?.allHeaderFields as? [String :String]
268+
269+ let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: responce.response!.url!)
270+
271+ HTTPCookieStorage.shared.setCookie(cookies[0])
272+
273+ completion(true)
205274 }
206275
276+ completion(false)
277+ }
278+ }
279+
280+ // yes or no
281+ static func authenticateMe(completion: @escaping ((Bool)->())){
282+ var request = URLRequest(url: authMeURL)
283+ request.httpMethod = "POST"
284+
285+ AF.request(request).response { (responce) in
286+
287+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
288+ isValidTocken?(statusCode)
289+
207290 guard let json = responce.data else { return }
208291 guard let personId = Int(String(data: json, encoding: String.Encoding.utf8)!) else {
209292 completion(false)
210293 return
211294 }
212295
213− let fields = realResponse.allHeaderFields as? [String :String]
296+ DataStorage.standard.setIsLoggedIn(value: true, with: personId)
297+ completion(true)
298+ }
299+ }
300+
301+ // register, ok or invalid
302+ static func authenticate(with email: String, completion: @escaping ((AuthStatus)->())) {
303+
304+ let json: [String:Any] = ["authenticationEmail" : email]
305+ let jsonData = try? JSONSerialization.data(withJSONObject: json)
306+
307+ var request = URLRequest(url: authenticationURL)
308+ request.httpMethod = "POST"
309+
310+ // insert json data to the request
311+ request.httpBody = jsonData
312+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
313+
314+ AF.request(request).response { (response) in
214315
215− let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: realResponse.url!)
316+ guard let realResponse = response.response, realResponse.statusCode == 200 else
317+ {
318+ print("Not a 200 response")
319+ completion(AuthStatus())
320+ return
321+ }
322+
323+ guard let json = response.data else { return }
324+ guard let res = try? decoder.decode(AuthStatus.self, from: json) else { return }
216325
217− HTTPCookieStorage.shared.setCookie(cookies[0])
326+ if realResponse.statusCode == 200 && res.userStatus == "registered"
327+ {
328+ // at this point cookies are set
329+ let fields = realResponse.allHeaderFields as? [String :String]
330+ let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: realResponse.url!)
331+ HTTPCookieStorage.shared.setCookie(cookies[0])
332+ }
218333
219− DataStorage.standard.setIsLoggedIn(value: true, with: personId)
220− completion(true)
334+ completion(res)
221335 }
222336 }
223337
@@ -855,4 +969,33 @@ class Model{
855969 completion()
856970 }
857971 }
972+
973+ struct Faculty: Codable
974+ {
975+
976+ var path: String
977+ var url: String
978+ var campusName: String
979+ var campusCode: String
980+ var name: String
981+ var tags: [String]
982+
983+ }
984+
985+ static func searchFaculty(string: String, completion: @escaping (([Model.Faculty])->()))
986+ {
987+ var request = URLRequest(url: facultySearchURL)
988+ request.httpMethod = "POST"
989+ request.httpBody = string.data(using: .utf8)
990+ request.setValue("text/plain;charset=utf-8", forHTTPHeaderField: "Content-Type")
991+
992+ AF.request(request).response { (response) in
993+ isValidTocken?(response.response?.statusCode ?? 498)
994+
995+ guard let json = response.data else { return }
996+ guard let faculties = try? decoder.decode([Faculty].self, from: json) else { return }
997+
998+ completion(faculties)
999+ }
1000+ }
8581001}