diff --git a/Vienna Tests/ArticleTests.m b/Vienna Tests/ArticleTests.m
new file mode 100644
index 0000000000..b16224966d
--- /dev/null
+++ b/Vienna Tests/ArticleTests.m
@@ -0,0 +1,51 @@
+//
+// VNAArticleTests.m
+// Vienna
+//
+// Copyright © 2016 uk.co.opencommunity. All rights reserved.
+//
+
+@import XCTest;
+
+#import "Article.h"
+#import "Vienna_Tests-Swift.h"
+
+static NSString * const guid = @"07f446d2-8d6b-4d99-b488-cebc9eac7c33";
+
+@interface VNAArticleTests : XCTestCase
+
+@property (nonatomic) Article *article;
+
+@end
+
+@implementation VNAArticleTests
+
+- (void)setUp
+{
+ self.article = [[Article alloc] initWithGUID:guid];
+}
+
+- (void)tearDown
+{
+ self.article = nil;
+}
+
+- (void)testRandomCompatibilityKeyPath
+{
+ NSString *randomArticleDataKeyPath = [@"articleData." stringByAppendingString:@"dummyProperty"];
+
+ XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomArticleDataKeyPath],
+ NSException,
+ NSUndefinedKeyException);
+}
+
+- (void)testRandomKeyPath
+{
+ NSString *randomKeyPath = @"dummyProperty";
+
+ XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomKeyPath],
+ NSException,
+ NSUndefinedKeyException);
+}
+
+@end
diff --git a/Vienna Tests/ArticleTests.swift b/Vienna Tests/ArticleTests.swift
index a2d3ca6bcf..2c3568bd7d 100644
--- a/Vienna Tests/ArticleTests.swift
+++ b/Vienna Tests/ArticleTests.swift
@@ -42,20 +42,16 @@ class ArticleTests: XCTestCase {
var article: Article!
var articleConverter: WebKitArticleConverter!
- override func setUpWithError() throws {
- try super.setUpWithError()
- // Put setup code here. This method is called before the invocation of each test method in the class.
+ override func setUp() {
self.article = Article(guid: guid)
self.articleConverter = WebKitArticleConverter()
}
- override func tearDownWithError() throws {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
+ override func tearDown() {
self.article = nil
- try super.tearDownWithError()
}
- // MARK: Article Tests
+ // MARK: - Article Tests
func testAccessInstanceVariablesDirectly() {
XCTAssertFalse(Article.accessInstanceVariablesDirectly)
@@ -64,24 +60,32 @@ class ArticleTests: XCTestCase {
// MARK: - Test custom setters
func testTitle() {
+ XCTAssertNil(self.article.title)
+
self.article.title = title
XCTAssertEqual(self.article.title, title)
}
func testAuthor() {
+ XCTAssertNil(self.article.author)
+
self.article.author = author
XCTAssertEqual(self.article.author, author)
}
func testLink() {
+ XCTAssertNil(self.article.link)
+
self.article.link = link
XCTAssertEqual(self.article.link, link)
}
func testLastUpdate() {
+ XCTAssertNil(self.article.lastUpdate)
+
let date = Date()
self.article.lastUpdate = date
@@ -90,6 +94,8 @@ class ArticleTests: XCTestCase {
}
func testPublicationDate() {
+ XCTAssertNil(self.article.publicationDate)
+
let date = Date()
self.article.publicationDate = date
@@ -98,30 +104,35 @@ class ArticleTests: XCTestCase {
}
func testBody() {
+ XCTAssertNil(self.article.body)
+
self.article.body = body
XCTAssertEqual(self.article.body, body)
}
func testEnclosure() {
+ XCTAssertNil(self.article.enclosure)
+
self.article.enclosure = enclosure
XCTAssertEqual(self.article.enclosure, enclosure)
- }
- func testEnclosureRemoval() {
self.article.enclosure = nil
-
XCTAssertNil(self.article.enclosure)
}
func testHasEnclosure() {
+ XCTAssertFalse(self.article.hasEnclosure)
+
self.article.hasEnclosure = true
XCTAssert(self.article.hasEnclosure)
}
func testFolderId() {
+ XCTAssertEqual(self.article.folderId, -1)
+
let folderId = 111
self.article.folderId = folderId
@@ -130,12 +141,13 @@ class ArticleTests: XCTestCase {
}
func testGuid() {
- self.article.guid = guid
-
+ // The GUID is set by the initializer.
XCTAssertEqual(self.article.guid, guid)
}
func testParentId() {
+ XCTAssertEqual(self.article.parentId, 0)
+
let parentId = 222
self.article.parentId = parentId
@@ -144,7 +156,9 @@ class ArticleTests: XCTestCase {
}
func testStatus() {
- let status = ArticleStatus.new.rawValue
+ XCTAssertEqual(self.article.status, .empty)
+
+ let status = Article.Status.new
self.article.status = status
@@ -154,7 +168,7 @@ class ArticleTests: XCTestCase {
func testMarkRead() {
XCTAssertFalse(self.article.isRead)
- self.article.markRead(true)
+ self.article.isRead = true
XCTAssert(self.article.isRead)
}
@@ -162,7 +176,7 @@ class ArticleTests: XCTestCase {
func testMarkRevised() {
XCTAssertFalse(self.article.isRevised)
- self.article.markRevised(true)
+ self.article.isRevised = true
XCTAssert(self.article.isRevised)
}
@@ -170,7 +184,7 @@ class ArticleTests: XCTestCase {
func testMarkDeleted() {
XCTAssertFalse(self.article.isDeleted)
- self.article.markDeleted(true)
+ self.article.isDeleted = true
XCTAssert(self.article.isDeleted)
}
@@ -178,7 +192,7 @@ class ArticleTests: XCTestCase {
func testMarkFlagged() {
XCTAssertFalse(self.article.isFlagged)
- self.article.markFlagged(true)
+ self.article.isFlagged = true
XCTAssert(self.article.isFlagged)
}
@@ -186,7 +200,7 @@ class ArticleTests: XCTestCase {
func testMarkEnclosureDowloaded() {
XCTAssertFalse(self.article.enclosureDownloaded)
- self.article.markEnclosureDownloaded(true)
+ self.article.enclosureDownloaded = true
XCTAssert(self.article.enclosureDownloaded)
}
@@ -235,18 +249,6 @@ class ArticleTests: XCTestCase {
XCTAssertEqual(self.article.value(forKeyPath: summaryKeyPath) as? String, summary)
}
-// func testRandomCompatibilityKeyPath() {
-// let randomArticleDataKeyPath = "articleData.dummyProperty"
-//
-// XCTAssertThrowsSpecificNamed(self.article.value(forKeyPath: randomArticleDataKeyPath), NSException, NSUndefinedKeyException);
-// }
-
-// func testRandomKeyPath() {
-// let randomKeyPath = "dummyProperty"
-//
-// XCTAssertThrowsSpecificNamed(self.article.value(forKeyPath: randomKeyPath), NSException, NSUndefinedKeyException);
-// }
-
func testDescription() {
let title = "Lorem ipsum dolor sit amet"
diff --git a/Vienna Tests/VNAArticleTests.m b/Vienna Tests/VNAArticleTests.m
deleted file mode 100644
index bc2784b480..0000000000
--- a/Vienna Tests/VNAArticleTests.m
+++ /dev/null
@@ -1,366 +0,0 @@
-//
-// VNAArticleTests.m
-// Vienna
-//
-// Copyright © 2016 uk.co.opencommunity. All rights reserved.
-//
-
-@import XCTest;
-
-#import "Article.h"
-#import "ArticleConverter.h"
-#import "Vienna_Tests-Swift.h"
-
-static NSString * const GUID = @"07f446d2-8d6b-4d99-b488-cebc9eac7c33";
-static NSString * const Author = @"Author McAuthorface";
-static NSString * const Title = @"Lorem ipsum dolor sit amet";
-static NSString * const Link = @"http://www.vienna-rss.com";
-static NSString * const Enclosure = @"http://vienna-rss.sourceforge.net/img/vienna_logo.png";
-static NSString * const EnclosureFilename = @"vienna_logo.png"; // last path component of Enclosure
-static NSString * const Body =
- @"
Pellentesque habitant morbi tristique senectus et netus "
- "et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, "
- "ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper."
- "Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet "
- "est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo "
- "vitae
, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, "
- "eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. "
- "Donec non enim in turpis pulvinar facilisis. Ut felis.
";
-
-
-@interface VNAArticleTests : XCTestCase
-
-@property (nonatomic, strong) Article *article;
-@property (nonatomic, strong) WebKitArticleConverter *articleConverter;
-
-@end
-
-@implementation VNAArticleTests
-
-- (void)setUp
-{
- [super setUp];
-
- self.article = [[Article alloc] initWithGuid:GUID];
- self.articleConverter = [[WebKitArticleConverter alloc] init];
-}
-
-- (void)testAccessInstanceVariablesDirectly
-{
- XCTAssertFalse([Article accessInstanceVariablesDirectly]);
-}
-
-#pragma mark - Test custom setters
-
-- (void)testTitle
-{
- self.article.title = Title;
-
- XCTAssertEqualObjects(self.article.title, Title);
-}
-
-- (void)testAuthor
-{
- self.article.author = Author;
-
- XCTAssertEqualObjects(self.article.author, Author);
-}
-
-- (void)testLink
-{
- self.article.link = Link;
-
- XCTAssertEqualObjects(self.article.link, Link);
-}
-
-- (void)testLastUpdate
-{
- NSDate *date = [NSDate date];
-
- self.article.lastUpdate = date;
-
- XCTAssertEqualObjects(self.article.lastUpdate, date);
-}
-
-- (void)testPublicationDate
-{
- NSDate *date = [NSDate date];
-
- self.article.publicationDate = date;
-
- XCTAssertEqualObjects(self.article.publicationDate, date);
-}
-
-- (void)testBody
-{
- self.article.body = Body;
-
- XCTAssertEqualObjects(self.article.body, Body);
-}
-
-- (void)testEnclosure
-{
- self.article.enclosure = Enclosure;
-
- XCTAssertEqualObjects(self.article.enclosure, Enclosure);
-}
-
-- (void)testEnclosureRemoval
-{
- self.article.enclosure = nil;
-
- XCTAssertNil(self.article.enclosure);
-}
-
-- (void)testHasEnclosure
-{
- self.article.hasEnclosure = YES;
-
- XCTAssert(self.article.hasEnclosure);
-}
-
-- (void)testFolderId
-{
- NSInteger folderId = 111;
-
- self.article.folderId = folderId;
-
- XCTAssertEqual(self.article.folderId, folderId);
-}
-
-- (void)testGuid
-{
- self.article.guid = GUID;
-
- XCTAssertEqualObjects(self.article.guid, GUID);
-}
-
-- (void)testParentId
-{
- NSInteger parentId = 222;
-
- self.article.parentId = parentId;
-
- XCTAssertEqual(self.article.parentId, parentId);
-}
-
-- (void)testStatus
-{
- NSInteger status = ArticleStatusNew;
-
- self.article.status = status;
-
- XCTAssertEqual(self.article.status, status);
-}
-
-- (void)testMarkRead
-{
- XCTAssertFalse(self.article.isRead);
-
- [self.article markRead:YES];
-
- XCTAssert(self.article.isRead);
-}
-
-- (void)testMarkRevised
-{
- XCTAssertFalse(self.article.isRevised);
-
- [self.article markRevised:YES];
-
- XCTAssert(self.article.isRevised);
-}
-
-- (void)testMarkDeleted
-{
- XCTAssertFalse(self.article.isDeleted);
-
- [self.article markDeleted:YES];
-
- XCTAssert(self.article.isDeleted);
-}
-
-- (void)testMarkFlagged
-{
- XCTAssertFalse(self.article.isFlagged);
-
- [self.article markFlagged:YES];
-
- XCTAssert(self.article.isFlagged);
-}
-
-- (void)testMarkEnclosureDowloaded
-{
- XCTAssertFalse(self.article.enclosureDownloaded);
-
- [self.article markEnclosureDownloaded:YES];
-
- XCTAssert(self.article.enclosureDownloaded);
-}
-
-- (void)testCompatibilityDate
-{
- NSDate *date = [NSDate date];
- NSString *dateKeyPath = [@"articleData." stringByAppendingString:MA_Field_LastUpdate];
-
- self.article.lastUpdate = date;
-
- XCTAssertEqualObjects([self.article valueForKeyPath:dateKeyPath], date);
-}
-
-- (void)testCompatibilityAuthor
-{
- NSString *authorKeyPath = [@"articleData." stringByAppendingString:MA_Field_Author];
-
- self.article.author = Author;
-
- XCTAssertEqualObjects([self.article valueForKeyPath:authorKeyPath], Author);
-}
-
-- (void)testCompatibilitySubject
-{
- NSString *subject = @"Lorem ipsum dolor sit amet";
- NSString *subjectKeyPath = [@"articleData." stringByAppendingString:MA_Field_Subject];
-
- self.article.title = subject;
-
- XCTAssertEqualObjects([self.article valueForKeyPath:subjectKeyPath], subject);
-}
-
-- (void)testCompatibilityLink
-{
- NSString *link = @"http://www.vienna-rss.com";
- NSString *linkKeyPath = [@"articleData." stringByAppendingString:MA_Field_Link];
-
- self.article.link = link;
-
- XCTAssertEqualObjects([self.article valueForKeyPath:linkKeyPath], link);
-}
-
-- (void)testCompatibilitySummary
-{
- NSString *summary = @"Lorem ipsum dolor sit amet";
- NSString *summaryKeyPath = [@"articleData." stringByAppendingString:MA_Field_Summary];
-
- self.article.body = summary;
-
- XCTAssertEqualObjects([self.article valueForKeyPath:summaryKeyPath], summary);
-}
-
-- (void)testRandomCompatibilityKeyPath
-{
- NSString *randomArticleDataKeyPath = [@"articleData." stringByAppendingString:@"dummyProperty"];
-
- XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomArticleDataKeyPath],
- NSException,
- NSUndefinedKeyException);
-}
-
-- (void)testRandomKeyPath
-{
- NSString *randomKeyPath = @"dummyProperty";
-
- XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomKeyPath],
- NSException,
- NSUndefinedKeyException);
-}
-
-- (void)testDescription
-{
- NSString *title = @"Lorem ipsum dolor sit amet";
-
- self.article.guid = GUID;
- self.article.title = title;
-
- NSString *expectedDescription =
- [NSString stringWithFormat:@"{GUID=%@ title=\"%@\"", GUID, title];
-
- XCTAssertEqualObjects(self.article.description, expectedDescription);
-}
-
-#pragma mark - Expand tags
-
-- (void)testExpandLinkTag
-{
- NSString *string = @"$ArticleLink$/development";
-
- NSString *expectedString = [NSString stringWithFormat:@"%@/development", Link];
-
- self.article.link = Link;
-
- NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES];
-
- XCTAssertEqualObjects(expandedString, expectedString);
-}
-
-- (void)testExpandTitleTag
-{
- NSString *string = @"$ArticleTitle$";
- NSString *expectedString = Title;
-
- self.article.title = Title;
-
- NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES];
-
- XCTAssertEqualObjects(expandedString, expectedString);
-}
-
-- (void)testExpandArticleBodyTag
-{
- NSString *string = @"$ArticleBody$";
- NSString *expectedString = Body;
-
- self.article.body = Body;
-
- NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES];
-
- XCTAssertEqualObjects(expandedString, expectedString);
-}
-
-- (void)testExpandArticleAuthorTag
-{
- NSString *string = @"$ArticleAuthor$";
- NSString *expectedString = Author;
-
- self.article.author = Author;
-
- NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES];
-
- XCTAssertEqualObjects(expandedString, expectedString);
-}
-
-- (void)testExpandArticleEnclosureLinkTag
-{
- NSString *string = @"$ArticleEnclosureLink$";
- NSString *expectedString = Enclosure;
-
- self.article.enclosure = Enclosure;
-
- NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES];
-
- XCTAssertEqualObjects(expandedString, expectedString);
-}
-
-- (void)testExpandArticleEnclosureFileName
-{
- NSString *string = @"$ArticleEnclosureFilename$";
- NSString *expectedString = EnclosureFilename;
-
- self.article.enclosure = Enclosure;
- NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES];
-
- XCTAssertEqualObjects(expandedString, expectedString);
-}
-
-- (void)testURLIDNinArticleView
-{
- self.article.link = @"http://ουτοπία.δπθ.gr/نجيب_محفوظ/";
- NSString * htmlTextFromIDNALink = [self.articleConverter articleTextFromArray:@[self.article]];
-
- self.article.link = @"http://xn--kxae4bafwg.xn--pxaix.gr/%D9%86%D8%AC%D9%8A%D8%A8_%D9%85%D8%AD%D9%81%D9%88%D8%B8/";
- NSString * htmlTextFromResolvedIDNALink = [self.articleConverter articleTextFromArray:@[self.article]];
-
- XCTAssertEqualObjects(htmlTextFromIDNALink, htmlTextFromResolvedIDNALink);
-}
-
-@end
diff --git a/Vienna.xcodeproj/project.pbxproj b/Vienna.xcodeproj/project.pbxproj
index 6efffd98c8..4da0780719 100644
--- a/Vienna.xcodeproj/project.pbxproj
+++ b/Vienna.xcodeproj/project.pbxproj
@@ -132,7 +132,7 @@
435028B8165DE9E00018EDB7 /* URLHandlerCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 43502890165DE9DF0018EDB7 /* URLHandlerCommand.m */; };
435028B9165DE9E00018EDB7 /* ViennaApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 43502892165DE9DF0018EDB7 /* ViennaApp.m */; };
43BA97FE1664804E00B95F35 /* DSClickableURLTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = B2E09F2C111192B7003B530A /* DSClickableURLTextField.m */; settings = {COMPILER_FLAGS = "-Xclang -analyzer-tidy-checker=-readability-braces-around-statements"; }; };
- 4D36B44B1D37F91E009736C1 /* VNAArticleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D36B44A1D37F91E009736C1 /* VNAArticleTests.m */; };
+ 4D36B44B1D37F91E009736C1 /* ArticleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D36B44A1D37F91E009736C1 /* ArticleTests.m */; };
664F87C713C62DFE00E266DE /* OpenReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 664F87C613C62DFE00E266DE /* OpenReader.m */; };
793C95331C42A0DD00984D4E /* FoldersFilterable.m in Sources */ = {isa = PBXBuildFile; fileRef = 793C95321C42A0DD00984D4E /* FoldersFilterable.m */; };
8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
@@ -428,7 +428,7 @@
439824221666B3DB00FFE219 /* notes.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = notes.html; sourceTree = SOURCE_ROOT; };
439824231666B3DB00FFE219 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = SOURCE_ROOT; };
439824241666B3DB00FFE219 /* Release Instructions.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "Release Instructions.md"; sourceTree = SOURCE_ROOT; };
- 4D36B44A1D37F91E009736C1 /* VNAArticleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VNAArticleTests.m; sourceTree = ""; };
+ 4D36B44A1D37F91E009736C1 /* ArticleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArticleTests.m; sourceTree = ""; };
664F87C513C62DFE00E266DE /* OpenReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenReader.h; sourceTree = ""; };
664F87C613C62DFE00E266DE /* OpenReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenReader.m; sourceTree = ""; };
793C95311C42A0DD00984D4E /* FoldersFilterable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FoldersFilterable.h; sourceTree = ""; };
@@ -679,7 +679,7 @@
035B703619E0E4AE00197334 /* Vienna Tests */ = {
isa = PBXGroup;
children = (
- 4D36B44A1D37F91E009736C1 /* VNAArticleTests.m */,
+ 4D36B44A1D37F91E009736C1 /* ArticleTests.m */,
3A8D9AE225A9DA4B0016F30F /* ArticleTests.swift */,
2F437B3A25CF336400AD1B57 /* SubscriptionModelTests.swift */,
2FE328F025CF436C005B9C18 /* CriteriaTests.swift */,
@@ -1725,7 +1725,7 @@
2F437B3C25CF336400AD1B57 /* SubscriptionModelTests.swift in Sources */,
F6A179D326B82BE3008DDA42 /* NSFileManagerExtensionTests.swift in Sources */,
F6AC41AC25A4FAF6007DED7B /* FeedDiscovererTests.swift in Sources */,
- 4D36B44B1D37F91E009736C1 /* VNAArticleTests.m in Sources */,
+ 4D36B44B1D37F91E009736C1 /* ArticleTests.m in Sources */,
F6E01A072C652DEE0082E07B /* RSSFeedTests.swift in Sources */,
F648C2B81E7F3BEA00CE4043 /* DirectoryMonitorTests.swift in Sources */,
3A50014E259AA2BE00AA6AAD /* WebKitArticleConverter.swift in Sources */,
diff --git a/Vienna/Sources/Application/AppController.m b/Vienna/Sources/Application/AppController.m
index 6800b4c2a8..3ccb2ef3d3 100644
--- a/Vienna/Sources/Application/AppController.m
+++ b/Vienna/Sources/Application/AppController.m
@@ -2344,7 +2344,7 @@ -(IBAction)markReadToggle:(id)sender
Article * theArticle = self.selectedArticle;
if (theArticle != nil && !db.readOnly) {
NSArray * articleArray = self.articleController.markedArticleRange;
- [self.articleController markReadByArray:articleArray readFlag:!theArticle.read];
+ [self.articleController markReadByArray:articleArray readFlag:!theArticle.isRead];
}
}
@@ -2380,7 +2380,7 @@ -(IBAction)markFlagged:(id)sender
Article * theArticle = self.selectedArticle;
if (theArticle != nil && !db.readOnly) {
NSArray * articleArray = self.articleController.markedArticleRange;
- [self.articleController markFlaggedByArray:articleArray flagged:!theArticle.flagged];
+ [self.articleController markFlaggedByArray:articleArray flagged:!theArticle.isFlagged];
}
}
@@ -3333,7 +3333,7 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem
} else if (theAction == @selector(markFlagged:)) {
Article * thisArticle = self.selectedArticle;
if (thisArticle != nil) {
- if (thisArticle.flagged) {
+ if (thisArticle.isFlagged) {
[menuItem setTitle:NSLocalizedString(@"Mark Unflagged", nil)];
} else {
[menuItem setTitle:NSLocalizedString(@"Mark Flagged", nil)];
diff --git a/Vienna/Sources/Database/Database.m b/Vienna/Sources/Database/Database.m
index 1330510f6b..c9f32d47e3 100644
--- a/Vienna/Sources/Database/Database.m
+++ b/Vienna/Sources/Database/Database.m
@@ -1506,10 +1506,10 @@ -(BOOL)addArticle:(Article *)article toFolder:(NSInteger)folderID
NSString * articleEnclosure = article.enclosure.vna_trimmed;
NSString * articleGuid = article.guid;
NSInteger parentId = article.parentId;
- BOOL marked_flag = article.flagged;
- BOOL read_flag = article.read;
- BOOL revised_flag = article.revised;
- BOOL deleted_flag = article.deleted;
+ BOOL marked_flag = article.isFlagged;
+ BOOL read_flag = article.isRead;
+ BOOL revised_flag = article.isRevised;
+ BOOL deleted_flag = article.isDeleted;
BOOL hasenclosure_flag = article.hasEnclosure;
NSDate *currentDate = [NSDate date];
@@ -1601,7 +1601,7 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit
NSString * userName = articleUpdate.author.vna_trimmed;
NSString * articleGuid = articleUpdate.guid;
NSInteger parentId = articleUpdate.parentId;
- BOOL revised_flag = articleUpdate.revised;
+ BOOL revised_flag = articleUpdate.isRevised;
// keep last update date the same if not set in the current version of the article
NSDate * lastUpdate = existingArticle.lastUpdate;
@@ -1657,7 +1657,7 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit
// Articles preexisting in database should be marked as revised.
// New articles created during the current refresh should not be marked as revised,
// even if there are multiple versions of the new article in the feed.
- if (existingArticle.revised || (existingArticle.status == ArticleStatusEmpty)) {
+ if (existingArticle.isRevised || (existingArticle.status == ArticleStatusEmpty)) {
revised_flag = YES;
}
@@ -1684,7 +1684,7 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit
// update the existing article in memory
existingArticle.title = articleTitle;
existingArticle.body = articleBody;
- [existingArticle markRevised:revised_flag];
+ existingArticle.revised = revised_flag;
existingArticle.parentId = parentId;
existingArticle.author = userName;
existingArticle.link = articleLink;
@@ -1760,13 +1760,13 @@ -(BOOL)deleteArticle:(Article *)article
}];
if (success) {
- if (!article.read) {
+ if (!article.isRead) {
[self setFolderUnreadCount:folder adjustment:-1];
}
if (folder.countOfCachedArticles > 0) {
// If we're in a smart folder, the cached article may be different.
Article * cachedArticle = [folder articleFromGuid:guid];
- [cachedArticle markDeleted:YES];
+ cachedArticle.deleted = YES;
[folder removeArticleFromCache:guid];
}
return YES;
@@ -2043,11 +2043,11 @@ -(NSArray *)minimalCacheForFolder:(NSInteger)folderId
++unread_count;
}
- Article * article = [[Article alloc] initWithGuid:guid];
- [article markRead:read_flag];
- [article markFlagged:marked_flag];
- [article markRevised:revised_flag];
- [article markDeleted:deleted_flag];
+ Article * article = [[Article alloc] initWithGUID:guid];
+ article.read = read_flag;
+ article.flagged = marked_flag;
+ article.revised = revised_flag;
+ article.deleted = deleted_flag;
article.folderId = folderId;
article.title = title;
article.link = link;
@@ -2238,12 +2238,12 @@ -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterS
}
while ([results next]) {
NSString * guid = [results stringForColumnIndex:0];
- Article * article = [[Article alloc] initWithGuid:guid];
+ Article * article = [[Article alloc] initWithGUID:guid];
article.folderId = [results intForColumnIndex:1];
article.parentId = [results intForColumnIndex:2];
- [article markRead:[results intForColumnIndex:3]];
- [article markFlagged:[results intForColumnIndex:4]];
- [article markDeleted:[results intForColumnIndex:5]];
+ article.read = [results intForColumnIndex:3];
+ article.flagged = [results intForColumnIndex:4];
+ article.deleted = [results intForColumnIndex:5];
article.title = [results stringForColumnIndex:6];
article.author = [results stringForColumnIndex:7];
article.link = [results stringForColumnIndex:8];
@@ -2251,18 +2251,18 @@ -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterS
article.lastUpdate = [NSDate dateWithTimeIntervalSince1970:[results stringForColumnIndex:10].doubleValue];
NSString * text = [results stringForColumnIndex:11];
article.body = text;
- [article markRevised:[results intForColumnIndex:12]];
+ article.revised = [results intForColumnIndex:12];
article.hasEnclosure = [results intForColumnIndex:13];
article.enclosure = [results stringForColumnIndex:14];
Folder * articleFolder = [self folderFromID:article.folderId];
article.status = [articleFolder retrieveKnownStatusForGuid:guid];
- if (folder == nil || !article.deleted || folder.type == VNAFolderTypeTrash) {
+ if (folder == nil || !article.isDeleted || folder.type == VNAFolderTypeTrash) {
[newArray addObject:article];
}
// Keep our own track of unread articles
- if (!article.read) {
+ if (!article.isRead) {
++unread_count;
}
@@ -2331,7 +2331,7 @@ -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)is
Folder * folder = [self folderFromID:folderId];
if (folder != nil) {
Article * article = [folder articleFromGuid:guid];
- if (article != nil && isRead != article.read) {
+ if (article != nil && isRead != article.isRead) {
// Mark an individual article read
FMDatabaseQueue *queue = self.databaseQueue;
__block BOOL success;
@@ -2342,7 +2342,7 @@ -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)is
if (success) {
NSInteger adjustment = (isRead ? -1 : 1);
- [article markRead:isRead];
+ article.read = isRead;
[self setFolderUnreadCount:folder adjustment:adjustment];
}
}
@@ -2426,7 +2426,7 @@ -(void)markArticleFlagged:(NSInteger)folderId guid:(NSString *)guid isFlagged:(B
Folder * folder = [self folderFromID:folderId];
if (folder != nil) {
Article * article = [folder articleFromGuid:guid];
- if (article != nil && isFlagged != article.flagged) {
+ if (article != nil && isFlagged != article.isFlagged) {
FMDatabaseQueue *queue = self.databaseQueue;
__block BOOL success;
[queue inDatabase:^(FMDatabase *db) {
@@ -2438,7 +2438,7 @@ -(void)markArticleFlagged:(NSInteger)folderId guid:(NSString *)guid isFlagged:(B
if (success) {
// Mark an individual article flagged
- [article markFlagged:isFlagged];
+ article.flagged = isFlagged;
}
}
}
@@ -2453,7 +2453,7 @@ -(void)markArticleDeleted:(Article *)article isDeleted:(BOOL)isDeleted
NSString * guid = article.guid;
Folder * folder = [self folderFromID:folderId];
if (folder !=nil) {
- if (isDeleted && !article.read) {
+ if (isDeleted && !article.isRead) {
[self markArticleRead:folderId guid:guid isRead:YES];
}
FMDatabaseQueue *queue = self.databaseQueue;
@@ -2463,14 +2463,14 @@ -(void)markArticleDeleted:(Article *)article isDeleted:(BOOL)isDeleted
@(folderId),
guid];
}];
- [article markDeleted:isDeleted];
+ article.deleted = isDeleted;
//TODO this should all move to the folder implementation, to make this less of a god object.
// Or even better: when marking an article as deleted it triggers the deletion from its folder itself, and that in turn triggers the db update.
// The same also applies to deleteArticle and probably many other parts of this class.
if (folder.countOfCachedArticles > 0) {
// If we're in a smart folder, the cached article may be different.
Article * cachedArticle = [folder articleFromGuid:guid];
- [cachedArticle markDeleted:isDeleted];
+ cachedArticle.deleted = isDeleted;
}
}
}
diff --git a/Vienna/Sources/Fetching/OpenReader.m b/Vienna/Sources/Fetching/OpenReader.m
index 0f5d808138..8a9c96e2ff 100644
--- a/Vienna/Sources/Fetching/OpenReader.m
+++ b/Vienna/Sources/Fetching/OpenReader.m
@@ -570,7 +570,7 @@ -(void)feedRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *)
for (NSDictionary *newsItem in (NSArray *)subscriptionsDict[@"items"]) {
NSString *articleGuid = newsItem[@"id"];
- Article *article = [[Article alloc] initWithGuid:articleGuid];
+ Article *article = [[Article alloc] initWithGUID:articleGuid];
article.folderId = refreshedFolder.itemId;
if (newsItem[@"author"] != nil) {
@@ -589,13 +589,13 @@ -(void)feedRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *)
for (NSString *category in (NSArray *)newsItem[@"categories"]) {
if ([category hasSuffix:@"/read"]) {
- [article markRead:YES];
+ article.read = YES;
}
if ([category hasSuffix:@"/starred"]) {
- [article markFlagged:YES];
+ article.flagged = YES;
}
if ([category hasSuffix:@"/kept-unread"]) {
- [article markRead:NO];
+ article.read = NO;
}
}
@@ -737,13 +737,13 @@ -(void)readRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *)
[guidArray addObject:guid];
// now, mark relevant articles unread
- [[refreshedFolder articleFromGuid:guid] markRead:NO];
+ [refreshedFolder articleFromGuid:guid].read = NO;
}
[[Database sharedManager] markUnreadArticlesFromFolder:refreshedFolder guidArray:guidArray];
// reset starred statuses in cache : we will receive in -StarredRequestDone: the updated list
for (Article *article in refreshedFolder.articles) {
- [article markFlagged:NO];
+ article.flagged = NO;
}
} @catch (NSException *exception) {
[aItem appendDetail:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Error", nil), exception]];
@@ -801,7 +801,7 @@ -(void)starredRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse
guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx", (long long)shortId];
}
[guidArray addObject:guid];
- [[refreshedFolder articleFromGuid:guid] markFlagged:YES];
+ [refreshedFolder articleFromGuid:guid].flagged = YES;
}
[[Database sharedManager] markStarredArticlesFromFolder:refreshedFolder guidArray:guidArray];
@@ -1152,7 +1152,7 @@ -(void)markReadDone:(NSMutableURLRequest *)request response:(NSURLResponse *)res
Article *article = ((NSDictionary *)[request vna_userInfo])[@"article"];
BOOL readFlag = [[((NSDictionary *)[request vna_userInfo]) valueForKey:@"readFlag"] boolValue];
[[Database sharedManager] markArticleRead:article.folderId guid:article.guid isRead:readFlag];
- [article markRead:readFlag];
+ article.read = readFlag;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc vna_postNotificationOnMainThreadWithName:MA_Notify_ArticleListStateChange object:@(article.folderId)];
}
diff --git a/Vienna/Sources/Fetching/RefreshManager.m b/Vienna/Sources/Fetching/RefreshManager.m
index c66866922a..4eddddfe7c 100644
--- a/Vienna/Sources/Fetching/RefreshManager.m
+++ b/Vienna/Sources/Fetching/RefreshManager.m
@@ -839,7 +839,7 @@ -(void)finalizeFolderRefresh:(NSDictionary *)parameters
NSString * articleGuid = [self getOrCalculateArticleGuid:newsItem folderId:folderId articles:articleArray articleGuidArray:articleGuidArray];
[articleGuidArray addObject:articleGuid];
- Article * article = [[Article alloc] initWithGuid:articleGuid];
+ Article * article = [[Article alloc] initWithGUID:articleGuid];
article.folderId = folderId;
article.author = newsItem.authors;
article.body = newsItem.content;
diff --git a/Vienna/Sources/Main window/ArticleController.m b/Vienna/Sources/Main window/ArticleController.m
index cb307865b8..e001011ab0 100644
--- a/Vienna/Sources/Main window/ArticleController.m
+++ b/Vienna/Sources/Main window/ArticleController.m
@@ -364,7 +364,7 @@ -(void)displayFirstUnread
{
// mark current article read
Article * currentArticle = self.selectedArticle;
- if (currentArticle != nil && !currentArticle.read) {
+ if (currentArticle != nil && !currentArticle.isRead) {
[self markReadByArray:@[currentArticle] readFlag:YES];
}
@@ -392,7 +392,7 @@ -(void)displayNextUnread
{
// mark current article read
Article * currentArticle = self.selectedArticle;
- if (currentArticle != nil && !currentArticle.read) {
+ if (currentArticle != nil && !currentArticle.isRead) {
[self markReadByArray:@[currentArticle] readFlag:YES];
}
@@ -480,7 +480,7 @@ -(void)reloadArrayOfArticles
// Make sure selectedArticle hasn't changed since reload started.
if (articleToPreserve != nil && articleToPreserve != article) {
- if (article != nil && !article.deleted) {
+ if (article != nil && !article.isDeleted) {
articleToPreserve = article;
} else {
articleToPreserve = nil;
@@ -503,7 +503,7 @@ -(void)reloadArrayOfArticles
Article *currentArticle = self.selectedArticle;
if (currentArticle == article &&
[[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles]
- && currentArticle.revised)
+ && currentArticle.isRevised)
{
[[NSNotificationCenter defaultCenter] postNotificationName:MA_Notify_ArticleViewChange object:nil];
}
@@ -757,7 +757,7 @@ -(void)innerMarkFlaggedByArray:(NSArray *)articleArray flagged:(BOOL)flagged
[[Database sharedManager] markArticleFlagged:theArticle.folderId
guid:theArticle.guid
isFlagged:flagged];
- [theArticle markFlagged:flagged];
+ theArticle.flagged = flagged;
}
}
@@ -804,12 +804,12 @@ -(void)innerMarkReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag
{
for (Article * theArticle in articleArray) {
NSInteger folderId = theArticle.folderId;
- if (theArticle.read != readFlag) {
+ if (theArticle.isRead != readFlag) {
if ([[Database sharedManager] folderFromID:folderId].type == VNAFolderTypeOpenReader) {
[[OpenReader sharedManager] markRead:theArticle readFlag:readFlag];
} else {
[[Database sharedManager] markArticleRead:folderId guid:theArticle.guid isRead:readFlag];
- [theArticle markRead:readFlag];
+ theArticle.read = readFlag;
}
}
}
@@ -872,7 +872,7 @@ -(void)markAllFoldersReadByArray:(NSArray *)folderArray
![folderArray containsObject:currentFolder]))
{
for (Article *theArticle in folderArrayOfArticles) {
- [theArticle markRead:YES];
+ theArticle.read = YES;
}
}
@@ -1028,7 +1028,7 @@ -(void)handleArticleListContentChange:(NSNotification *)note
- (BOOL)filterArticle:(Article *)article usingMode:(NSInteger)filterMode {
switch (filterMode) {
case VNAFilterUnread:
- return !article.read;
+ return !article.isRead;
case VNAFilterLastRefresh: {
return article.status == ArticleStatusNew || article.status == ArticleStatusUpdated;
}
@@ -1042,9 +1042,9 @@ - (BOOL)filterArticle:(Article *)article usingMode:(NSInteger)filterMode {
return [article.lastUpdate compare:twoDaysAgo] != NSOrderedAscending;
}
case VNAFilterFlagged:
- return article.flagged;
+ return article.isFlagged;
case VNAFilterUnreadOrFlagged:
- return (!article.read || article.flagged);
+ return (!article.isRead || article.isFlagged);
default:
return true;
}
diff --git a/Vienna/Sources/Main window/ArticleListView.m b/Vienna/Sources/Main window/ArticleListView.m
index ad72864c34..73953de2bc 100644
--- a/Vienna/Sources/Main window/ArticleListView.m
+++ b/Vienna/Sources/Main window/ArticleListView.m
@@ -321,11 +321,11 @@ -(IBAction)singleClickRow:(id)sender
Article * theArticle = allArticles[row];
NSString * columnName = ((NSTableColumn *)columns[column]).identifier;
if ([columnName isEqualToString:MA_Field_Read]) {
- [self.controller.articleController markReadByArray:@[theArticle] readFlag:!theArticle.read];
+ [self.controller.articleController markReadByArray:@[theArticle] readFlag:!theArticle.isRead];
return;
}
if ([columnName isEqualToString:MA_Field_Flagged]) {
- [self.controller.articleController markFlaggedByArray:@[theArticle] flagged:!theArticle.flagged];
+ [self.controller.articleController markFlaggedByArray:@[theArticle] flagged:!theArticle.isFlagged];
return;
}
if ([columnName isEqualToString:MA_Field_HasEnclosure]) {
@@ -889,7 +889,7 @@ -(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow
Article * theArticle;
while (currentRow < totalRows) {
theArticle = allArticles[currentRow];
- if (!theArticle.read) {
+ if (!theArticle.isRead) {
[self makeRowSelectedAndVisible:currentRow];
return YES;
}
@@ -968,7 +968,7 @@ -(void)performFindPanelAction:(NSInteger)actionTag
BOOL shouldSelectArticle = YES;
if ([Preferences standardPreferences].markReadInterval > 0.0f) {
Article * article = self.controller.articleController.allArticles[0u];
- if (!article.read) {
+ if (!article.isRead) {
shouldSelectArticle = NO;
}
}
@@ -1016,7 +1016,7 @@ -(void)refreshImmediatelyArticleAtCurrentRow
[self refreshArticlePane];
Article * theArticle = self.selectedArticle;
- if (theArticle != nil && !theArticle.read) {
+ if (theArticle != nil && !theArticle.isRead) {
CGFloat interval = [Preferences standardPreferences].markReadInterval;
if (interval > 0 && !isAppInitialising) {
markReadTimer = [NSTimer scheduledTimerWithTimeInterval:(double)interval
@@ -1157,7 +1157,7 @@ -(void)refreshArticlePane
-(void)markCurrentRead:(NSTimer *)aTimer
{
Article * theArticle = self.selectedArticle;
- if (theArticle != nil && !theArticle.read && ![Database sharedManager].readOnly) {
+ if (theArticle != nil && !theArticle.isRead && ![Database sharedManager].readOnly) {
[self.controller.articleController markReadByArray:@[theArticle] readFlag:YES];
}
}
@@ -1187,10 +1187,10 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum
theArticle = allArticles[rowIndex];
NSString * identifier = aTableColumn.identifier;
if ([identifier isEqualToString:MA_Field_Read]) {
- if (!theArticle.read) {
+ if (!theArticle.isRead) {
if (@available(macOS 11, *)) {
NSImage *image = nil;
- if (theArticle.revised) {
+ if (theArticle.isRevised) {
image = [NSImage imageWithSystemSymbolName:@"sparkles"
accessibilityDescription:nil];
// Setting the template property to NO enables the tint color.
@@ -1203,7 +1203,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum
}
return image;
} else {
- if (theArticle.revised) {
+ if (theArticle.isRevised) {
return [NSImage imageNamed:ACImageNameRevised];
} else {
return [NSImage imageNamed:ACImageNameUnread];
@@ -1213,7 +1213,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum
return nil;
}
if ([identifier isEqualToString:MA_Field_Flagged]) {
- if (theArticle.flagged) {
+ if (theArticle.isFlagged) {
if (@available(macOS 11, *)) {
NSImage *image = [NSImage imageWithSystemSymbolName:@"flag.fill"
accessibilityDescription:nil];
@@ -1247,7 +1247,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum
if ([db fieldByName:MA_Field_Subject].visible) {
NSDictionary * topLineDictPtr;
- if (theArticle.read) {
+ if (theArticle.isRead) {
topLineDictPtr = (isSelectedRow ? selectionDict : topLineDict);
} else {
topLineDictPtr = (isSelectedRow ? unreadTopLineSelectionDict : unreadTopLineDict);
@@ -1338,7 +1338,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum
[NSException raise:@"ArticleListView unknown table column identifier exception" format:@"Unknown table column identifier: %@", identifier];
}
- theAttributedString = [[NSMutableAttributedString alloc] initWithString:SafeString(cellString) attributes:(theArticle.read ? reportCellDict : unreadReportCellDict)];
+ theAttributedString = [[NSMutableAttributedString alloc] initWithString:SafeString(cellString) attributes:(theArticle.isRead ? reportCellDict : unreadReportCellDict)];
[theAttributedString fixFontAttributeInRange:NSMakeRange(0u, theAttributedString.length)];
return theAttributedString;
}
diff --git a/Vienna/Sources/Main window/UnifiedDisplayView.m b/Vienna/Sources/Main window/UnifiedDisplayView.m
index 2ba5fb4897..bfe52b904e 100644
--- a/Vienna/Sources/Main window/UnifiedDisplayView.m
+++ b/Vienna/Sources/Main window/UnifiedDisplayView.m
@@ -247,7 +247,7 @@ -(void)performFindPanelAction:(NSInteger)actionTag
BOOL shouldSelectArticle = YES;
if ([Preferences standardPreferences].markReadInterval > 0.0f) {
Article * article = self.controller.articleController.allArticles[0u];
- if (!article.read) {
+ if (!article.isRead) {
shouldSelectArticle = NO;
}
}
@@ -393,7 +393,7 @@ -(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow
Article * theArticle;
while (currentRow < totalRows) {
theArticle = allArticles[currentRow];
- if (!theArticle.read) {
+ if (!theArticle.isRead) {
[self makeRowSelectedAndVisible:currentRow];
return YES;
}
@@ -483,7 +483,7 @@ -(void)refreshFolder:(NSInteger)refreshFlag
-(void)markCurrentRead:(NSTimer *)aTimer
{
Article * theArticle = self.selectedArticle;
- if (theArticle != nil && !theArticle.read && ![Database sharedManager].readOnly) {
+ if (theArticle != nil && !theArticle.isRead && ![Database sharedManager].readOnly) {
[self.controller.articleController markReadByArray:@[theArticle] readFlag:YES];
}
}
diff --git a/Vienna/Sources/Models/Article.h b/Vienna/Sources/Models/Article.h
index a5aef227fe..0181aa0b39 100644
--- a/Vienna/Sources/Models/Article.h
+++ b/Vienna/Sources/Models/Article.h
@@ -43,8 +43,6 @@ extern NSString * const MA_Field_Enclosure;
extern NSString * const MA_Field_EnclosureDownloaded;
extern NSString * const MA_Field_HasEnclosure;
-NS_ASSUME_NONNULL_END
-
typedef NS_ENUM(NSInteger, VNAArticleFieldTag) {
VNAArticleFieldTagGUID = 400,
VNAArticleFieldTagSubject,
@@ -70,14 +68,17 @@ typedef NS_ENUM(NSInteger, ArticleStatus) {
ArticleStatusEmpty = 0,
ArticleStatusNew,
ArticleStatusUpdated
-};
+} NS_SWIFT_NAME(Article.Status);
@interface Article : NSObject
-// Accessor functions
--(instancetype _Nonnull)initWithGuid:(NSString * _Nonnull)theGuid /*NS_DESIGNATED_INITIALIZER*/;
+- (instancetype)initWithGUID:(NSString *)guid NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
@property (nonatomic) NSInteger parentId;
-@property (nonnull, nonatomic, copy) NSString *guid;
+@property (nonatomic, copy) NSString *guid;
@property (nullable, nonatomic, copy) NSString *author;
@property (nullable, nonatomic, copy) NSString *body;
@property (nullable, nonatomic, copy) NSString *title;
@@ -88,17 +89,14 @@ typedef NS_ENUM(NSInteger, ArticleStatus) {
@property (nullable, nonatomic) NSDate *publicationDate;
@property (nullable, nonatomic, readonly) Folder *containingFolder;
@property (nonatomic) NSInteger folderId;
-@property (nonatomic, getter=isRead, readonly) BOOL read;
-@property (nonatomic, getter=isRevised, readonly) BOOL revised;
-@property (nonatomic, getter=isFlagged, readonly) BOOL flagged;
-@property (nonatomic, getter=isDeleted, readonly) BOOL deleted;
+@property (nonatomic, getter=isRead) BOOL read;
+@property (nonatomic, getter=isRevised) BOOL revised;
+@property (nonatomic, getter=isFlagged) BOOL flagged;
+@property (nonatomic, getter=isDeleted) BOOL deleted;
@property (nonatomic) BOOL hasEnclosure;
-@property (nonatomic, readonly) BOOL enclosureDownloaded;
-@property (nonatomic) NSInteger status;
--(void)markRead:(BOOL)flag;
--(void)markRevised:(BOOL)flag;
--(void)markFlagged:(BOOL)flag;
--(void)markDeleted:(BOOL)flag;
--(void)markEnclosureDownloaded:(BOOL)flag;
+@property (nonatomic) BOOL enclosureDownloaded;
+@property (nonatomic) ArticleStatus status;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Vienna/Sources/Models/Article.m b/Vienna/Sources/Models/Article.m
index a48f0dc314..6215e34b1d 100644
--- a/Vienna/Sources/Models/Article.m
+++ b/Vienna/Sources/Models/Article.m
@@ -45,39 +45,15 @@
@implementation Article {
NSMutableDictionary *articleData;
- BOOL readFlag;
- BOOL revisedFlag;
- BOOL markedFlag;
- BOOL deletedFlag;
- BOOL enclosureDownloadedFlag;
- BOOL hasEnclosureFlag;
- NSInteger status;
}
-- (instancetype)init
+- (instancetype)initWithGUID:(NSString *)guid
{
self = [super init];
if (self) {
+ _guid = [guid copy];
+ _folderId = -1;
articleData = [[NSMutableDictionary alloc] init];
- readFlag = NO;
- revisedFlag = NO;
- markedFlag = NO;
- deletedFlag = NO;
- hasEnclosureFlag = NO;
- enclosureDownloadedFlag = NO;
- status = ArticleStatusEmpty;
- self.folderId = -1;
- self.parentId = 0;
- }
- return self;
-}
-
-/* initWithGuid
- */
--(instancetype)initWithGuid:(NSString *)theGuid
-{
- if ((self = [self init]) != nil) {
- self.guid = theGuid;
}
return self;
}
@@ -139,48 +115,6 @@ -(void)setEnclosure:(NSString *)enclosure
}
}
-/* markEnclosureDownloaded
- */
--(void)markEnclosureDownloaded:(BOOL)flag
-{
- enclosureDownloadedFlag = flag;
-}
-
-/* setHasEnclosure
- */
--(void)setHasEnclosure:(BOOL)flag
-{
- hasEnclosureFlag = flag;
-}
-
-/* markRead
- */
--(void)markRead:(BOOL)flag
-{
- readFlag = flag;
-}
-
-/* markRevised
- */
--(void)markRevised:(BOOL)flag
-{
- revisedFlag = flag;
-}
-
-/* markFlagged
- */
--(void)markFlagged:(BOOL)flag
-{
- markedFlag = flag;
-}
-
-/* markDeleted
- */
--(void)markDeleted:(BOOL)flag
-{
- deletedFlag = flag;
-}
-
/* accessInstanceVariablesDirectly
* Override this so that KVC doesn't get the articleData ivar
*/
@@ -218,18 +152,8 @@ -(id)valueForKeyPath:(NSString *)keyPath
/* Accessor functions
*/
--(BOOL)isRead { return readFlag; }
--(BOOL)isRevised { return revisedFlag; }
--(BOOL)isFlagged { return markedFlag; }
--(BOOL)isDeleted { return deletedFlag; }
--(BOOL)hasEnclosure { return hasEnclosureFlag; }
--(BOOL)enclosureDownloaded { return enclosureDownloadedFlag; }
--(NSInteger)status { return status; }
--(NSInteger)folderId { return [articleData[MA_Field_Folder] integerValue]; }
-(NSString *)author { return articleData[MA_Field_Author]; }
-(NSString *)link { return articleData[MA_Field_Link]; }
--(NSString *)guid { return articleData[MA_Field_GUID]; }
--(NSInteger)parentId { return [articleData[MA_Field_Parent] integerValue]; }
-(NSString *)title { return articleData[MA_Field_Subject]; }
-(NSString *)summary
{
@@ -255,34 +179,6 @@ -(Folder *)containingFolder
return [[Database sharedManager] folderFromID:self.folderId];
}
-/* setFolderId
- */
--(void)setFolderId:(NSInteger)newFolderId
-{
- articleData[MA_Field_Folder] = @(newFolderId);
-}
-
-/* setGuid
- */
--(void)setGuid:(NSString *)newGuid
-{
- articleData[MA_Field_GUID] = [newGuid copy];
-}
-
-/* setParentId
- */
--(void)setParentId:(NSInteger)newParentId
-{
- articleData[MA_Field_Parent] = @(newParentId);
-}
-
-/* setStatus
- */
--(void)setStatus:(NSInteger)newStatus
-{
- status = newStatus;
-}
-
/* description
* Return a human readable description of this article for debugging.
*/
diff --git a/Vienna/Sources/Models/Folder.m b/Vienna/Sources/Models/Folder.m
index 7c4d7262d2..420be404a0 100644
--- a/Vienna/Sources/Models/Folder.m
+++ b/Vienna/Sources/Models/Folder.m
@@ -504,14 +504,14 @@ -(BOOL)createArticle:(Article *)article guidHistory:(NSArray *)guidHistory
NSString * guid = article.guid;
[self.cachedArticles setObject:article forKey:guid];
[self.cachedGuids addObject:guid];
- if(!article.read) {
+ if(!article.isRead) {
adjustment = 1;
}
} else {
return NO;
}
}
- } else if (existingArticle.deleted) {
+ } else if (existingArticle.isDeleted) {
return NO;
} else if (![[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles]) {
return NO;
@@ -519,10 +519,10 @@ -(BOOL)createArticle:(Article *)article guidHistory:(NSArray *)guidHistory
BOOL success = [[Database sharedManager] updateArticle:existingArticle ofFolder:self.itemId withArticle:article];
if (success) {
// Update folder unread count if necessary
- if (existingArticle.read) {
+ if (existingArticle.isRead) {
adjustment = 1;
article.status = ArticleStatusNew;
- [existingArticle markRead:NO];
+ existingArticle.read = NO;
} else {
article.status = ArticleStatusUpdated;
}
@@ -638,8 +638,8 @@ -(void)markArticlesInCacheRead
// so it makes the code slightly faster.
for (id obj in self.cachedGuids.reverseObjectEnumerator.allObjects) {
Article * article = [self.cachedArticles objectForKey:(NSString *)obj];
- if (!article.read) {
- [article markRead:YES];
+ if (!article.isRead) {
+ article.read = YES;
count--;
if (count == 0) {
break;
@@ -682,7 +682,7 @@ -(void)resetArticleStatuses
NSMutableArray * result = [NSMutableArray arrayWithCapacity:unreadCount];
for (id obj in self.cachedGuids.reverseObjectEnumerator.allObjects) {
Article * article = [self.cachedArticles objectForKey:(NSString *)obj];
- if (!article.read) {
+ if (!article.isRead) {
[result addObject:[ArticleReference makeReference:article]];
count--;
if (count == 0) {