Skip to content

Commit 14531aa

Browse files
committed
Add optional modification and creation date properties. Tests optional-writing.
1 parent 29e826c commit 14531aa

File tree

5 files changed

+121
-15
lines changed

5 files changed

+121
-15
lines changed

Example/NotesExample-iOS/Base.lproj/Main.storyboard

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="H1p-Uh-vWS">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="H1p-Uh-vWS">
33
<device id="retina4_7" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
66
<dependencies>
77
<deployment identifier="iOS"/>
8-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
99
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
1010
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1111
</dependencies>
@@ -465,15 +465,62 @@
465465
</constraints>
466466
</tableViewCellContentView>
467467
</tableViewCell>
468-
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="AuthorCell" rowHeight="165" id="x5Y-uX-LLW">
469-
<rect key="frame" x="0.0" y="99.5" width="375" height="165"/>
468+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="AuthorCell" rowHeight="80" id="MBQ-Q8-ID5" userLabel="DatesCell">
469+
<rect key="frame" x="0.0" y="99.5" width="375" height="80"/>
470+
<autoresizingMask key="autoresizingMask"/>
471+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="MBQ-Q8-ID5" id="I4S-7Z-vmK">
472+
<rect key="frame" x="0.0" y="0.0" width="375" height="79.5"/>
473+
<autoresizingMask key="autoresizingMask"/>
474+
<subviews>
475+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" text="Created:" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ltg-a8-HKT">
476+
<rect key="frame" x="16" y="11" width="72" height="21"/>
477+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
478+
<nil key="textColor"/>
479+
<nil key="highlightedColor"/>
480+
</label>
481+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1980-11-12" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nff-e6-ybc">
482+
<rect key="frame" x="100" y="11" width="87" height="21"/>
483+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
484+
<nil key="textColor"/>
485+
<nil key="highlightedColor"/>
486+
</label>
487+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" text="Modified:" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1TL-Eu-20l">
488+
<rect key="frame" x="16" y="40" width="72" height="21"/>
489+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
490+
<nil key="textColor"/>
491+
<nil key="highlightedColor"/>
492+
</label>
493+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1980-11-12" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dha-hx-Ppc">
494+
<rect key="frame" x="100" y="40" width="87" height="21"/>
495+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
496+
<nil key="textColor"/>
497+
<nil key="highlightedColor"/>
498+
</label>
499+
</subviews>
500+
<constraints>
501+
<constraint firstItem="dha-hx-Ppc" firstAttribute="leading" secondItem="nff-e6-ybc" secondAttribute="leading" id="9mJ-Oi-P9l"/>
502+
<constraint firstAttribute="trailingMargin" relation="greaterThanOrEqual" secondItem="dha-hx-Ppc" secondAttribute="trailing" id="A4w-ih-LEJ"/>
503+
<constraint firstItem="dha-hx-Ppc" firstAttribute="leading" secondItem="1TL-Eu-20l" secondAttribute="trailing" constant="12" id="Ckv-O4-dNw"/>
504+
<constraint firstAttribute="trailingMargin" relation="greaterThanOrEqual" secondItem="nff-e6-ybc" secondAttribute="trailing" id="GNb-RZ-j6t"/>
505+
<constraint firstItem="nff-e6-ybc" firstAttribute="firstBaseline" secondItem="Ltg-a8-HKT" secondAttribute="firstBaseline" id="Ou9-Aj-o1H"/>
506+
<constraint firstItem="nff-e6-ybc" firstAttribute="leading" secondItem="Ltg-a8-HKT" secondAttribute="trailing" constant="12" id="X7I-lp-5mt"/>
507+
<constraint firstItem="Ltg-a8-HKT" firstAttribute="leading" secondItem="I4S-7Z-vmK" secondAttribute="leadingMargin" id="ZfM-xc-Yb3"/>
508+
<constraint firstItem="1TL-Eu-20l" firstAttribute="top" secondItem="Ltg-a8-HKT" secondAttribute="bottom" constant="8" id="k39-R3-XpF"/>
509+
<constraint firstItem="dha-hx-Ppc" firstAttribute="firstBaseline" secondItem="1TL-Eu-20l" secondAttribute="firstBaseline" id="o1L-az-vZv"/>
510+
<constraint firstItem="Ltg-a8-HKT" firstAttribute="top" secondItem="I4S-7Z-vmK" secondAttribute="topMargin" id="pkb-VT-T1D"/>
511+
<constraint firstItem="1TL-Eu-20l" firstAttribute="leading" secondItem="I4S-7Z-vmK" secondAttribute="leadingMargin" id="vkm-et-flm"/>
512+
</constraints>
513+
</tableViewCellContentView>
514+
</tableViewCell>
515+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="AuthorCell" rowHeight="174" id="x5Y-uX-LLW">
516+
<rect key="frame" x="0.0" y="179.5" width="375" height="174"/>
470517
<autoresizingMask key="autoresizingMask"/>
471518
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="x5Y-uX-LLW" id="HcG-RY-8L9">
472-
<rect key="frame" x="0.0" y="0.0" width="375" height="164.5"/>
519+
<rect key="frame" x="0.0" y="0.0" width="375" height="173.5"/>
473520
<autoresizingMask key="autoresizingMask"/>
474521
<subviews>
475522
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wiR-UB-CCr">
476-
<rect key="frame" x="0.0" y="0.0" width="375" height="164.5"/>
523+
<rect key="frame" x="0.0" y="0.0" width="375" height="173.5"/>
477524
<connections>
478525
<outlet property="dataSource" destination="AQa-CG-VLn" id="Cmk-BA-Eh5"/>
479526
<outlet property="delegate" destination="AQa-CG-VLn" id="2WS-Qc-YXR"/>
@@ -493,7 +540,7 @@
493540
<tableViewSection headerTitle="Text" id="doI-x6-0IL">
494541
<cells>
495542
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="TextCell" rowHeight="300" id="gO3-H5-rL6">
496-
<rect key="frame" x="0.0" y="320.5" width="375" height="300"/>
543+
<rect key="frame" x="0.0" y="409.5" width="375" height="300"/>
497544
<autoresizingMask key="autoresizingMask"/>
498545
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="gO3-H5-rL6" id="Czq-DS-mMH">
499546
<rect key="frame" x="0.0" y="0.0" width="375" height="299.5"/>
@@ -531,6 +578,8 @@
531578
<outlet property="authorPickerView" destination="wiR-UB-CCr" id="6Rd-9j-tuQ"/>
532579
<outlet property="cancelDraftBarButtonItem" destination="sCG-Wh-e6e" id="OIb-iB-9Io"/>
533580
<outlet property="contentTextView" destination="rjd-DA-ToB" id="cBg-ZM-Ieh"/>
581+
<outlet property="creationDateLabel" destination="nff-e6-ybc" id="uTx-qa-9Zv"/>
582+
<outlet property="modificationDateLabel" destination="dha-hx-Ppc" id="3Z4-nj-vnk"/>
534583
<outlet property="saveDraftBarButtonItem" destination="vlo-gg-HVH" id="ofd-N2-w72"/>
535584
<outlet property="titleTextField" destination="S9h-nU-4h9" id="Tbq-Yw-e5c"/>
536585
</connections>
@@ -548,7 +597,7 @@
548597
<placeholder placeholderIdentifier="IBFirstResponder" id="dfh-5D-0ys" userLabel="First Responder" sceneMemberID="firstResponder"/>
549598
<exit id="AY2-Yw-i9F" userLabel="Exit" sceneMemberID="exit"/>
550599
</objects>
551-
<point key="canvasLocation" x="2164" y="174"/>
600+
<point key="canvasLocation" x="2164" y="173.16341829085459"/>
552601
</scene>
553602
<!--Notes-->
554603
<scene sceneID="oaf-mk-a0k">
@@ -626,6 +675,6 @@
626675
</scenes>
627676
<inferredMetricsTieBreakers>
628677
<segue reference="jF9-l9-MOM"/>
629-
<segue reference="JXz-I2-P4l"/>
678+
<segue reference="7s5-jb-PaF"/>
630679
</inferredMetricsTieBreakers>
631680
</document>

Example/NotesExample-iOS/NoteEditingViewController.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class NoteEditingViewController: UITableViewController {
3939
@IBOutlet weak var titleTextField: UITextField!
4040
@IBOutlet weak var authorPickerView: UIPickerView!
4141
@IBOutlet weak var contentTextView: UITextView!
42+
@IBOutlet weak var creationDateLabel: UILabel!
43+
@IBOutlet weak var modificationDateLabel: UILabel!
44+
45+
private var noteModificationDateChangeSubscription: NotificationToken!
4246

4347
lazy var authorModel: AuthorModel = AuthorModel(authorBox: Services.instance.authorBox)
4448
var noteBox: Box<Note> = Services.instance.noteBox
@@ -65,6 +69,33 @@ class NoteEditingViewController: UITableViewController {
6569
if let contentTextView = contentTextView {
6670
contentTextView.text = note.text
6771
}
72+
73+
self.refreshCreationDate()
74+
self.refreshModificationDate()
75+
76+
noteModificationDateChangeSubscription = NotificationCenter.default.observe(name: .noteModificationDateDidChange, object: nil) { _ in
77+
self.refreshModificationDate()
78+
}
79+
}
80+
81+
private func refreshCreationDate() {
82+
guard let creationDateLabel = creationDateLabel, let note = note else { return }
83+
84+
var dateString: String?
85+
if let creationDate = note.creationDate {
86+
dateString = DateFormatter.localizedString(from: creationDate, dateStyle: .short, timeStyle: .short)
87+
}
88+
creationDateLabel.text = dateString ?? "--"
89+
}
90+
91+
private func refreshModificationDate() {
92+
guard let modificationDateLabel = modificationDateLabel, let note = note else { return }
93+
94+
var dateString: String?
95+
if let modificationDate = note.modificationDate {
96+
dateString = DateFormatter.localizedString(from: modificationDate, dateStyle: .short, timeStyle: .short)
97+
}
98+
modificationDateLabel.text = dateString ?? "--"
6899
}
69100

70101
private func refreshAuthors() {
@@ -134,6 +165,10 @@ extension NoteEditingViewController: UITextFieldDelegate {
134165
name: .noteTitleDidChange,
135166
object: note,
136167
userInfo: [ "oldValue" : oldTitle, "newValue" : newTitle])
168+
NotificationCenter.default.post(
169+
name: .noteModificationDateDidChange,
170+
object: note,
171+
userInfo: nil)
137172
}
138173
}
139174

@@ -181,6 +216,7 @@ extension NoteEditingViewController: UIPickerViewDelegate {
181216

182217
let oldAuthorId = note.author.targetId
183218
note.author.target = newAuthor
219+
note.modificationDate = Date()
184220

185221
// Do not autosave drafts
186222
guard self.mode == .edit else { return }
@@ -202,6 +238,10 @@ extension NoteEditingViewController: UIPickerViewDelegate {
202238
name: .noteAuthorDidChange,
203239
object: note,
204240
userInfo: changeUserInfo)
241+
NotificationCenter.default.post(
242+
name: .noteModificationDateDidChange,
243+
object: note,
244+
userInfo: nil)
205245
}
206246
}
207247

@@ -228,6 +268,10 @@ extension NoteEditingViewController: UITextViewDelegate {
228268

229269
func textViewDidChange(_ textView: UITextView) {
230270
note?.text = textView.text
271+
NotificationCenter.default.post(
272+
name: .noteModificationDateDidChange,
273+
object: note,
274+
userInfo: nil)
231275
}
232276

233277
func textViewDidEndEditing(_ textView: UITextView) {

Example/NotesExample-iOS/NotesOverviewViewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ extension NotesOverviewViewController {
114114
controller.note = {
115115
let draft = Note()
116116
draft.author.targetId = filter.authorId
117+
draft.modificationDate = Date()
117118
return draft
118119
}()
119120
}

Example/NotesExample-iOS/Notification+NoteChanges.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ import Foundation
44

55
extension Notification.Name {
66
/// Its `userInfo` provides `oldValue` and `newValue` Strings.
7-
static var noteTitleDidChange: Notification.Name { return .init("OB_NoteTitleDidChange") }
7+
static var noteTitleDidChange: Notification.Name { return .init("OBXNoteTitleDidChange") }
88

99
/// - If the note had an author before the change, `userInfo["oldValue"]` contains the old ID value.
1010
/// - If the note has an author after the change, `userInfo["newValue"]` contains the new ID value.
11-
static var noteAuthorDidChange: Notification.Name { return .init("OB_NoteAuthorDidChange") }
11+
static var noteAuthorDidChange: Notification.Name { return .init("OBXNoteAuthorDidChange") }
12+
13+
static var noteModificationDateDidChange: Notification.Name { return .init("OBXNoteModificationDateDidChange") }
1214

1315
/// Its `userInfo` contains `noteId`.
14-
static var noteAdded: Notification.Name { return .init("OB_NoteAdded") }
16+
static var noteAdded: Notification.Name { return .init("OBXNoteAdded") }
1517

1618
/// Its `userInfo` contains `noteId`.
17-
static var noteRemoved: Notification.Name { return .init("OB_NoteRemoved") }
19+
static var noteRemoved: Notification.Name { return .init("OBXNoteRemoved") }
1820

1921
}

Example/Shared/Note.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,18 @@ import ObjectBox
44

55
class Note: Entity {
66
var id: Id<Note> = 0 // An `Id<Note>` is required by ObjectBox
7-
var title: String = ""
8-
var text: String = ""
7+
var title: String = "" {
8+
didSet {
9+
modificationDate = Date()
10+
}
11+
}
12+
var text: String = "" {
13+
didSet {
14+
modificationDate = Date()
15+
}
16+
}
17+
var creationDate: Date? = Date()
18+
var modificationDate: Date?
919
var author: ToOne<Author> = nil
1020

1121
// An initializer with no parameters is required by ObjectBox

0 commit comments

Comments
 (0)