Просмотр исходного кода

Add Ruby and Swift linters and PR template

Add Swift and Ruby linters
Define PR template for GitHub
Define lint lane
Add lint step to circleci
Fix linter issues in Ruby and Swift code
David Cordero 7 лет назад
Родитель
Сommit
fad3d6879c

+ 10 - 0
.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,10 @@
+<!-- Thanks for contributing to _vlc-ios_! Before you submit your pull request, please make sure to check the following boxes by putting an x in the [ ] (don't: [x ], [ x], do: [x]) -->
+
+### Checklist
+- [ ] I've run `bundle exec fastlane test` from the root directory to see all new and existing tests pass
+- [ ] I've followed the [vlc-ios code style](Docs/CodingStyle.md) and run `bundle exec fastlane lint` to ensure the code style is valid
+- [ ] I've read the [Contribution Guidelines](https://github.com/videolan/vlc-ios#contribute)
+- [ ] I've updated the documentation if necessary.
+
+### Description
+<!-- Describe your changes in detail -->

+ 26 - 0
.rubocop.yml

@@ -0,0 +1,26 @@
+AllCops:
+  Include:
+    - '**/fastlane/Fastfile'
+  Exclude:
+    - Gemfile
+    - Podfile
+    - '**/Pods'
+    - '**/fastlane/Snapfile'
+
+Documentation:
+  Enabled: false
+
+Style/FrozenStringLiteralComment:
+  Enabled: false
+
+Metrics/AbcSize:
+  Max: 20
+
+Metrics/MethodLength:
+  Max: 30
+
+Metrics/BlockLength:
+  Max: 30
+
+Metrics/LineLength:
+  Max: 250

+ 33 - 0
.swiftlint.yml

@@ -0,0 +1,33 @@
+whitelist_rules:
+  - closing_brace
+  - colon
+  - comma
+  - control_statement
+  - custom_rules
+  - empty_count
+  - leading_whitespace
+  - legacy_cggeometry_functions
+  - legacy_constant
+  - legacy_constructor
+  - mark
+  - opening_brace
+  - operator_whitespace
+  - private_unit_test
+  - redundant_nil_coalesing
+  - redundant_string_enum_value
+  - return_arrow_whitespace
+  - syntactic_sugar
+  - trailing_semicolon
+  - void_return
+
+excluded:
+  - Pods
+  - .bundle
+
+colon:
+  apply_to_dictionaries: false
+
+custom_rules:
+  equal_sign_whitespace:
+    message: "Expected only one space before and after ="
+    regex: "(([ ]{2,}=)|(=[ ]{2,}))"

+ 0 - 212
Docs/Coding Style.rtf

@@ -1,212 +0,0 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
-\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Monaco;}
-{\colortbl;\red255\green255\blue255;\red0\green134\blue2;\red195\green0\blue0;}
-\paperw12240\paperh15840\vieww18380\viewh12620\viewkind0
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\qc
-
-\f0\fs36 \cf0 Coding Rules\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
-
-\fs24 \cf0 \
-
-\fs28 Cocoa coding style for the naming.\
-\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f1\fs20 \cf0 variableNaming
-\f0\fs28  variable should use capitalization on all word expect the first and never '_' ie\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 BOOL isFirstTimeReading;\
-int age;\
-
-\f0\fs24 \
-
-\b \cf3 WRONG\
-
-\f1\b0\fs18 \cf0 BOOL is_first_time_reading;\
-int Age;\
-int isFirstTimeReading_ever;\
-\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f0\fs28 \cf0 Objective-C Instance variable must be prefixed with _\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 @interface Object \{\
-	  BOOL _isFirstTimeReading;\
-	  int _age;\
-\}\
-
-\f0\fs24 \
-
-\b \cf3 WRONG\
-
-\f1\b0\fs18 \cf0 @interface Object \{\
-	  BOOL isFirstTimeReading;\
-	  int age;\
-\}
-\f0\fs28 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
-
-\fs24 \cf0 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f1\fs20 \cf0 Pointer *
-\f0\fs28  must be preceded with a space and with no space after ie\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 void *pointer;\
-
-\f0\fs24 \
-
-\b \cf3 WRONG\
-
-\f1\b0\fs18 \cf0 void * pointer;\
-void* pointer;\
-void*pointer;\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
-
-\f0\fs24 \cf0 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f1\fs20 \cf0 if
-\f0\fs28 , 
-\f1\fs18 switch
-\f0\fs28 , and other keyword that are not function but takes parameter should have a space before ()\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 if (a) \{\
-  ...\
-\}\
-function();\
-
-\f0\fs24 \
-
-\b \cf3 WRONG\
-
-\f1\b0\fs18 \cf0 if( a )\
-if ( a )\
-if(a)\
-function ();\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
-
-\f0\fs24 \cf0 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f1\fs18 \cf0 \{\}
-\f0\fs28  usage\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 if (a) \{\
-   ...\
-\}\
-while (a) \{\
-   ...\
-\}\
-void function()\
-\{\
-   ...\
-\}\
-- (void)functionWithParameter:(BOOL)parameter\
-\{\
-   ...\
-\}\
-
-\f0\b\fs24 \cf3 WRONG
-\b0 \cf0 \
-
-\f1\fs18 - (void)function \{\
-   ...\
-\}\
-if (a)\
-\{\
-   ...\
-\}\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
-
-\f0\fs24 \cf0 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\fs28 \cf0 Prefer early 
-\f1\fs18 return
-\f0\fs28  ie:\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\b\fs24 \cf2 PREFER\
-
-\f1\b0\fs18 \cf0 if (!a)\
-    return;\
-
-\f0\fs24 \
-
-\b \cf3 OVER\
-
-\f1\b0\fs18 \cf0 if (a) \{\
-  ...\
-  ...\
-\}\
-
-\f0\fs24 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\fs28 \cf0 Objective C code - Don't call multiply the same method\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 NSWindow *window = [self window];\
-NSRect frame = [window frame];\
-frame.origin.x = 0;\
-[window setFrame:frame display:NO];\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\f0\b\fs24 \cf3 WRONG\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\f1\b0\fs18 \cf0 NSRect frame = [[self window] frame];\
-frame.origin.x = 0;\
-[[self window] setFrame:frame display:NO];\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f0\fs28 \cf0 objectAtIndex is gone - keep it like this\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 NSArray *array;\
-\'85filled with lots of stuff\
-id object = array[index];\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\f0\b\fs24 \cf3 WRONG\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\f1\b0\fs18 \cf0 NSArray *array;\
-\'85filled with lots of stuff\
-id object = [array objectAtIndex:index];\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\sl480\slmult1\pardirnatural
-
-\f0\fs28 \cf0 NSArray literals improve readability - use them\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\b\fs24 \cf2 RIGHT\
-
-\f1\b0\fs18 \cf0 NSArray *array = @[obj1, obj2, obj3];\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\fi540\pardirnatural
-
-\f0\b\fs24 \cf3 WRONG\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li540\pardirnatural
-
-\f1\b0\fs18 \cf0 NSArray *array = [NSArray arrayWithObjects: obj1, obj2, obj3, nil];\
-}

+ 170 - 0
Docs/CodingStyle.md

@@ -0,0 +1,170 @@
+# Coding Rules
+
+This document defines Swift and Objective-C code style rules for this project.
+
+## Table of Contents
+* [Swift](#swift)
+* [Objective-C](#objective-c)
+# Objective-c code style
+
+## Swift
+
+The swift code style rules are defined by [this set of swiftlint rules](../.swiftlint.yml)
+
+## Objective-C
+
+Variable names should use capitalization on all word expect the first, and never '_' ie
+
+**Right:**
+```obj-c
+BOOL isFirstTimeReading;
+int age;
+NSArray *myArray;
+```
+
+**Wrong:**
+```objc-c
+BOOL is_first_time_reading;
+int Age;
+int isFirstTimeReading_ever;
+```
+
+Objective-C Instance variables must be prefixed with _
+
+**Right:**
+```obj-c
+@interface Object {
+	  BOOL _isFirstTimeReading;
+	  int _age;
+}
+```
+
+**Wrong:**
+```objc-c
+@interface Object {
+	  BOOL isFirstTimeReading;
+	  int age;
+}
+```
+
+Pointer * must be preceded with a space and with no space after ie
+
+**Right:**
+```obj-c
+void *pointer;
+```
+
+**Wrong:**
+```objc-c
+void * pointer;
+void* pointer;
+void*pointer;
+```
+
+If, switch, and other keyword that are not function but takes parameter should have a space before ()
+
+**Right:**
+```obj-c
+if (a) {
+  ...
+}
+function();
+```
+
+**Wrong:**
+```objc-c
+if( a )
+if ( a )
+if(a)
+function ();
+```
+
+Brackets usage
+
+**Right:**
+```obj-c
+if (a) {
+   ...
+}
+while (a) {
+   ...
+}
+void function()
+{
+   ...
+}
+- (void)functionWithParameter:(BOOL)parameter
+{
+   ...
+}
+```
+
+**Wrong:**
+```objc-c
+- (void)function {
+   ...
+}
+if (a)
+{
+   ...
+}
+```
+
+Prefer early return ie:
+
+**Prefer:**
+```obj-c
+if (!a)
+    return;
+```
+
+**Over:**
+```objc-c
+if (a) {
+  ...
+  ...
+}
+```
+
+Objective C code - Don't call multiply the same method.
+
+**Right:**
+```obj-c
+NSWindow *window = [self window];
+NSRect frame = [window frame];
+frame.origin.x = 0;
+[window setFrame:frame display:NO];
+```
+
+**Wrong:**
+```objc-c
+NSRect frame = [[self window] frame];
+frame.origin.x = 0;
+[[self window] setFrame:frame display:NO];
+objectAtIndex is gone - keep it like this
+```
+
+**Right:**
+```obj-c
+NSArray *array;
+…filled with lots of stuff
+id object = array[index];
+```
+
+**Wrong:**
+```objc-c
+NSArray *array;
+…filled with lots of stuff
+id object = [array objectAtIndex:index];
+NSArray literals improve readability - use them
+```
+
+**Right:**
+```obj-c
+NSArray *array = @[obj1, obj2, obj3];
+```
+
+**Wrong:**
+```objc-c
+NSArray *array = [NSArray arrayWithObjects: obj1, obj2, obj3, nil];
+```

+ 9 - 5
Gemfile

@@ -1,6 +1,10 @@
-source "https://rubygems.org"
+source 'https://rubygems.org'
 
-gem 'fastlane', '2.82.0'
-gem 'cocoapods', '1.4.0'
-gem 'xcode-install', '2.3.1'
-gem 'xcodeproj', '1.5.6'
+gem 'cocoapods', '~> 1.4.0'
+gem 'fastlane', '~> 2.82.0'
+gem 'rubocop', '~> 0.54.0'
+gem 'xcode-install', '~> 2.3.1'
+gem 'xcodeproj', '~> 1.5.6'
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)

+ 32 - 10
Gemfile.lock

@@ -1,7 +1,7 @@
 GEM
   remote: https://rubygems.org/
   specs:
-    CFPropertyList (2.3.6)
+    CFPropertyList (3.0.0)
     activesupport (4.2.10)
       i18n (~> 0.7)
       minitest (~> 5.1)
@@ -9,6 +9,7 @@ GEM
       tzinfo (~> 1.1)
     addressable (2.5.2)
       public_suffix (>= 2.0.2, < 4.0)
+    ast (2.4.0)
     atomos (0.1.2)
     babosa (1.0.2)
     claide (1.0.2)
@@ -56,7 +57,7 @@ GEM
       unf (>= 0.0.5, < 1.0.0)
     dotenv (2.2.1)
     escape (0.0.4)
-    excon (0.60.0)
+    excon (0.62.0)
     faraday (0.14.0)
       multipart-post (>= 1.2, < 3)
     faraday-cookie_jar (0.0.6)
@@ -99,9 +100,10 @@ GEM
       xcodeproj (>= 1.5.2, < 2.0.0)
       xcpretty (>= 0.2.4, < 1.0.0)
       xcpretty-travis-formatter (>= 0.0.3)
+    fastlane-plugin-ruby (0.1.3)
     fourflusher (2.0.1)
     fuzzy_match (2.0.4)
-    gh_inspector (1.1.2)
+    gh_inspector (1.1.3)
     google-api-client (0.13.6)
       addressable (~> 2.5, >= 2.5.1)
       googleauth (~> 0.5)
@@ -135,23 +137,36 @@ GEM
     mime-types-data (3.2016.0521)
     mini_magick (4.5.1)
     minitest (5.11.3)
-    molinillo (0.6.4)
+    molinillo (0.6.5)
     multi_json (1.13.1)
     multi_xml (0.6.0)
     multipart-post (2.0.0)
-    nanaimo (0.2.3)
+    nanaimo (0.2.4)
     nap (1.1.0)
     netrc (0.11.0)
     os (0.9.6)
+    parallel (1.12.1)
+    parser (2.5.0.5)
+      ast (~> 2.4.0)
     plist (3.4.0)
+    powerpack (0.1.1)
     public_suffix (2.0.5)
+    rainbow (3.0.0)
     representable (3.0.4)
       declarative (< 0.1.0)
       declarative-option (< 0.2.0)
       uber (< 0.2.0)
     retriable (3.1.1)
     rouge (2.0.7)
+    rubocop (0.54.0)
+      parallel (~> 1.10)
+      parser (>= 2.5)
+      powerpack (~> 0.1)
+      rainbow (>= 2.2.2, < 4.0)
+      ruby-progressbar (~> 1.7)
+      unicode-display_width (~> 1.0, >= 1.0.1)
     ruby-macho (1.1.0)
+    ruby-progressbar (1.9.0)
     rubyzip (1.2.1)
     security (0.1.3)
     signet (0.8.1)
@@ -176,12 +191,15 @@ GEM
     unf_ext (0.0.7.5)
     unicode-display_width (1.3.0)
     word_wrap (1.0.0)
-    xcodeproj (1.5.6)
-      CFPropertyList (~> 2.3.3)
+    xcode-install (2.3.1)
+      claide (>= 0.9.1, < 1.1.0)
+      fastlane (>= 2.1.0, < 3.0.0)
+    xcodeproj (1.5.7)
+      CFPropertyList (>= 2.3.3, < 4.0)
       atomos (~> 0.1.2)
       claide (>= 1.0.2, < 2.0)
       colored2 (~> 3.1)
-      nanaimo (~> 0.2.3)
+      nanaimo (~> 0.2.4)
     xcpretty (0.2.8)
       rouge (~> 2.0.7)
     xcpretty-travis-formatter (1.0.0)
@@ -191,8 +209,12 @@ PLATFORMS
   ruby
 
 DEPENDENCIES
-  cocoapods (= 1.4.0)
-  fastlane (= 2.82.0)
+  cocoapods (~> 1.4.0)
+  fastlane (~> 2.82.0)
+  fastlane-plugin-ruby
+  rubocop (~> 0.54.0)
+  xcode-install (~> 2.3.1)
+  xcodeproj (~> 1.5.6)
 
 BUNDLED WITH
    1.16.1

+ 1 - 0
Podfile

@@ -10,6 +10,7 @@ def shared_pods
   pod 'VLC-WhiteRaccoon'
   pod 'VLC-LiveSDK', '5.7.0x'
   pod 'ObjectiveDropboxOfficial', :git => 'git://github.com/carolanitz/dropbox-sdk-obj-c.git' #update ios platform version
+  pod 'SwiftLint', '~> 0.25.0'
 end
 
 def iOS_pods

+ 4 - 1
Podfile.lock

@@ -52,6 +52,7 @@ PODS:
     - xmlrpc
   - PAPasscode (1.0)
   - RESideMenu (4.0.7)
+  - SwiftLint (0.25.0)
   - TVVLCKit (3.0.2)
   - upnpx (1.4.0)
   - VLC-LiveSDK (5.7.0x)
@@ -79,6 +80,7 @@ DEPENDENCIES:
   - OROpenSubtitleDownloader (from `https://github.com/orta/OROpenSubtitleDownloader.git`, commit `0509eac2`)
   - PAPasscode (~> 1.0)
   - RESideMenu (~> 4.0.7)
+  - SwiftLint (~> 0.25.0)
   - TVVLCKit (= 3.0.2)
   - upnpx (~> 1.4.0)
   - VLC-LiveSDK (= 5.7.0x)
@@ -139,6 +141,7 @@ SPEC CHECKSUMS:
   OROpenSubtitleDownloader: 154b8c08acbf8836b77ac259018dc8b5baef907e
   PAPasscode: b408fb87c530cad58a554e26482e87dbb14b7bc2
   RESideMenu: f24c508404b49c667344c54aba7e590883533958
+  SwiftLint: e14651157288e9e01d6e1a71db7014fb5744a8ea
   TVVLCKit: 178e4f82f8b57320774821384e42eaac403d2faa
   upnpx: c695b99229e08154d23abe5c252cb64f1600f35d
   VLC-LiveSDK: c9566a9edde968f969138f84cfd40b540a109b3f
@@ -147,6 +150,6 @@ SPEC CHECKSUMS:
   XKKeychain: 852ef663c56a7194c73d3c68e8d9d4f07b121d4f
   xmlrpc: 109bb21d15ed6d108b2c1ac5973a6a223a50f5f4
 
-PODFILE CHECKSUM: 6a912f6ba8819dae74bb05d7a721fd2430785700
+PODFILE CHECKSUM: 7049ed97875cfde471396ccb609af0afd165ef7d
 
 COCOAPODS: 1.4.0

+ 3 - 3
SharedSources/Coordinators/AppCoordinator.swift

@@ -12,14 +12,14 @@
 import Foundation
 
 @objc(VLCService)
-public class Services:NSObject {
+public class Services: NSObject {
     @objc let mediaDataSource = VLCMediaDataSource()
 }
 
-@objc class AppCoordinator : NSObject {
+@objc class AppCoordinator: NSObject {
 
     var childCoordinators: [NSObject] = []
-    private var tabBarController:UITabBarController
+    private var tabBarController: UITabBarController
     private var services = Services()
 
     @objc public init(tabBarController: UITabBarController) {

+ 1 - 1
SharedSources/Coordinators/SortOption.swift

@@ -10,7 +10,7 @@
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
-public enum SortOption:String {
+public enum SortOption: String {
     case alphabetically = "Name"
     case insertonDate = "Date"
     case size = "Size"

+ 6 - 6
SharedSources/MediaDataSource.swift

@@ -10,13 +10,13 @@
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
-public class MediaDataSourceAndDelegate:NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
+public class MediaDataSourceAndDelegate: NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
 
-    private let cellPadding:CGFloat = 5.0
+    private let cellPadding: CGFloat = 5.0
     private var services: Services
     public weak var delegate: UICollectionViewDelegate?
 
-    public convenience init(services:Services) {
+    public convenience init(services: Services) {
         self.init()
         self.services = services
     }
@@ -44,8 +44,8 @@ public class MediaDataSourceAndDelegate:NSObject, UICollectionViewDataSource, UI
 
     public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
 
-        let numberOfCells:CGFloat =  collectionView.traitCollection.horizontalSizeClass == .regular ? 3.0 : 2.0
-        let aspectRatio:CGFloat = 10.0 / 16.0
+        let numberOfCells: CGFloat = collectionView.traitCollection.horizontalSizeClass == .regular ? 3.0 : 2.0
+        let aspectRatio: CGFloat = 10.0 / 16.0
 
         // We have the number of cells and we always have numberofCells + 1 padding spaces. -pad-[Cell]-pad-[Cell]-pad-
         // we then have the entire padding, we divide the entire padding by the number of Cells to know how much needs to be substracted from ech cell
@@ -57,7 +57,7 @@ public class MediaDataSourceAndDelegate:NSObject, UICollectionViewDataSource, UI
     }
 
     public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
-        return UIEdgeInsetsMake(cellPadding, cellPadding, cellPadding, cellPadding);
+        return UIEdgeInsets(top: cellPadding, left: cellPadding, bottom: cellPadding, right: cellPadding)
     }
 
     public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {

+ 30 - 31
SharedSources/PresentationTheme.swift

@@ -16,39 +16,39 @@ extension Notification.Name {
     static let VLCThemeDidChangeNotification = Notification.Name("themeDidChangeNotfication")
 }
 
-@objcMembers public class ColorPalette : NSObject {
+@objcMembers public class ColorPalette: NSObject {
 
     public let isDark: Bool
     public let name: String
-    public let background:UIColor
-    public let cellBackgroundA:UIColor
-    public let cellBackgroundB:UIColor
-    public let cellDetailTextColor:UIColor
-    public let cellTextColor:UIColor
-    public let lightTextColor:UIColor
-    public let sectionHeaderTextColor:UIColor
-    public let sectionHeaderTintColor:UIColor
-    public let settingsBackground:UIColor
-    public let settingsCellBackground:UIColor
-    public let settingsSeparatorColor:UIColor
-    public let tabBarColor:UIColor
-    public let orangeUI:UIColor
+    public let background: UIColor
+    public let cellBackgroundA: UIColor
+    public let cellBackgroundB: UIColor
+    public let cellDetailTextColor: UIColor
+    public let cellTextColor: UIColor
+    public let lightTextColor: UIColor
+    public let sectionHeaderTextColor: UIColor
+    public let sectionHeaderTintColor: UIColor
+    public let settingsBackground: UIColor
+    public let settingsCellBackground: UIColor
+    public let settingsSeparatorColor: UIColor
+    public let tabBarColor: UIColor
+    public let orangeUI: UIColor
 
     public init(isDark: Bool,
                 name: String,
-                background:UIColor,
-                cellBackgroundA:UIColor,
-                cellBackgroundB:UIColor,
-                cellDetailTextColor:UIColor,
-                cellTextColor:UIColor,
-                lightTextColor:UIColor,
-                sectionHeaderTextColor:UIColor,
-                sectionHeaderTintColor:UIColor,
-                settingsBackground:UIColor,
-                settingsCellBackground:UIColor,
-                settingsSeparatorColor:UIColor,
-                tabBarColor:UIColor,
-                orangeUI:UIColor) {
+                background: UIColor,
+                cellBackgroundA: UIColor,
+                cellBackgroundB: UIColor,
+                cellDetailTextColor: UIColor,
+                cellTextColor: UIColor,
+                lightTextColor: UIColor,
+                sectionHeaderTextColor: UIColor,
+                sectionHeaderTintColor: UIColor,
+                settingsBackground: UIColor,
+                settingsCellBackground: UIColor,
+                settingsSeparatorColor: UIColor,
+                tabBarColor: UIColor,
+                orangeUI: UIColor) {
         self.isDark = isDark
         self.name = name
         self.background = background
@@ -67,7 +67,7 @@ extension Notification.Name {
     }
 }
 
-@objcMembers public class PresentationTheme : NSObject {
+@objcMembers public class PresentationTheme: NSObject {
 
     public static let brightTheme = PresentationTheme(colors: brightPalette)
     public static let darkTheme = PresentationTheme(colors: darkPalette)
@@ -75,8 +75,7 @@ extension Notification.Name {
     static var current: PresentationTheme = {
         let isDarkTheme = UserDefaults.standard.bool(forKey: kVLCSettingAppTheme)
         return isDarkTheme ? PresentationTheme.darkTheme : PresentationTheme.brightTheme
-        }()
-        {
+        }() {
         didSet {
             NotificationCenter.default.post(name: .VLCThemeDidChangeNotification, object: self)
             AppearanceManager.setupAppearance(theme: self.current)
@@ -91,7 +90,7 @@ extension Notification.Name {
 
 @objc public extension UIColor {
 
-    public convenience init(_ rgbValue:UInt32, _ alpha:CGFloat = 1.0) {
+    public convenience init(_ rgbValue: UInt32, _ alpha: CGFloat = 1.0) {
         let r = CGFloat((rgbValue & 0xFF0000) >> 16)/255.0
         let g = CGFloat((rgbValue & 0xFF00) >> 8)/255.0
         let b = CGFloat(rgbValue & 0xFF)/255.0

+ 3 - 4
Sources/AppearanceManager.swift

@@ -12,10 +12,9 @@
 import UIKit
 
 @objc(VLCApperanceManager)
-class AppearanceManager:NSObject
-{
-    @objc class func setupAppearance(theme:PresentationTheme = PresentationTheme.current)
-    {
+class AppearanceManager: NSObject {
+
+    @objc class func setupAppearance(theme: PresentationTheme = PresentationTheme.current) {
         // Change the keyboard for UISearchBar
         UITextField.appearance().keyboardAppearance = theme == PresentationTheme.darkTheme ? .dark : .light
         // For the cursor

+ 13 - 13
Sources/KeychainCoordinator.swift

@@ -14,16 +14,16 @@ import Foundation
 import LocalAuthentication
 
 @objc(VLCKeychainCoordinator)
-class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
+class KeychainCoordinator: NSObject, PAPasscodeViewControllerDelegate {
 
-    @objc class var passcodeLockEnabled:Bool {
+    @objc class var passcodeLockEnabled: Bool {
         return UserDefaults.standard.bool(forKey:kVLCSettingPasscodeOnKey)
     }
 
     //Since FaceID and TouchID are both set to 1 when the defaults are registered
     //we have to double check for the biometry type to not return true even though the setting is not visible
     //and that type is not supported by the device
-    private var touchIDEnabled:Bool {
+    private var touchIDEnabled: Bool {
         var touchIDEnabled = UserDefaults.standard.bool(forKey:kVLCSettingPasscodeAllowTouchID)
         let laContext = LAContext()
 
@@ -32,7 +32,7 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
         }
         return touchIDEnabled
     }
-    private var faceIDEnabled:Bool {
+    private var faceIDEnabled: Bool {
         var faceIDEnabled = UserDefaults.standard.bool(forKey:kVLCSettingPasscodeAllowFaceID)
         let laContext = LAContext()
 
@@ -44,11 +44,11 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
 
     static let passcodeService = "org.videolan.vlc-ios.passcode"
 
-    var completion: (() -> ())? = nil
+    var completion: (() -> Void)? = nil
 
     private var avoidPromptingTouchOrFaceID = false
 
-    private lazy var passcodeLockController:PAPasscodeViewController = {
+    private lazy var passcodeLockController: PAPasscodeViewController = {
         let passcodeController = PAPasscodeViewController(for: PasscodeActionEnter)
         passcodeController!.delegate = self
         return passcodeController!
@@ -59,7 +59,7 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
         NotificationCenter.default.addObserver(self, selector: #selector(appInForeground), name: .UIApplicationDidBecomeActive, object: nil)
     }
 
-    @objc class func setPasscode(passcode:String?) throws {
+    @objc class func setPasscode(passcode: String?) throws {
         guard let passcode = passcode else {
             do {
                 try XKKeychainGenericPasswordItem.removeItems(forService: passcodeService)
@@ -79,7 +79,7 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
         }
     }
 
-    @objc func validatePasscode(completion:@escaping ()->()) {
+    @objc func validatePasscode(completion: @escaping () -> Void) {
         passcodeLockController.passcode = passcodeFromKeychain()
         self.completion = completion
         guard let rootViewController = UIApplication.shared.delegate?.window??.rootViewController, passcodeLockController.passcode != "" else {
@@ -97,13 +97,13 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
 
         rootViewController.present(navigationController, animated: true) {
             [weak self] in
-            if (self?.touchIDEnabled == true || self?.faceIDEnabled == true) {
+            if self?.touchIDEnabled == true || self?.faceIDEnabled == true {
                 self?.touchOrFaceIDQuery()
             }
         }
     }
 
-    @objc private func appInForeground(notification:Notification) {
+    @objc private func appInForeground(notification: Notification) {
         if let navigationController = UIApplication.shared.delegate?.window??.rootViewController?.presentedViewController as? UINavigationController, navigationController.topViewController is PAPasscodeViewController,
             touchIDEnabled || faceIDEnabled {
             touchOrFaceIDQuery()
@@ -111,13 +111,13 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
     }
 
     private func touchOrFaceIDQuery() {
-        if (avoidPromptingTouchOrFaceID || UIApplication.shared.applicationState != .active) {
+        if avoidPromptingTouchOrFaceID || UIApplication.shared.applicationState != .active {
             return
         }
 
         let laContext = LAContext()
 
-        if laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil){
+        if laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
             avoidPromptingTouchOrFaceID = true
             laContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
                                      localizedReason: NSLocalizedString("BIOMETRIC_UNLOCK", comment: ""),
@@ -146,7 +146,7 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
         return ""
     }
 
-    //MARK: PAPassCodeDelegate
+    // MARK: PAPassCodeDelegate
     func paPasscodeViewControllerDidEnterPasscode(_ controller: PAPasscodeViewController!) {
         avoidPromptingTouchOrFaceID = false
         UIApplication.shared.delegate?.window??.rootViewController?.dismiss(animated: true, completion: {

+ 2 - 2
Sources/LayoutAnchorContainer.swift

@@ -25,6 +25,6 @@ import Foundation
     var centerYAnchor: NSLayoutYAxisAnchor { get }
 }
 
-extension UIView:LayoutAnchorContainer {}
+extension UIView: LayoutAnchorContainer {}
 
-extension UILayoutGuide:LayoutAnchorContainer {}
+extension UILayoutGuide: LayoutAnchorContainer {}

+ 2 - 2
Sources/LocalNetworkConnectivity/RemoteNetworkDataSource.swift

@@ -12,14 +12,14 @@
 import Foundation
 
 @objc(VLCRemoteNetworkDataSource)
-public class RemoteNetworkDataSource:NSObject, UITableViewDataSource {
+public class RemoteNetworkDataSource: NSObject, UITableViewDataSource {
 
     public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return 1
     }
     
     public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        if let wifiCell =  tableView.dequeueReusableCell(withIdentifier: VLCWiFiUploadTableViewCell.cellIdentifier()) {
+        if let wifiCell = tableView.dequeueReusableCell(withIdentifier: VLCWiFiUploadTableViewCell.cellIdentifier()) {
             return wifiCell
         }
         return UITableViewCell()

+ 10 - 11
Sources/MediaViewController.swift

@@ -13,26 +13,25 @@
 import Foundation
 
 @objc public protocol VLCMediaViewControllerDelegate: class {
-    func mediaViewControllerDidSelectMediaObject(_ mediaViewController: VLCMediaViewController, mediaObject:NSManagedObject)
+    func mediaViewControllerDidSelectMediaObject(_ mediaViewController: VLCMediaViewController, mediaObject: NSManagedObject)
     func mediaViewControllerDidSelectSort(_ mediaViewController: VLCMediaViewController)
 }
 
-public class VLCMediaViewController: UICollectionViewController, UISearchResultsUpdating, UISearchControllerDelegate
-{
+public class VLCMediaViewController: UICollectionViewController, UISearchResultsUpdating, UISearchControllerDelegate {
     private var services: Services
-    private var mediaDatasourceAndDelegate:MediaDataSourceAndDelegate?
+    private var mediaDatasourceAndDelegate: MediaDataSourceAndDelegate?
     private var searchController: UISearchController?
     private let searchDataSource = VLCLibrarySearchDisplayDataSource()
     public weak var delegate: VLCMediaViewControllerDelegate?
 
     @available(iOS 11.0, *)
-    lazy var dragAndDropManager:VLCDragAndDropManager = {
+    lazy var dragAndDropManager: VLCDragAndDropManager = {
         let dragAndDropManager = VLCDragAndDropManager()
         dragAndDropManager.delegate = services.mediaDataSource
         return dragAndDropManager
     }()
 
-    public convenience init(services:Services) {
+    public convenience init(services: Services) {
         self.init(collectionViewLayout: UICollectionViewFlowLayout())
         self.services = services
         NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .VLCThemeDidChangeNotification, object: nil)
@@ -60,7 +59,7 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
         collectionView?.backgroundColor = PresentationTheme.current.colors.background
     }
 
-    func setupCollectionView(){
+    func setupCollectionView() {
         mediaDatasourceAndDelegate = MediaDataSourceAndDelegate(services: services)
         mediaDatasourceAndDelegate?.delegate = self
         let playlistnib = UINib(nibName: "VLCPlaylistCollectionViewCell", bundle:nil)
@@ -91,8 +90,8 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
         if let textfield = searchController?.searchBar.value(forKey: "searchField") as? UITextField {
             if let backgroundview = textfield.subviews.first {
                 backgroundview.backgroundColor = UIColor.white
-                backgroundview.layer.cornerRadius = 10;
-                backgroundview.clipsToBounds = true;
+                backgroundview.layer.cornerRadius = 10
+                backgroundview.clipsToBounds = true
             }
         }
         if #available(iOS 11.0, *) {
@@ -115,12 +114,12 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
         collectionView?.collectionViewLayout.invalidateLayout()
     }
 
-    //MARK: - MediaDatasourceAndDelegate
+    // MARK: - MediaDatasourceAndDelegate
     override public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         delegate?.mediaViewControllerDidSelectMediaObject(self, mediaObject:services.mediaDataSource.object(at: UInt(indexPath.row)))
     }
 
-    //MARK: - Search
+    // MARK: - Search
     public func updateSearchResults(for searchController: UISearchController) {
         searchDataSource.shouldReloadTable(forSearch: searchController.searchBar.text, searchableFiles: services.mediaDataSource.allObjects())
         collectionView?.reloadData()

+ 41 - 43
Sources/VLCDragAndDropManager.swift

@@ -23,20 +23,19 @@ struct DropError: Error {
     let kind: ErrorKind
 }
 @available(iOS 11.0, *)
-@objc protocol VLCDragAndDropManagerDelegate : NSObjectProtocol {
-    func dragAndDropManagerRequestsFile(manager:VLCDragAndDropManager, atIndexPath indexPath:IndexPath) -> AnyObject?
-    func dragAndDropManagerInsertItem(manager:VLCDragAndDropManager, item:NSManagedObject, atIndexPath indexPath:IndexPath)
-    func dragAndDropManagerDeleteItem(manager:VLCDragAndDropManager, atIndexPath indexPath:IndexPath)
-    func dragAndDropManagerRemoveFileFromFolder(manager:VLCDragAndDropManager, file:NSManagedObject)
-    func dragAndDropManagerCurrentSelection(manager:VLCDragAndDropManager) -> AnyObject?
+@objc protocol VLCDragAndDropManagerDelegate: NSObjectProtocol {
+    func dragAndDropManagerRequestsFile(manager: VLCDragAndDropManager, atIndexPath indexPath: IndexPath) -> AnyObject?
+    func dragAndDropManagerInsertItem(manager: VLCDragAndDropManager, item: NSManagedObject, atIndexPath indexPath: IndexPath)
+    func dragAndDropManagerDeleteItem(manager: VLCDragAndDropManager, atIndexPath indexPath: IndexPath)
+    func dragAndDropManagerRemoveFileFromFolder(manager: VLCDragAndDropManager, file: NSManagedObject)
+    func dragAndDropManagerCurrentSelection(manager: VLCDragAndDropManager) -> AnyObject?
 }
 
 @available(iOS 11.0, *)
-class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableViewDragDelegate, UICollectionViewDropDelegate, UITableViewDropDelegate, UIDropInteractionDelegate
-{
-    @objc weak var delegate:VLCDragAndDropManagerDelegate?
+class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableViewDragDelegate, UICollectionViewDropDelegate, UITableViewDropDelegate, UIDropInteractionDelegate {
+    @objc weak var delegate: VLCDragAndDropManagerDelegate?
 
-    let utiTypeIdentifiers:[String] = VLCDragAndDropManager.supportedTypeIdentifiers()
+    let utiTypeIdentifiers: [String] = VLCDragAndDropManager.supportedTypeIdentifiers()
 
     /// Returns the supported type identifiers that VLC can process.
     /// It fetches the identifiers in LSItemContentTypes from all the CFBundleDocumentTypes in the info.plist.
@@ -44,10 +43,10 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
     ///
     /// - Returns: Array of UTITypeIdentifiers
     private class func supportedTypeIdentifiers() -> [String] {
-        var typeIdentifiers:[String] = []
-        if let documents = Bundle.main.infoDictionary?["CFBundleDocumentTypes"] as? [[String:Any]] {
+        var typeIdentifiers: [String] = []
+        if let documents = Bundle.main.infoDictionary?["CFBundleDocumentTypes"] as? [[String: Any]] {
             for item in documents {
-                if let value = item["LSItemContentTypes"] as? Array<String> {
+                if let value = item["LSItemContentTypes"] as? [String] {
                     typeIdentifiers.append(contentsOf: value)
                 }
             }
@@ -55,17 +54,17 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         return typeIdentifiers
     }
 
-    //MARK: - TableView
+    // MARK: - TableView
     func tableView(_ tableView: UITableView, canHandle session: UIDropSession) -> Bool {
         return canHandleDropSession(session: session)
     }
 
     func tableView(_ tableView: UITableView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem] {
-        return dragItems(forIndexPath:indexPath)
+        return dragItems(forIndexPath: indexPath)
     }
 
     func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
-         return dragItems(forIndexPath:indexPath)
+         return dragItems(forIndexPath: indexPath)
     }
 
     func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
@@ -120,8 +119,8 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         return delegate?.dragAndDropManagerCurrentSelection(manager: self) as? MLLabel != nil
     }
 
-    private func moveItem(tableView:UITableView, item:UITableViewDropItem, toIndexPath destinationPath:IndexPath) {
-        if let mlFile = item.dragItem.localObject as? MLFile, mlFile.labels.count > 0 && !inFolder() {
+    private func moveItem(tableView: UITableView, item: UITableViewDropItem, toIndexPath destinationPath: IndexPath) {
+        if let mlFile = item.dragItem.localObject as? MLFile, !mlFile.labels.isEmpty && !inFolder() {
             tableView.performBatchUpdates({
                 tableView.insertRows(at: [destinationPath], with: .automatic)
                 delegate?.dragAndDropManagerInsertItem(manager: self, item: mlFile, atIndexPath: destinationPath)
@@ -130,7 +129,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    private func addDragItem(tableView:UITableView, dragItem item:UITableViewDropItem, toFolderAt index:IndexPath) {
+    private func addDragItem(tableView: UITableView, dragItem item: UITableViewDropItem, toFolderAt index: IndexPath) {
         if let sourcepath = item.sourceIndexPath { //local file that just needs to be moved
             tableView.performBatchUpdates({
                 if let file = delegate?.dragAndDropManagerRequestsFile(manager:self, atIndexPath: sourcepath) as? MLFile {
@@ -151,7 +150,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    //MARK: - Collectionview
+    // MARK: - Collectionview
     func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool {
         return canHandleDropSession(session: session)
     }
@@ -208,8 +207,8 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    private func moveItem(collectionView:UICollectionView, item:UICollectionViewDropItem, toIndexPath destinationPath:IndexPath) {
-        if let mlFile = item.dragItem.localObject as? MLFile, mlFile.labels.count > 0 && !inFolder() {
+    private func moveItem(collectionView: UICollectionView, item: UICollectionViewDropItem, toIndexPath destinationPath: IndexPath) {
+        if let mlFile = item.dragItem.localObject as? MLFile, !mlFile.labels.isEmpty && !inFolder() {
             collectionView.performBatchUpdates({
                 collectionView.insertItems(at: [destinationPath])
                 delegate?.dragAndDropManagerInsertItem(manager: self, item: mlFile, atIndexPath: destinationPath)
@@ -218,7 +217,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    private func addDragItem(collectionView:UICollectionView, dragItem item:UICollectionViewDropItem, toFolderAt index:IndexPath) {
+    private func addDragItem(collectionView: UICollectionView, dragItem item: UICollectionViewDropItem, toFolderAt index: IndexPath) {
         if let sourcepath = item.sourceIndexPath {
             //local file that just needs to be moved
             collectionView.performBatchUpdates({
@@ -239,7 +238,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    //MARK: - DropInteractionDelegate for EmptyView
+    // MARK: - DropInteractionDelegate for EmptyView
 
     func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
         return canHandleDropSession(session: session)
@@ -261,10 +260,10 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    //MARK: - Shared Methods
-    //Checks if the session has items conforming to typeidentifiers
-    private func canHandleDropSession(session:UIDropSession) -> Bool {
-        if (session.localDragSession != nil) {
+    // MARK: - Shared Methods
+    // Checks if the session has items conforming to typeidentifiers
+    private func canHandleDropSession(session: UIDropSession) -> Bool {
+        if session.localDragSession != nil {
             return true
         }
         return session.hasItemsConforming(toTypeIdentifiers: utiTypeIdentifiers)
@@ -276,7 +275,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
     ///   - hasActiveDrag: State if the drag started within the app
     ///   - item: UIDragItem from session
     /// - Returns: UIDropOperation
-    private func dropOperation(hasActiveDrag: Bool, firstSessionItem item: AnyObject?, withDestinationIndexPath destinationIndexPath:IndexPath?) -> UIDropOperation {
+    private func dropOperation(hasActiveDrag: Bool, firstSessionItem item: AnyObject?, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UIDropOperation {
         let inAlbum = delegate?.dragAndDropManagerCurrentSelection(manager: self) as? MLAlbum != nil
         let inShow = delegate?.dragAndDropManagerCurrentSelection(manager: self) as? MLShow != nil
         //you can move files into a folder or copy from anothr app into a folder
@@ -296,7 +295,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
             return .cancel
         }
         //we're dragging a file out of a folder
-        if let dragItem = item, let mlFile = dragItem.localObject as? MLFile, mlFile.labels.count > 0 {
+        if let dragItem = item, let mlFile = dragItem.localObject as? MLFile, !mlFile.labels.isEmpty {
             return .copy
         }
         //no reorder from another app into the top layer
@@ -311,7 +310,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
     private func handleError(error: DropError, itemProvider: NSItemProvider) {
         let message: String
         let filename = itemProvider.suggestedName ?? NSLocalizedString("THIS_FILE", comment:"")
-        switch (error.kind) {
+        switch error.kind {
         case .loadFileRepresentationFailed:
             message = String(format: NSLocalizedString("NOT_SUPPORTED_FILETYPE", comment: ""), filename)
         case .moveFileToDocuments:
@@ -322,7 +321,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
     }
 
-    private func fileIsFolder(atIndexPath indexPath:IndexPath?) -> Bool {
+    private func fileIsFolder(atIndexPath indexPath: IndexPath?) -> Bool {
         if let indexPath = indexPath {
             let file = delegate?.dragAndDropManagerRequestsFile(manager: self, atIndexPath: indexPath)
             return file as? MLLabel != nil
@@ -330,14 +329,14 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         return false
     }
 
-    private func fileIsCollection(file:AnyObject?) -> Bool {
+    private func fileIsCollection(file: AnyObject?) -> Bool {
         let isFolder = file as? MLLabel != nil
         let isAlbum = file as? MLAlbum != nil
         let isShow = file as? MLShow != nil
         return isFolder || isAlbum || isShow
     }
 
-    private func fileIsCollection(atIndexPath indexPath:IndexPath?) -> Bool {
+    private func fileIsCollection(atIndexPath indexPath: IndexPath?) -> Bool {
         if let indexPath = indexPath {
             let file = delegate?.dragAndDropManagerRequestsFile(manager: self, atIndexPath: indexPath)
             return fileIsCollection(file:file)
@@ -346,7 +345,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
     }
 
     //creating dragItems for the file at indexpath
-    private func dragItems(forIndexPath indexPath:IndexPath) -> [UIDragItem] {
+    private func dragItems(forIndexPath indexPath: IndexPath) -> [UIDragItem] {
         if let file = delegate?.dragAndDropManagerRequestsFile(manager: self, atIndexPath: indexPath) {
             if fileIsCollection(atIndexPath: indexPath) {
                 return dragItemsforCollection(file: file)
@@ -391,7 +390,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
     }
 
     //Provides an item for other applications
-    private func dragItem(fromFile file:AnyObject) -> [UIDragItem] {
+    private func dragItem(fromFile file: AnyObject) -> [UIDragItem] {
         guard let file = mlFile(from: file), let path = file.url else {
             assert(false, "can't create a dragitem if there is no file or the file has no url")
             return []
@@ -415,12 +414,12 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         return []
     }
 
-    private func mlFile(from file:AnyObject) -> MLFile? {
-        if let episode = file as? MLShowEpisode, let convertedfile = episode.files.first as? MLFile{
+    private func mlFile(from file: AnyObject) -> MLFile? {
+        if let episode = file as? MLShowEpisode, let convertedfile = episode.files.first as? MLFile {
             return convertedfile
         }
 
-        if let track = file as? MLAlbumTrack, let convertedfile = track.files.first as? MLFile{
+        if let track = file as? MLAlbumTrack, let convertedfile = track.files.first as? MLFile {
             return convertedfile
         }
 
@@ -430,7 +429,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         return nil
     }
 
-    private func addFile(file:MLFile, toFolderAt folderIndex:IndexPath) {
+    private func addFile(file: MLFile, toFolderAt folderIndex: IndexPath) {
         let label = delegate?.dragAndDropManagerRequestsFile(manager: self, atIndexPath: folderIndex) as! MLLabel
         DispatchQueue.main.async {
             _ = label.files.insert(file)
@@ -444,8 +443,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
     /// - Parameters:
     ///   - itemProvider: itemprovider which is used to load the files from
     ///   - completion: callback with the successfully created file or error if it failed
-    private func createFileWith(itemProvider:NSItemProvider, completion: @escaping ((MLFile?, Error?) -> Void))
-    {
+    private func createFileWith(itemProvider: NSItemProvider, completion: @escaping ((MLFile?, Error?) -> Void)) {
         itemProvider.loadFileRepresentation(forTypeIdentifier: kUTTypeData as String) {
             [weak self] (url, error) in
             guard let strongSelf = self else { return }
@@ -480,7 +478,7 @@ class VLCDragAndDropManager: NSObject, UICollectionViewDragDelegate, UITableView
         }
     }
 
-    private func moveFileToDocuments(fromURL filepath:URL?) -> URL? {
+    private func moveFileToDocuments(fromURL filepath: URL?) -> URL? {
         let searchPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
         let newDirectoryPath = searchPaths.first
         guard let directoryPath = newDirectoryPath, let url = filepath else {

+ 18 - 18
Sources/VLCTabBarCoordinator.swift

@@ -15,11 +15,11 @@ import Foundation
 class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarControllerDelegate {
 
     private var childCoordinators: [NSObject] = []
-    private var tabBarController:UITabBarController
-    private var services:Services
+    private var tabBarController: UITabBarController
+    private var services: Services
     private let displayController = VLCPlayerDisplayController()
 
-    public init(tabBarController: UITabBarController, services:Services) {
+    public init(tabBarController: UITabBarController, services: Services) {
         self.tabBarController = tabBarController
         self.services = services
         super.init()
@@ -60,9 +60,9 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
         let videoVC = VLCMediaViewController(services: services)
         //this should probably not be the delegate
         videoVC.delegate = self
-        videoVC.title = NSLocalizedString("Video",comment: "")
+        videoVC.title = NSLocalizedString("Video", comment: "")
         videoVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("Video",comment: ""),
+            title: NSLocalizedString("Video", comment: ""),
             image: UIImage(named: "TVShowsIcon"),
             selectedImage: UIImage(named: "TVShowsIcon"))
 
@@ -70,9 +70,9 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
         let audioVC = VLCMediaViewController(services: services)
         //this should probably not be the delegate
         audioVC.delegate = self
-        audioVC.title = NSLocalizedString("Audio",comment: "")
+        audioVC.title = NSLocalizedString("Audio", comment: "")
         audioVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("Audio",comment: ""),
+            title: NSLocalizedString("Audio", comment: ""),
             image: UIImage(named: "MusicAlbums"),
             selectedImage:UIImage(named: "MusicAlbums"))
 
@@ -80,23 +80,23 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
         let serverVC = VLCServerListViewController(nibName: nil, bundle: nil)
         serverVC.title = NSLocalizedString("LOCAL_NETWORK", comment: "")
         serverVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("LOCAL_NETWORK",comment: ""),
+            title: NSLocalizedString("LOCAL_NETWORK", comment: ""),
             image: UIImage(named: "Local"),
             selectedImage: UIImage(named: "Local"))
 
         //CloudServices
         let cloudVC = VLCCloudServicesTableViewController(nibName: "VLCCloudServicesTableViewController", bundle: Bundle.main)
-        cloudVC.title = NSLocalizedString("CLOUD_SERVICES",comment: "")
+        cloudVC.title = NSLocalizedString("CLOUD_SERVICES", comment: "")
         cloudVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("CLOUD_SERVICES",comment: ""),
+            title: NSLocalizedString("CLOUD_SERVICES", comment: ""),
             image: UIImage(named: "iCloudIcon"),
             selectedImage: UIImage(named: "iCloudIcon"))
 
         //Settings
         let settingsVC = VLCSettingsController()
-        settingsVC.title = NSLocalizedString("Settings",comment: "")
+        settingsVC.title = NSLocalizedString("Settings", comment: "")
         settingsVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("Settings",comment: ""),
+            title: NSLocalizedString("Settings", comment: ""),
             image: UIImage(named: "Settings"),
             selectedImage: UIImage(named: "Settings"))
 
@@ -104,7 +104,7 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
         let downloadVC = VLCDownloadViewController()
         downloadVC.title = NSLocalizedString("DOWNLOAD_FROM_HTTP", comment:"")
         downloadVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("DOWNLOAD_FROM_HTTP",comment: ""),
+            title: NSLocalizedString("DOWNLOAD_FROM_HTTP", comment: ""),
             image: UIImage(named: "Downloads"),
             selectedImage:  UIImage(named: "Downloads"))
 
@@ -118,10 +118,10 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
 
         //About
         let aboutVC = VLCAboutViewController()
-        aboutVC.title = NSLocalizedString("ABOUT_APP",comment: "")
+        aboutVC.title = NSLocalizedString("ABOUT_APP", comment: "")
 
         aboutVC.tabBarItem = UITabBarItem(
-            title: NSLocalizedString("ABOUT_APP",comment: ""),
+            title: NSLocalizedString("ABOUT_APP", comment: ""),
             image: coneIcon(),
             selectedImage: coneIcon())
 
@@ -137,7 +137,7 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
         return nil
     }
 
-    //MARK - VLCMediaViewControllerDelegate
+    // MARK: - VLCMediaViewControllerDelegate
     func mediaViewControllerDidSelectMediaObject(_ VLCMediaViewController: VLCMediaViewController, mediaObject: NSManagedObject) {
         playMedia(media:mediaObject)
     }
@@ -154,14 +154,14 @@ class VLCTabbarCooordinator: NSObject, VLCMediaViewControllerDelegate, UITabBarC
 
     func showSortOptions() {
         //This should be in a subclass
-        let sortOptionsAlertController = UIAlertController(title: NSLocalizedString("Sort by",comment: ""), message: nil, preferredStyle: .actionSheet)
+        let sortOptionsAlertController = UIAlertController(title: NSLocalizedString("Sort by", comment: ""), message: nil, preferredStyle: .actionSheet)
         let sortByNameAction = UIAlertAction(title: SortOption.alphabetically.localizedDescription, style: .default) { action in
         }
         let sortBySizeAction = UIAlertAction(title: SortOption.size.localizedDescription, style: .default) { action in
         }
         let sortbyDateAction = UIAlertAction(title: SortOption.insertonDate.localizedDescription, style: .default) { action in
         }
-        let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel",comment:""), style: .cancel, handler: nil)
+        let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
         sortOptionsAlertController.addAction(sortByNameAction)
         sortOptionsAlertController.addAction(sortbyDateAction)
         sortOptionsAlertController.addAction(sortBySizeAction)

+ 44 - 41
fastlane/Fastfile

@@ -20,40 +20,48 @@ desc '- Build and sign the app'
 desc '- Update the changelog from the NEWS file'
 desc '- Push the version bump'
 lane :release do |options|
-   platform = get_platform options
-   version = get_version options
-   ensure_git_status_clean
-   clear_derived_data
-   set_version_bump_build_and_commit(platform: platform, version: version)
-   git_apply_private_constants
-   cocoapods(repo_update: true)
-   gym(scheme: "VLC-#{platform}")
-   pilot(app_platform: platform == 'tvOS' ? 'appletvos' : 'ios')
-   update_changelog
-   push_to_git_remote
+  platform = get_platform options
+  version = get_version options
+  ensure_git_status_clean
+  clear_derived_data
+  set_version_bump_build_and_commit(platform: platform, version: version)
+  git_apply_private_constants
+  cocoapods(repo_update: true)
+  gym(scheme: "VLC-#{platform}")
+  pilot(app_platform: platform == 'tvOS' ? 'appletvos' : 'ios')
+  update_changelog
+  push_to_git_remote
+end
+
+desc 'Check style and conventions'
+lane :lint do
+  rubocop
+  swiftlint(executable: 'Pods/SwiftLint/swiftlint', strict: true)
 end
 
 lane :ci do
-  xcversion(version: "9.2.0")
-  xcode_select "/Applications/Xcode.app"
-  #Ideally we have iOS 9 support here but this is not yet added
-  #https://discuss.circleci.com/t/please-add-simulators-for-ios-9-10-to-xcode-9-image/16530
+  lint
+  xcversion(version: '9.2.0')
+  xcode_select '/Applications/Xcode.app'
+  # Ideally we have iOS 9 support here but this is not yet added
+  # https://discuss.circleci.com/t/please-add-simulators-for-ios-9-10-to-xcode-9-image/16530
   xcodebuild(
-    workspace: "VLC.xcworkspace",
-    scheme: "VLC-iOS",
-    configuration: "Debug",
+    workspace: 'VLC.xcworkspace',
+    scheme: 'VLC-iOS',
+    configuration: 'Debug',
     clean: true,
     build: true,
-    destination: "platform=iOS Simulator,name=iPhone 6s,OS=10.3.1"
+    destination: 'platform=iOS Simulator,name=iPhone 6s,OS=10.3.1'
   )
   xcodebuild(
-    workspace: "VLC.xcworkspace",
-    scheme: "VLC-tvOS",
-    configuration: "Debug",
+    workspace: 'VLC.xcworkspace',
+    scheme: 'VLC-tvOS',
+    configuration: 'Debug',
     clean: true,
     build: true,
-    destination: "platform=tvOS Simulator,name=Apple TV 1080p,OS=10.2"
+    destination: 'platform=tvOS Simulator,name=Apple TV 1080p,OS=10.2'
   )
+  test
 end
 
 #### Tests ####
@@ -69,15 +77,15 @@ end
 desc 'Bump and commit app version and build number'
 private_lane :set_version_bump_build_and_commit do |options|
   if options[:platform] == 'tvOS'
-    increment_build_number_in_plist(VLC::infoPlistPath[:tvOS])
-    set_version_number_in_plist(VLC::infoPlistPath[:tvOS], options[:version])
+    increment_build_number_in_plist(VLC.info_plist_path[:tvOS])
+    set_version_number_in_plist(VLC.info_plist_path[:tvOS], options[:version])
   elsif options[:platform] == 'iOS'
-    increment_build_number_in_plist(VLC::infoPlistPath[:iOS])
-    increment_build_number_in_plist(VLC::infoPlistPath[:watchKitExtension])
-    increment_build_number_in_plist(VLC::infoPlistPath[:watchOS])
-    set_version_number_in_plist(VLC::infoPlistPath[:iOS], options[:version])
-    set_version_number_in_plist(VLC::infoPlistPath[:watchKitExtension], options[:version])
-    set_version_number_in_plist(VLC::infoPlistPath[:watchOS], options[:version])
+    increment_build_number_in_plist(VLC.info_plist_path[:iOS])
+    increment_build_number_in_plist(VLC.info_plist_path[:watchKitExtension])
+    increment_build_number_in_plist(VLC.info_plist_path[:watchOS])
+    set_version_number_in_plist(VLC.info_plist_path[:iOS], options[:version])
+    set_version_number_in_plist(VLC.info_plist_path[:watchKitExtension], options[:version])
+    set_version_number_in_plist(VLC.info_plist_path[:watchOS], options[:version])
   end
 
   commit_version_bump(message: 'Version Bump by fastlane', force: true)
@@ -85,12 +93,11 @@ end
 
 desc 'Update changelog in iTunes Connect with the content from Docs/NEWS'
 private_lane :update_changelog do |options|
+  platform = options[:platform]
   # Splits the News by -------- get out the top notes
   changelog = File.read('../Docs/NEWS').split('-----------')[1].split('-----------').first
-  temp_changelog = changelog.split("${options[:platform]}")
-  if temp_changelog.count <= 1
-    temp_changelog = changelog.split("tvOS")
-  end
+  temp_changelog = changelog.split(platform)
+  temp_changelog = changelog.split('tvOS') if temp_changelog.count <= 1
   changelog = temp_changelog[0..-2].join.strip
   set_changelog(app_identifier: 'org.videolan.vlc-ios', changelog: changelog, username: '*', team_name: 'VideoLAN')
 end
@@ -109,9 +116,7 @@ end
 desc 'Return the platform received as parameter, or ask for it if missing'
 private_lane :get_platform do |options|
   platform = options[:platform]
-  if !platform || platform.empty?
-    platform = prompt(text: 'Platform [iOS, tvOS]: ')
-  end
+  platform = prompt(text: 'Platform [iOS, tvOS]: ') if !platform || platform.empty?
   if platform != 'iOS' && platform != 'tvOS'
     puts("⚠️  Platform '#{platform}' not supported")
     exit 1
@@ -122,8 +127,6 @@ end
 desc 'Return the version received as parameter, or ask for it if missing'
 private_lane :get_version do |options|
   version = options[:version]
-  if !version || version.empty?
-    version = ask("Enter a new version number: ")
-  end
+  version = ask('Enter a new version number: ') if !version || version.empty?
   version
 end

+ 5 - 0
fastlane/Pluginfile

@@ -0,0 +1,5 @@
+# Autogenerated by fastlane
+#
+# Ensure this file is checked in to source control!
+
+gem 'fastlane-plugin-ruby'

+ 5 - 1
fastlane/README.md

@@ -46,7 +46,11 @@ This action does the following:
 - Update the changelog from the NEWS file
 
 - Push the version bump
-
+### lint
+```
+fastlane lint
+```
+Check style and conventions
 ### ci
 ```
 fastlane ci

+ 2 - 2
fastlane/helpers/VLC.rb

@@ -1,8 +1,8 @@
 #!/usr/bin/ruby
 
 class VLC
-  def self.infoPlistPath
-    return {
+  def self.info_plist_path
+    {
       iOS: '../Sources/VLC for iOS-Info.plist',
       tvOS: '../Apple-TV/Info.plist',
       watchKitExtension: '../VLC WatchKit Native Extension/Info.plist',

+ 7 - 8
fastlane/helpers/version.rb

@@ -1,13 +1,12 @@
 
-def set_version_number_in_plist(plistPath, version)
-  versionNumber = `xcrun /usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "#{plistPath}"`
+def set_version_number_in_plist(plist_path, version)
+  version_number = `xcrun /usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "#{plist_path}"`
   puts "Next version: #{version}"
-  puts "Current version: #{versionNumber}"
-  `/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString #{version}" "#{plistPath}"`
+  puts "Current version: #{version_number}"
+  `/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString #{version}" "#{plist_path}"`
 end
 
-def increment_build_number_in_plist(plistPath)
-  buildNumber = `xcrun /usr/libexec/PlistBuddy -c "Print CFBundleVersion" "#{plistPath}"`
-  `/usr/libexec/PlistBuddy -c "Set :CFBundleVersion #{buildNumber.next}" "#{plistPath}"`
+def increment_build_number_in_plist(plist_path)
+  build_number = `xcrun /usr/libexec/PlistBuddy -c "Print CFBundleVersion" "#{plist_path}"`
+  `/usr/libexec/PlistBuddy -c "Set :CFBundleVersion #{build_number.next}" "#{plist_path}"`
 end
-