From ef859ec11edbfba3917ae27af338520729222345 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Tue, 9 Jul 2024 09:55:08 +0200 Subject: [PATCH] V 4.0.0 (#77) --- AUTHORS | 2 + COPYING.iOS | 13 + LICENSE.txt | 674 ++++++++++++++++++ Package.resolved | 78 +- .../API/NextcloudKit+API_Async.swift | 92 --- .../E2EE/NextcloudKit+E2EE_Async.swift | 144 ---- .../Extensions/Image+Extension.swift | 4 +- .../Extensions/String+Extension.swift | 1 - Sources/NextcloudKit/NKCommon.swift | 111 ++- Sources/NextcloudKit/NKError.swift | 3 - Sources/NextcloudKit/NKModel.swift | 638 ++++++++--------- Sources/NextcloudKit/NKRequestOptions.swift | 10 +- Sources/NextcloudKit/NKShareAccounts.swift | 22 +- .../{API => }/NextcloudKit+API.swift | 338 ++++----- .../NextcloudKit/NextcloudKit+Assistant.swift | 75 +- .../NextcloudKit/NextcloudKit+Comments.swift | 74 +- .../NextcloudKit/NextcloudKit+Dashboard.swift | 68 +- .../{E2EE => }/NextcloudKit+E2EE.swift | 162 ++--- .../NextcloudKit/NextcloudKit+FilesLock.swift | 19 +- .../NextcloudKit+Groupfolders.swift | 33 +- .../NextcloudKit/NextcloudKit+Hovercard.swift | 42 +- .../NextcloudKit/NextcloudKit+Livephoto.swift | 31 +- Sources/NextcloudKit/NextcloudKit+Login.swift | 77 +- .../NextcloudKit/NextcloudKit+NCText.swift | 68 +- .../NextcloudKit+PushNotification.swift | 86 +-- .../NextcloudKit+Richdocuments.swift | 61 +- .../NextcloudKit/NextcloudKit+Search.swift | 94 +-- Sources/NextcloudKit/NextcloudKit+Share.swift | 260 +++---- .../NextcloudKit+UserStatus.swift | 122 +--- .../{WebDAV => }/NextcloudKit+WebDAV.swift | 283 +++----- Sources/NextcloudKit/NextcloudKit.swift | 157 +--- .../NextcloudKit/NextcloudKitBackground.swift | 59 +- .../WebDAV/NextcloudKit+WebDAV_Async.swift | 101 --- 33 files changed, 1828 insertions(+), 2174 deletions(-) create mode 100644 AUTHORS create mode 100644 COPYING.iOS create mode 100644 LICENSE.txt delete mode 100644 Sources/NextcloudKit/API/NextcloudKit+API_Async.swift delete mode 100644 Sources/NextcloudKit/E2EE/NextcloudKit+E2EE_Async.swift rename Sources/NextcloudKit/{API => }/NextcloudKit+API.swift (81%) rename Sources/NextcloudKit/{E2EE => }/NextcloudKit+E2EE.swift (83%) rename Sources/NextcloudKit/{WebDAV => }/NextcloudKit+WebDAV.swift (72%) delete mode 100644 Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV_Async.swift diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..74656bbd --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Marino Faggiana +All contributors can be viewed at https://github.com/nextcloud/NextcloudKit/graphs/contributors diff --git a/COPYING.iOS b/COPYING.iOS new file mode 100644 index 00000000..534f7b9d --- /dev/null +++ b/COPYING.iOS @@ -0,0 +1,13 @@ +The NextcloudKit developers are aware that the terms of service that +apply to apps distributed via Apple's App Store services may conflict +with rights granted under the NextcloudKit license, the GNU General +Public License, version 3 or (at your option) any later version. The +copyright holders of the NextcloudKit do not wish this conflict +to prevent the otherwise-compliant distribution of derived apps via +the App Store. Therefore, we have committed not to pursue any license +violation that results solely from the conflict between the GNU GPLv3 +or any later version and the Apple App Store terms of service. In +other words, as long as you comply with the GPL in all other respects, +including its requirements to provide users with source code and the +text of the license, we will not object to your distribution of the +NextcloudKit through the App Store. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..9cecc1d4 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Package.resolved b/Package.resolved index dd082463..bff4ffdc 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,43 +1,41 @@ { - "object": { - "pins": [ - { - "package": "Alamofire", - "repositoryURL": "https://github.com/Alamofire/Alamofire", - "state": { - "branch": null, - "revision": "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad", - "version": "5.8.1" - } - }, - { - "package": "Mocker", - "repositoryURL": "https://github.com/WeTransfer/Mocker.git", - "state": { - "branch": null, - "revision": "5d86f27a8f80d4ba388bc1a379a3c2289a1f3d18", - "version": "2.6.0" - } - }, - { - "package": "SwiftyJSON", - "repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON", - "state": { - "branch": null, - "revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07", - "version": "5.0.1" - } - }, - { - "package": "SwiftyXMLParser", - "repositoryURL": "https://github.com/yahoojapan/SwiftyXMLParser", - "state": { - "branch": null, - "revision": "d7a1d23f04c86c1cd2e8f19247dd15d74e0ea8be", - "version": "5.6.0" - } + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire", + "state" : { + "revision" : "f455c2975872ccd2d9c81594c658af65716e9b9a", + "version" : "5.9.1" } - ] - }, - "version": 1 + }, + { + "identity" : "mocker", + "kind" : "remoteSourceControl", + "location" : "https://github.com/WeTransfer/Mocker.git", + "state" : { + "revision" : "5d86f27a8f80d4ba388bc1a379a3c2289a1f3d18", + "version" : "2.6.0" + } + }, + { + "identity" : "swiftyjson", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftyJSON/SwiftyJSON", + "state" : { + "revision" : "af76cf3ef710b6ca5f8c05f3a31307d44a3c5828", + "version" : "5.0.2" + } + }, + { + "identity" : "swiftyxmlparser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/yahoojapan/SwiftyXMLParser", + "state" : { + "revision" : "d7a1d23f04c86c1cd2e8f19247dd15d74e0ea8be", + "version" : "5.6.0" + } + } + ], + "version" : 2 } diff --git a/Sources/NextcloudKit/API/NextcloudKit+API_Async.swift b/Sources/NextcloudKit/API/NextcloudKit+API_Async.swift deleted file mode 100644 index c0d7f981..00000000 --- a/Sources/NextcloudKit/API/NextcloudKit+API_Async.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// NextcloudKit+API_Async.swift -// NextcloudKit -// -// Created by Marino Faggiana on 19/10/22. -// -// Copyright © 2022 Marino Faggiana. All rights reserved. -// Author Marino Faggiana -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -#if os(macOS) -import Foundation -import AppKit -#else -import UIKit -#endif - -@available(iOS 13.0, *) -extension NextcloudKit { - - public func getServerStatus(serverUrl: String, - options: NKRequestOptions = NKRequestOptions()) async -> (ServerInfoResult) { - - await withUnsafeContinuation({ continuation in - getServerStatus(serverUrl: serverUrl) { serverInfoResult in - continuation.resume(returning: serverInfoResult) - } - }) - } - - public func getPreview(url: URL, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - getPreview(url: url, options: options) { account, data, error in - continuation.resume(returning: (account: account, data: data, error: error)) - } - }) - } - - public func downloadPreview(fileId: String, - fileNamePreviewLocalPath: String, - fileNameIconLocalPath: String? = nil, - widthPreview: Int = 512, - heightPreview: Int = 512, - sizeIcon: Int = 512, - etag: String? = nil, - crop: Int = 0, - cropMode: String = "fill", - forceIcon: Int = 1, - mimeFallback: Int = 0, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, imagePreview: UIImage?, imageIcon: UIImage?, imageOriginal: UIImage?, etag: String?, error: NKError) { - - await withUnsafeContinuation({ continuation in - downloadPreview(fileId: fileId, fileNamePreviewLocalPath: fileNamePreviewLocalPath, fileNameIconLocalPath: fileNameIconLocalPath, widthPreview: widthPreview, heightPreview: heightPreview, sizeIcon: sizeIcon, etag: etag, crop: crop, cropMode: cropMode, forceIcon: forceIcon, mimeFallback: mimeFallback, options: options) { account, imagePreview, imageIcon, imageOriginal, etag, error in - continuation.resume(returning: (account: account, imagePreview: imagePreview, imageIcon: imageIcon, imageOriginal: imageOriginal, etag: etag, error: error)) - } - }) - } - - public func getUserProfile(options: NKRequestOptions = NKRequestOptions()) async -> (account: String, userProfile: NKUserProfile?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - getUserProfile(options: options) { account, userProfile, data, error in - continuation.resume(returning: (account: account, userProfile: userProfile, data: data, error: error)) - } - }) - } - - public func sendClientDiagnosticsRemoteOperation(data: Data, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - sendClientDiagnosticsRemoteOperation(data: data, options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } -} diff --git a/Sources/NextcloudKit/E2EE/NextcloudKit+E2EE_Async.swift b/Sources/NextcloudKit/E2EE/NextcloudKit+E2EE_Async.swift deleted file mode 100644 index 06e2a6ff..00000000 --- a/Sources/NextcloudKit/E2EE/NextcloudKit+E2EE_Async.swift +++ /dev/null @@ -1,144 +0,0 @@ -// -// NextcloudKit+E2EE_Async.swift -// NextcloudKit -// -// Created by Marino Faggiana on 19/10/22. -// -// Copyright © 2022 Marino Faggiana. All rights reserved. -// Author Marino Faggiana -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -import Foundation - -@available(iOS 13.0, *) -extension NextcloudKit { - - public func markE2EEFolder(fileId: String, - delete: Bool, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - markE2EEFolder(fileId: fileId, delete: delete, options: options) { account, error in - - continuation.resume(returning: (account: account, error: error)) - } - }) - } - - @discardableResult - public func lockE2EEFolder(fileId: String, - e2eToken: String?, - e2eCounter: String?, - method: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, e2eToken: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - lockE2EEFolder(fileId: fileId, e2eToken: e2eToken, e2eCounter: e2eCounter, method: method, options: options) { account, e2eToken, data, error in - continuation.resume(returning: (account: account, e2eToken: e2eToken, data: data, error: error)) - } - }) - } - - public func getE2EEMetadata(fileId: String, - e2eToken: String?, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, e2eMetadata: String?, signature: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - getE2EEMetadata(fileId: fileId, e2eToken: e2eToken, options: options) { account, e2eMetadata, signature, data, error in - continuation.resume(returning: (account: account, e2eMetadata: e2eMetadata, signature: signature, data: data, error: error)) - } - }) - } - - public func putE2EEMetadata(fileId: String, - e2eToken: String, - e2eMetadata: String?, - signature: String?, - method: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, metadata: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: signature, method: method, options: options) { account, metadata, data, error in - continuation.resume(returning: (account: account, metadata: metadata, data: data, error: error)) - } - }) - } - - public func getE2EECertificate(user: String? = nil, options: NKRequestOptions = NKRequestOptions()) async -> (account: String, certificate: String?, certificateUser: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - getE2EECertificate(user: user, options: options) { account, certificate, certificateUser, data, error in - continuation.resume(returning: (account: account, certificate: certificate, certificateUser: certificateUser, data: data, error: error)) - } - }) - } - - public func getE2EEPrivateKey(options: NKRequestOptions = NKRequestOptions()) async -> (account: String, privateKey: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - getE2EEPrivateKey(options: options) { account, privateKey, data, error in - continuation.resume(returning: (account: account, privateKey: privateKey, data: data, error: error)) - } - }) - } - - public func getE2EEPublicKey(options: NKRequestOptions = NKRequestOptions()) async -> (account: String, publicKey: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - getE2EEPublicKey(options: options) { account, publicKey, data, error in - continuation.resume(returning: (account: account, publicKey: publicKey, data: data, error: error)) - } - }) - } - - public func signE2EECertificate(certificate: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, certificate: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - signE2EECertificate(certificate: certificate, options: options) { account, certificate, data, error in - continuation.resume(returning: (account: account, certificate: certificate, data: data, error: error)) - } - }) - } - - public func storeE2EEPrivateKey(privateKey: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, privateKey: String?, data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - storeE2EEPrivateKey(privateKey: privateKey, options: options) { account, privateKey, data, error in - continuation.resume(returning: (account: account, privateKey: privateKey, data: data, error: error)) - } - }) - } - - public func deleteE2EECertificate(options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - deleteE2EECertificate(options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } - - public func deleteE2EEPrivateKey(options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - deleteE2EEPrivateKey(options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } -} diff --git a/Sources/NextcloudKit/Extensions/Image+Extension.swift b/Sources/NextcloudKit/Extensions/Image+Extension.swift index 0d743573..d155e3bb 100644 --- a/Sources/NextcloudKit/Extensions/Image+Extension.swift +++ b/Sources/NextcloudKit/Extensions/Image+Extension.swift @@ -54,7 +54,7 @@ public extension NSImage { return nil } - func resizeImage(size: CGSize, isAspectRation: Bool) -> NSImage? { + func resizeImage(size: CGSize, isAspectRation: Bool = true) -> NSImage? { if let bitmapRep = NSBitmapImageRep( bitmapDataPlanes: nil, pixelsWide: Int(size.width), pixelsHigh: Int(size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, @@ -78,7 +78,7 @@ public extension NSImage { import UIKit extension UIImage { - internal func resizeImage(size: CGSize, isAspectRation: Bool) -> UIImage? { + internal func resizeImage(size: CGSize, isAspectRation: Bool = true) -> UIImage? { let originRatio = self.size.width / self.size.height let newRatio = size.width / size.height var newSize = size diff --git a/Sources/NextcloudKit/Extensions/String+Extension.swift b/Sources/NextcloudKit/Extensions/String+Extension.swift index 9f5e8c12..a205a436 100644 --- a/Sources/NextcloudKit/Extensions/String+Extension.swift +++ b/Sources/NextcloudKit/Extensions/String+Extension.swift @@ -24,7 +24,6 @@ import Foundation import Alamofire extension String { - public var urlEncoded: String? { // + for historical reason, most web servers treat + as a replacement of whitespace // ?, & mark query pararmeter which should not be part of a url string, but added seperately diff --git a/Sources/NextcloudKit/NKCommon.swift b/Sources/NextcloudKit/NKCommon.swift index 164be534..6cbd77f5 100644 --- a/Sources/NextcloudKit/NKCommon.swift +++ b/Sources/NextcloudKit/NKCommon.swift @@ -30,29 +30,27 @@ import MobileCoreServices import CoreServices #endif -@objc public protocol NKCommonDelegate { +public protocol NKCommonDelegate { + func authenticationChallenge(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) + func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) - @objc optional func authenticationChallenge(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) - @objc optional func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) + func networkReachabilityObserver(_ typeReachability: NKCommon.TypeReachability) - @objc optional func networkReachabilityObserver(_ typeReachability: NKCommon.TypeReachability) + func downloadProgress(_ progress: Float, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask) + func uploadProgress(_ progress: Float, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask) - @objc optional func downloadProgress(_ progress: Float, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask) - @objc optional func uploadProgress(_ progress: Float, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask) - - @objc optional func downloadingFinish(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) + func downloadingFinish(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) - @objc optional func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Int64, task: URLSessionTask, error: NKError) - @objc optional func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, size: Int64, task: URLSessionTask, error: NKError) + func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: Date?, dateLastModified: Date?, length: Int64, task: URLSessionTask, error: NKError) + func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: Date?, size: Int64, task: URLSessionTask, error: NKError) } -@objc public class NKCommon: NSObject { - - @objc public let dav: String = "remote.php/dav" - @objc public let sessionIdentifierDownload: String = "com.nextcloud.nextcloudkit.session.download" - @objc public let sessionIdentifierUpload: String = "com.nextcloud.nextcloudkit.session.upload" +public class NKCommon: NSObject { + public let dav: String = "remote.php/dav" + public let sessionIdentifierDownload: String = "com.nextcloud.nextcloudkit.session.download" + public let sessionIdentifierUpload: String = "com.nextcloud.nextcloudkit.session.upload" - @objc public enum TypeReachability: Int { + public enum TypeReachability: Int { case unknown = 0 case notReachable = 1 case reachableEthernetOrWiFi = 2 @@ -127,37 +125,37 @@ import CoreServices private var _copyLogToDocumentDirectory: Bool = false private let queueLog = DispatchQueue(label: "com.nextcloud.nextcloudkit.queuelog", attributes: .concurrent ) - @objc public var user: String { + public var user: String { return internalUser } - @objc public var userId: String { + public var userId: String { return internalUserId } - @objc public var password: String { + public var password: String { return internalPassword } - @objc public var account: String { + public var account: String { return internalAccount } - @objc public var urlBase: String { + public var urlBase: String { return internalUrlBase } - @objc public var userAgent: String? { + public var userAgent: String? { return internalUserAgent } - @objc public var nextcloudVersion: Int { + public var nextcloudVersion: Int { return internalNextcloudVersion } - @objc public let backgroundQueue = DispatchQueue(label: "com.nextcloud.nextcloudkit.backgroundqueue", qos: .background, attributes: .concurrent) + public let backgroundQueue = DispatchQueue(label: "com.nextcloud.nextcloudkit.backgroundqueue", qos: .background, attributes: .concurrent) - @objc public var filenameLog: String { + public var filenameLog: String { get { return _filenameLog } @@ -169,7 +167,7 @@ import CoreServices } } - @objc public var pathLog: String { + public var pathLog: String { get { return _pathLog } @@ -185,11 +183,11 @@ import CoreServices } } - @objc public var filenamePathLog: String { + public var filenamePathLog: String { return _filenamePathLog } - @objc public var levelLog: Int { + public var levelLog: Int { get { return _levelLog } @@ -198,7 +196,7 @@ import CoreServices } } - @objc public var printLog: Bool { + public var printLog: Bool { get { return _printLog } @@ -207,7 +205,7 @@ import CoreServices } } - @objc public var copyLogToDocumentDirectory: Bool { + public var copyLogToDocumentDirectory: Bool { get { return _copyLogToDocumentDirectory } @@ -239,27 +237,22 @@ import CoreServices return results } - @objc public func addInternalTypeIdentifier(typeIdentifier: String, classFile: String, editor: String, iconName: String, name: String) { - + public func addInternalTypeIdentifier(typeIdentifier: String, classFile: String, editor: String, iconName: String, name: String) { if !internalTypeIdentifiers.contains(where: { $0.typeIdentifier == typeIdentifier && $0.editor == editor}) { let newUTI = UTTypeConformsToServer(typeIdentifier: typeIdentifier, classFile: classFile, editor: editor, iconName: iconName, name: name) internalTypeIdentifiers.append(newUTI) } } - @objc public func objcGetInternalType(fileName: String, mimeType: String, directory: Bool) -> [String: String] { - + public func objcGetInternalType(fileName: String, mimeType: String, directory: Bool) -> [String: String] { let results = getInternalType(fileName: fileName, mimeType: mimeType, directory: directory) - return ["mimeType": results.mimeType, "classFile": results.classFile, "iconName": results.iconName, "typeIdentifier": results.typeIdentifier, "fileNameWithoutExt": results.fileNameWithoutExt, "ext": results.ext] } public func getInternalType(fileName: String, mimeType: String, directory: Bool) -> (mimeType: String, classFile: String, iconName: String, typeIdentifier: String, fileNameWithoutExt: String, ext: String) { - var ext = (fileName as NSString).pathExtension.lowercased() var mimeType = mimeType var classFile = "", iconName = "", typeIdentifier = "", fileNameWithoutExt = "" - var inUTI: CFString? if let cachedUTI = utiCache.object(forKey: ext as NSString) { @@ -267,7 +260,9 @@ import CoreServices } else { if let unmanagedFileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext as CFString, nil) { inUTI = unmanagedFileUTI.takeRetainedValue() - utiCache.setObject(inUTI!, forKey: ext as NSString) + if let inUTI { + utiCache.setObject(inUTI, forKey: ext as NSString) + } } } @@ -315,7 +310,6 @@ import CoreServices } public func getFileProperties(inUTI: CFString) -> NKFileProperty { - let fileProperty = NKFileProperty() let typeIdentifier: String = inUTI as String @@ -497,7 +491,6 @@ import CoreServices } public func getStandardHeaders(user: String?, password: String?, appendHeaders: [String: String]?, customUserAgent: String?, contentType: String? = nil) -> HTTPHeaders { - var headers: HTTPHeaders = [] if let username = user, let password = password { @@ -526,30 +519,25 @@ import CoreServices } public func createStandardUrl(serverUrl: String, endpoint: String) -> URLConvertible? { - guard var serverUrl = serverUrl.urlEncoded else { return nil } if serverUrl.last != "/" { serverUrl = serverUrl + "/" } serverUrl = serverUrl + endpoint - return serverUrl.asUrl } - public func convertDate(_ dateString: String, format: String) -> NSDate? { - + public func convertDate(_ dateString: String, format: String) -> Date? { if dateString.isEmpty { return nil } - let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.dateFormat = format - guard let date = dateFormatter.date(from: dateString) as? NSDate else { return nil } + guard let date = dateFormatter.date(from: dateString) else { return nil } return date } func convertDate(_ date: Date, format: String) -> String? { - let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier: "en_US_POSIX") @@ -559,7 +547,6 @@ import CoreServices } func findHeader(_ header: String, allHeaderFields: [AnyHashable: Any]?) -> String? { - guard let allHeaderFields = allHeaderFields else { return nil } let keyValues = allHeaderFields.map { (String(describing: $0.key).lowercased(), String(describing: $0.value)) } @@ -570,7 +557,6 @@ import CoreServices } func getHostName(urlString: String) -> String? { - if let url = URL(string: urlString) { guard let hostName = url.host else { return nil } guard let scheme = url.scheme else { return nil } @@ -583,7 +569,6 @@ import CoreServices } func getHostNameComponent(urlString: String) -> String? { - if let url = URL(string: urlString) { let components = url.pathComponents return components.joined(separator: "") @@ -592,7 +577,6 @@ import CoreServices } func getFileSize(filePath: String) -> Int64 { - do { let attributes = try FileManager.default.attributesOfItem(atPath: filePath) return attributes[FileAttributeKey.size] as? Int64 ?? 0 @@ -603,13 +587,11 @@ import CoreServices } public func returnPathfromServerUrl(_ serverUrl: String) -> String { - let home = urlBase + "/remote.php/dav/files/" + userId return serverUrl.replacingOccurrences(of: home, with: "") } public func getSessionErrorFromAFError(_ afError: AFError?) -> NSError? { - if let afError = afError?.asAFError { switch afError { case .sessionTaskFailed(let sessionError): @@ -622,33 +604,26 @@ import CoreServices // MARK: - Log - @objc public func clearFileLog() { - + public func clearFileLog() { FileManager.default.createFile(atPath: filenamePathLog, contents: nil, attributes: nil) - if copyLogToDocumentDirectory { - let filenameCopyToDocumentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/" + filenameLog + if copyLogToDocumentDirectory, let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first { + let filenameCopyToDocumentDirectory = path + "/" + filenameLog FileManager.default.createFile(atPath: filenameCopyToDocumentDirectory, contents: nil, attributes: nil) } } - @objc public func writeLog(_ text: String?) { - + public func writeLog(_ text: String?) { guard let text = text else { return } guard let date = self.convertDate(Date(), format: "yyyy-MM-dd' 'HH:mm:ss") else { return } let textToWrite = "\(date) " + text + "\n" - if printLog { - print(textToWrite) - } - + if printLog { print(textToWrite) } if levelLog > 0 { - queueLog.async(flags: .barrier) { self.writeLogToDisk(filename: self.filenamePathLog, text: textToWrite) - - if self.copyLogToDocumentDirectory { - let filenameCopyToDocumentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/" + self.filenameLog + if self.copyLogToDocumentDirectory, let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first { + let filenameCopyToDocumentDirectory = path + "/" + self.filenameLog self.writeLogToDisk(filename: filenameCopyToDocumentDirectory, text: textToWrite) } } @@ -656,12 +631,12 @@ import CoreServices } private func writeLogToDisk(filename: String, text: String) { - guard let data = text.data(using: .utf8) else { return } if !FileManager.default.fileExists(atPath: filename) { FileManager.default.createFile(atPath: filename, contents: nil, attributes: nil) } + if let fileHandle = FileHandle(forWritingAtPath: filename) { fileHandle.seekToEndOfFile() fileHandle.write(data) diff --git a/Sources/NextcloudKit/NKError.swift b/Sources/NextcloudKit/NKError.swift index 845b7b66..579b3000 100644 --- a/Sources/NextcloudKit/NKError.swift +++ b/Sources/NextcloudKit/NKError.swift @@ -51,11 +51,8 @@ extension OCSPath { static var ocsXMLMsg: Self { ["d:error", "s:message"] } } -@objcMembers public class NKError: NSObject { - static let internalError = -9999 - // Chunk error public static let chunkNoEnoughMemory = -9998 public static let chunkMoveFile = -9997 diff --git a/Sources/NextcloudKit/NKModel.swift b/Sources/NextcloudKit/NKModel.swift index 18735ed0..77df849f 100644 --- a/Sources/NextcloudKit/NKModel.swift +++ b/Sources/NextcloudKit/NKModel.swift @@ -33,260 +33,291 @@ import SwiftyJSON // MARK: - -@objc public class NKActivity: NSObject { - - @objc public var app = "" - @objc public var date = NSDate() - @objc public var idActivity: Int = 0 - @objc public var icon = "" - @objc public var link = "" - @objc public var message = "" - @objc public var messageRich: Data? - @objc public var objectId: Int = 0 - @objc public var objectName = "" - @objc public var objectType = "" - @objc public var previews: Data? - @objc public var subject = "" - @objc public var subjectRich: Data? - @objc public var type = "" - @objc public var user = "" -} +public enum NKProperties: String, CaseIterable { + /// DAV + case displayname = "" + case getlastmodified = "" + case getetag = "" + case getcontenttype = "" + case resourcetype = "" + case quotaavailablebytes = "" + case quotausedbytes = "" + case getcontentlength = "" + /// owncloud.org + case permissions = "" + case id = "" + case fileid = "" + case size = "" + case favorite = "" + case sharetypes = "" + case ownerid = "" + case ownerdisplayname = "" + case commentsunread = "" + case checksums = "" + case downloadURL = "" + case datafingerprint = "" + /// nextcloud.org + case creationtime = "" + case uploadtime = "" + case isencrypted = "" + case haspreview = "" + case mounttype = "" + case richworkspace = "" + case note = "" + case lock = "" + case lockowner = "" + case lockownereditor = "" + case lockownerdisplayname = "" + case lockownertype = "" + case locktime = "" + case locktimeout = "" + case systemtags = "" + case filemetadatasize = "" + case filemetadatagps = "" + case metadataphotossize = "" + case metadataphotosgps = "" + case metadatafileslivephoto = "" + case hidden = "" + /// open-collaboration-services.org + case sharepermissionscollaboration = "" + /// open-cloud-mesh.org + case sharepermissionscloudmesh = "" + + static func properties(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + var properties = allCases.map { $0.rawValue }.joined() + if let createProperties { + properties = "" + properties = createProperties.map { $0.rawValue }.joined(separator: "") + } + for removeProperty in removeProperties { + properties = properties.replacingOccurrences(of: removeProperty.rawValue, with: "") + } + return properties + } -@objc public class NKComments: NSObject { - - @objc public var actorDisplayName = "" - @objc public var actorId = "" - @objc public var actorType = "" - @objc public var creationDateTime = NSDate() - @objc public var isUnread: Bool = false - @objc public var message = "" - @objc public var messageId = "" - @objc public var objectId = "" - @objc public var objectType = "" - @objc public var path = "" - @objc public var verb = "" + static func trashProperties() -> String { + let properties: [String] = [displayname.rawValue, getcontenttype.rawValue, resourcetype.rawValue, id.rawValue, fileid.rawValue, size.rawValue, haspreview.rawValue, "", "", ""] + return properties.joined() + } } -@objc public class NKEditorDetailsCreators: NSObject { - - @objc public var editor = "" - @objc public var ext = "" - @objc public var identifier = "" - @objc public var mimetype = "" - @objc public var name = "" - @objc public var templates: Int = 0 +public class NKActivity: NSObject { + public var app = "" + public var date = Date() + public var idActivity: Int = 0 + public var icon = "" + public var link = "" + public var message = "" + public var messageRich: Data? + public var objectId: Int = 0 + public var objectName = "" + public var objectType = "" + public var previews: Data? + public var subject = "" + public var subjectRich: Data? + public var type = "" + public var user = "" } -@objc public class NKEditorDetailsEditors: NSObject { - - @objc public var mimetypes: [String] = [] - @objc public var name = "" - @objc public var optionalMimetypes: [String] = [] - @objc public var secure: Int = 0 +public class NKComments: NSObject { + public var actorDisplayName = "" + public var actorId = "" + public var actorType = "" + public var creationDateTime = Date() + public var isUnread: Bool = false + public var message = "" + public var messageId = "" + public var objectId = "" + public var objectType = "" + public var path = "" + public var verb = "" } -@objc public class NKEditorTemplates: NSObject { - - @objc public var delete = "" - @objc public var ext = "" - @objc public var identifier = "" - @objc public var name = "" - @objc public var preview = "" - @objc public var type = "" +public class NKEditorDetailsCreators: NSObject { + public var editor = "" + public var ext = "" + public var identifier = "" + public var mimetype = "" + public var name = "" + public var templates: Int = 0 } -@objc public class NKExternalSite: NSObject { +public class NKEditorDetailsEditors: NSObject { + public var mimetypes: [String] = [] + public var name = "" + public var optionalMimetypes: [String] = [] + public var secure: Int = 0 +} - @objc public var icon = "" - @objc public var idExternalSite: Int = 0 - @objc public var lang = "" - @objc public var name = "" - @objc public var order: Int = 0 - @objc public var type = "" - @objc public var url = "" +public class NKEditorTemplates: NSObject { + public var delete = "" + public var ext = "" + public var identifier = "" + public var name = "" + public var preview = "" + public var type = "" } -@objc public class NKFile: NSObject { - - @objc public var account = "" - @objc public var classFile = "" - @objc public var commentsUnread: Bool = false - @objc public var contentType = "" - @objc public var checksums = "" - @objc public var creationDate: NSDate? - @objc public var dataFingerprint = "" - @objc public var date = NSDate() - @objc public var directory: Bool = false - @objc public var downloadURL = "" - @objc public var e2eEncrypted: Bool = false - @objc public var etag = "" - @objc public var favorite: Bool = false - @objc public var fileId = "" - @objc public var fileName = "" - @objc public var hasPreview: Bool = false - @objc public var iconName = "" - @objc public var mountType = "" - @objc public var name = "" - @objc public var note = "" - @objc public var ocId = "" - @objc public var ownerId = "" - @objc public var ownerDisplayName = "" - @objc public var lock = false - @objc public var lockOwner = "" - @objc public var lockOwnerEditor = "" - @objc public var lockOwnerType = 0 - @objc public var lockOwnerDisplayName = "" - @objc public var lockTime: Date? - @objc public var lockTimeOut: Date? - @objc public var path = "" - @objc public var permissions = "" - @objc public var quotaUsedBytes: Int64 = 0 - @objc public var quotaAvailableBytes: Int64 = 0 - @objc public var resourceType = "" - @objc public var richWorkspace: String? - @objc public var sharePermissionsCollaborationServices: Int = 0 - @objc public var sharePermissionsCloudMesh: [String] = [] - @objc public var shareType: [Int] = [] - @objc public var size: Int64 = 0 - @objc public var serverUrl = "" - @objc public var tags: [String] = [] - @objc public var trashbinFileName = "" - @objc public var trashbinOriginalLocation = "" - @objc public var trashbinDeletionTime = NSDate() - @objc public var uploadDate: NSDate? - @objc public var urlBase = "" - @objc public var user = "" - @objc public var userId = "" - @objc public var latitude: Double = 0 - @objc public var longitude: Double = 0 - @objc public var altitude: Double = 0 - @objc public var height: Double = 0 - @objc public var width: Double = 0 +public class NKExternalSite: NSObject { + public var icon = "" + public var idExternalSite: Int = 0 + public var lang = "" + public var name = "" + public var order: Int = 0 + public var type = "" + public var url = "" +} +public class NKFile: NSObject { + public var account = "" + public var classFile = "" + public var commentsUnread: Bool = false + public var contentType = "" + public var checksums = "" + public var creationDate: Date? + public var dataFingerprint = "" + public var date = Date() + public var directory: Bool = false + public var downloadURL = "" + public var e2eEncrypted: Bool = false + public var etag = "" + public var favorite: Bool = false + public var fileId = "" + public var fileName = "" + public var hasPreview: Bool = false + public var iconName = "" + public var mountType = "" + public var name = "" + public var note = "" + public var ocId = "" + public var ownerId = "" + public var ownerDisplayName = "" + public var lock = false + public var lockOwner = "" + public var lockOwnerEditor = "" + public var lockOwnerType = 0 + public var lockOwnerDisplayName = "" + public var lockTime: Date? + public var lockTimeOut: Date? + public var path = "" + public var permissions = "" + public var quotaUsedBytes: Int64 = 0 + public var quotaAvailableBytes: Int64 = 0 + public var resourceType = "" + public var richWorkspace: String? + public var sharePermissionsCollaborationServices: Int = 0 + public var sharePermissionsCloudMesh: [String] = [] + public var shareType: [Int] = [] + public var size: Int64 = 0 + public var serverUrl = "" + public var tags: [String] = [] + public var trashbinFileName = "" + public var trashbinOriginalLocation = "" + public var trashbinDeletionTime = Date() + public var uploadDate: Date? + public var urlBase = "" + public var user = "" + public var userId = "" + public var latitude: Double = 0 + public var longitude: Double = 0 + public var altitude: Double = 0 + public var height: Double = 0 + public var width: Double = 0 + public var hidden = false /// If this is not empty, the media is a live photo. New media gets this straight from server, but old media needs to be detected as live photo (look isFlaggedAsLivePhotoByServer) - @objc public var livePhotoFile = "" - + public var livePhotoFile = "" /// Indicating if the file is sent as a live photo from the server, or if we should detect it as such and convert it client-side - @objc public var isFlaggedAsLivePhotoByServer = false - - @objc public var hidden = false - + public var isFlaggedAsLivePhotoByServer = false } -@objcMembers public class NKFileProperty: NSObject { - +public class NKFileProperty: NSObject { public var classFile: String = "" public var iconName: String = "" public var name: String = "" public var ext: String = "" } -@objc public class NKNotifications: NSObject { - - @objc public var actions: Data? - @objc public var app = "" - @objc public var date = NSDate() - @objc public var icon: String? - @objc public var idNotification: Int = 0 - @objc public var link = "" - @objc public var message = "" - @objc public var messageRich = "" - @objc public var messageRichParameters: Data? - @objc public var objectId = "" - @objc public var objectType = "" - @objc public var subject = "" - @objc public var subjectRich = "" - @objc public var subjectRichParameters: Data? - @objc public var user = "" +public class NKRichdocumentsTemplate: NSObject { + public var delete = "" + public var ext = "" + public var name = "" + public var preview = "" + public var templateId: Int = 0 + public var type = "" } -@objc public class NKRichdocumentsTemplate: NSObject { - - @objc public var delete = "" - @objc public var ext = "" - @objc public var name = "" - @objc public var preview = "" - @objc public var templateId: Int = 0 - @objc public var type = "" +public class NKSharee: NSObject { + public var circleInfo = "" + public var circleOwner = "" + public var label = "" + public var name = "" + public var shareType: Int = 0 + public var shareWith = "" + public var uuid = "" + public var userClearAt: Date? + public var userIcon = "" + public var userMessage = "" + public var userStatus = "" } -@objc public class NKSharee: NSObject { - - @objc public var circleInfo = "" - @objc public var circleOwner = "" - @objc public var label = "" - @objc public var name = "" - @objc public var shareType: Int = 0 - @objc public var shareWith = "" - @objc public var uuid = "" - @objc public var userClearAt: NSDate? - @objc public var userIcon = "" - @objc public var userMessage = "" - @objc public var userStatus = "" +public class NKTrash: NSObject { + public var contentType = "" + public var date = Date() + public var directory: Bool = false + public var fileId = "" + public var fileName = "" + public var filePath = "" + public var hasPreview: Bool = false + public var iconName = "" + public var size: Int64 = 0 + public var classFile = "" + public var trashbinFileName = "" + public var trashbinOriginalLocation = "" + public var trashbinDeletionTime = Date() } -@objc public class NKTrash: NSObject { - - @objc public var contentType = "" - @objc public var date = NSDate() - @objc public var directory: Bool = false - @objc public var fileId = "" - @objc public var fileName = "" - @objc public var filePath = "" - @objc public var hasPreview: Bool = false - @objc public var iconName = "" - @objc public var size: Int64 = 0 - @objc public var classFile = "" - @objc public var trashbinFileName = "" - @objc public var trashbinOriginalLocation = "" - @objc public var trashbinDeletionTime = NSDate() +public class NKUserProfile: NSObject { + public var address = "" + public var backend = "" + public var backendCapabilitiesSetDisplayName: Bool = false + public var backendCapabilitiesSetPassword: Bool = false + public var displayName = "" + public var email = "" + public var enabled: Bool = false + public var groups: [String] = [] + public var language = "" + public var lastLogin: Int64 = 0 + public var locale = "" + public var organisation = "" + public var phone = "" + public var quota: Int64 = 0 + public var quotaFree: Int64 = 0 + public var quotaRelative: Double = 0 + public var quotaTotal: Int64 = 0 + public var quotaUsed: Int64 = 0 + public var storageLocation = "" + public var subadmin: [String] = [] + public var twitter = "" + public var userId = "" + public var website = "" } -@objc public class NKUserProfile: NSObject { - - @objc public var address = "" - @objc public var backend = "" - @objc public var backendCapabilitiesSetDisplayName: Bool = false - @objc public var backendCapabilitiesSetPassword: Bool = false - @objc public var displayName = "" - @objc public var email = "" - @objc public var enabled: Bool = false - @objc public var groups: [String] = [] - @objc public var language = "" - @objc public var lastLogin: Int64 = 0 - @objc public var locale = "" - @objc public var organisation = "" - @objc public var phone = "" - @objc public var quota: Int64 = 0 - @objc public var quotaFree: Int64 = 0 - @objc public var quotaRelative: Double = 0 - @objc public var quotaTotal: Int64 = 0 - @objc public var quotaUsed: Int64 = 0 - @objc public var storageLocation = "" - @objc public var subadmin: [String] = [] - @objc public var twitter = "" - @objc public var userId = "" - @objc public var website = "" -} - -@objc public class NKUserStatus: NSObject { - - @objc public var clearAt: NSDate? - @objc public var clearAtTime: String? - @objc public var clearAtType: String? - @objc public var icon: String? - @objc public var id: String? - @objc public var message: String? - @objc public var predefined: Bool = false - @objc public var status: String? - @objc public var userId: String? +public class NKUserStatus: NSObject { + public var clearAt: Date? + public var clearAtTime: String? + public var clearAtType: String? + public var icon: String? + public var id: String? + public var message: String? + public var predefined: Bool = false + public var status: String? + public var userId: String? } // MARK: - Data File class NKDataFileXML: NSObject { let nkCommonInstance: NKCommon - let requestBodyComments = """ @@ -330,64 +361,17 @@ class NKDataFileXML: NSObject { """ - let propStandard = - """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """ - - lazy var requestBodyFile: String = { - return """ + func getRequestBodyFile(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + let request = """ - """ + propStandard + """ + """ + NKProperties.properties(createProperties: createProperties, removeProperties: removeProperties) + """ """ - }() + return request + } let requestBodyFileSetFavorite = """ @@ -401,28 +385,29 @@ class NKDataFileXML: NSObject { """ - lazy var requestBodyFileListingFavorites: String = { - return """ + func getRequestBodyFileListingFavorites(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + let request = """ - """ + propStandard + """ + """ + NKProperties.properties(createProperties: createProperties, removeProperties: removeProperties) + """ 1 """ - }() + return request + } - lazy var requestBodySearchFileName: String = { - return """ + func getRequestBodySearchFileName(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + let request = """ - """ + propStandard + """ + """ + NKProperties.properties(createProperties: createProperties, removeProperties: removeProperties) + """ @@ -440,16 +425,17 @@ class NKDataFileXML: NSObject { """ - }() + return request + } - lazy var requestBodySearchFileId: String = { - return """ + func getRequestBodySearchFileId(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + let request = """ - """ + propStandard + """ + """ + NKProperties.properties(createProperties: createProperties, removeProperties: removeProperties) + """ @@ -467,46 +453,17 @@ class NKDataFileXML: NSObject { """ - }() - - lazy var requestBodySearchLessThan: String = { - return """ - - - - - - """ + propStandard + """ - - - - - %@ - infinity - - - - - - %@ - - - - %@ - - - - """ - }() + return request + } - lazy var requestBodySearchMedia: String = { - return """ + func getRequestBodySearchMedia(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + let request = """ - """ + propStandard + """ + """ + NKProperties.properties(createProperties: createProperties, removeProperties: removeProperties) + """ @@ -554,16 +511,17 @@ class NKDataFileXML: NSObject { """ - }() + return request + } - lazy var requestBodySearchMediaWithLimit: String = { - return """ + func getRequestBodySearchMediaWithLimit(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String { + let request = """ - """ + propStandard + """ + """ + NKProperties.properties(createProperties: createProperties, removeProperties: removeProperties) + """ @@ -614,37 +572,15 @@ class NKDataFileXML: NSObject { """ - }() + return request + } let requestBodyTrash = """ - - - - - - - - - - - - - - - - - - - - - - - - + """ + NKProperties.trashProperties() + """ """ @@ -667,21 +603,19 @@ class NKDataFileXML: NSObject { } func convertDataAppPassword(data: Data) -> String? { - let xml = XML.parse(data) return xml["ocs", "data", "apppassword"].text } func convertDataFile(xmlData: Data, dav: String, urlBase: String, user: String, userId: String, showHiddenFiles: Bool, includeHiddenFiles: [String]) -> [NKFile] { - var files: [NKFile] = [] let rootFiles = "/" + dav + "/files/" guard let baseUrl = self.nkCommonInstance.getHostName(urlString: urlBase) else { return files } - let xml = XML.parse(xmlData) let elements = xml["d:multistatus", "d:response"] + for element in elements { let file = NKFile() if let href = element["d:href"].text { @@ -733,11 +667,11 @@ class NKDataFileXML: NSObject { } if let creationtime = propstat["d:prop", "nc:creation_time"].double, creationtime > 0 { - file.creationDate = NSDate(timeIntervalSince1970: creationtime) + file.creationDate = Date(timeIntervalSince1970: creationtime) } if let uploadtime = propstat["d:prop", "nc:upload_time"].double, uploadtime > 0 { - file.uploadDate = NSDate(timeIntervalSince1970: uploadtime) + file.uploadDate = Date(timeIntervalSince1970: uploadtime) } if let getetag = propstat["d:prop", "d:getetag"].text { @@ -958,15 +892,14 @@ class NKDataFileXML: NSObject { } func convertDataTrash(xmlData: Data, urlBase: String, showHiddenFiles: Bool) -> [NKTrash] { - var files: [NKTrash] = [] var first: Bool = true guard let baseUrl = self.nkCommonInstance.getHostName(urlString: urlBase) else { return files } - let xml = XML.parse(xmlData) let elements = xml["d:multistatus", "d:response"] + for element in elements { if first { first = false @@ -1027,7 +960,7 @@ class NKDataFileXML: NSObject { } if let trashbinDeletionTime = propstat["d:prop", "nc:trashbin-deletion-time"].text, let trashbinDeletionTimeDouble = Double(trashbinDeletionTime) { - file.trashbinDeletionTime = Date(timeIntervalSince1970: trashbinDeletionTimeDouble) as NSDate + file.trashbinDeletionTime = Date(timeIntervalSince1970: trashbinDeletionTimeDouble) } let results = self.nkCommonInstance.getInternalType(fileName: file.trashbinFileName, mimeType: file.contentType, directory: file.directory) @@ -1043,11 +976,10 @@ class NKDataFileXML: NSObject { } func convertDataComments(xmlData: Data) -> [NKComments] { - var items: [NKComments] = [] - let xml = XML.parse(xmlData) let elements = xml["d:multistatus", "d:response"] + for element in elements { let item = NKComments() diff --git a/Sources/NextcloudKit/NKRequestOptions.swift b/Sources/NextcloudKit/NKRequestOptions.swift index 961829d7..6c364b69 100644 --- a/Sources/NextcloudKit/NKRequestOptions.swift +++ b/Sources/NextcloudKit/NKRequestOptions.swift @@ -23,9 +23,7 @@ import Foundation -@objcMembers public class NKRequestOptions: NSObject { - var endpoint: String? var version: String? var customHeader: [String: String]? @@ -34,9 +32,11 @@ public class NKRequestOptions: NSObject { var e2eToken: String? var timeout: TimeInterval var taskDescription: String? + var createProperties: [NKProperties]? + var removeProperties: [NKProperties] var queue: DispatchQueue - public init(endpoint: String? = nil, + public init(endpoint: String? = nil, version: String? = nil, customHeader: [String: String]? = nil, customUserAgent: String? = nil, @@ -44,6 +44,8 @@ public class NKRequestOptions: NSObject { e2eToken: String? = nil, timeout: TimeInterval = 60, taskDescription: String? = nil, + createProperties: [NKProperties]? = nil, + removeProperties: [NKProperties] = [], queue: DispatchQueue = .main) { self.endpoint = endpoint @@ -54,6 +56,8 @@ public class NKRequestOptions: NSObject { self.e2eToken = e2eToken self.timeout = timeout self.taskDescription = taskDescription + self.createProperties = createProperties + self.removeProperties = removeProperties self.queue = queue } } diff --git a/Sources/NextcloudKit/NKShareAccounts.swift b/Sources/NextcloudKit/NKShareAccounts.swift index 16143a4e..b9b082bb 100644 --- a/Sources/NextcloudKit/NKShareAccounts.swift +++ b/Sources/NextcloudKit/NKShareAccounts.swift @@ -25,16 +25,14 @@ import Foundation #if os(iOS) import UIKit -@objc public class NKShareAccounts: NSObject { - - @objc public class DataAccounts: NSObject { - - @objc public var url: String - @objc public var user: String - @objc public var name: String? - @objc public var image: UIImage? - - @objc public init(withUrl url: String, user: String, name: String? = nil, image: UIImage? = nil) { +public class NKShareAccounts: NSObject { + public class DataAccounts: NSObject { + public var url: String + public var user: String + public var name: String? + public var image: UIImage? + + public init(withUrl url: String, user: String, name: String? = nil, image: UIImage? = nil) { self.url = url self.user = user self.name = name @@ -59,7 +57,7 @@ import UIKit /// - directory: the group directory of share the accounts (group.com.nextcloud.apps), use the func containerURL(forSecurityApplicationGroupIdentifier groupIdentifier: String) -> URL? // Available for OS X in 10.8.3. /// - app: the name of app /// - dataAccounts: the accounts data - @objc public func putShareAccounts(at directory: URL, app: String, dataAccounts: [DataAccounts]) -> Error? { + public func putShareAccounts(at directory: URL, app: String, dataAccounts: [DataAccounts]) -> Error? { var apps: [String: [Account]] = [:] var accounts: [Account] = [] @@ -105,7 +103,7 @@ import UIKit /// - Parameters: /// - directory: the group directory of share the accounts (group.com.nextcloud.apps), use the func containerURL(forSecurityApplicationGroupIdentifier groupIdentifier: String) -> URL? // Available for OS X in 10.8.3. /// - application: the UIApplication used for verify if the app(s) is still installed - @objc public func getShareAccount(at directory: URL, application: UIApplication) -> [DataAccounts]? { + public func getShareAccount(at directory: URL, application: UIApplication) -> [DataAccounts]? { var dataAccounts: [DataAccounts] = [] let url = directory.appendingPathComponent(directoryAccounts + "/" + fileName) diff --git a/Sources/NextcloudKit/API/NextcloudKit+API.swift b/Sources/NextcloudKit/NextcloudKit+API.swift similarity index 81% rename from Sources/NextcloudKit/API/NextcloudKit+API.swift rename to Sources/NextcloudKit/NextcloudKit+API.swift index 11bf82bb..6541a564 100644 --- a/Sources/NextcloudKit/API/NextcloudKit+API.swift +++ b/Sources/NextcloudKit/NextcloudKit+API.swift @@ -30,13 +30,29 @@ import UIKit import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func checkServer(serverUrl: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ error: NKError) -> Void) { +public class NKNotifications: NSObject { + public var actions: Data? + public var app = "" + public var date = Date() + public var icon: String? + public var idNotification: Int = 0 + public var link = "" + public var message = "" + public var messageRich = "" + public var messageRichParameters: Data? + public var objectId = "" + public var objectType = "" + public var subject = "" + public var subjectRich = "" + public var subjectRichParameters: Data? + public var user = "" +} +public extension NextcloudKit { + func checkServer(serverUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ error: NKError) -> Void) { guard let url = serverUrl.asUrl else { return options.queue.async { completion(.urlError) } } @@ -48,7 +64,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -61,21 +76,17 @@ extension NextcloudKit { // MARK: - - @objc public func generalWithEndpoint(_ endpoint: String, - method: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { - + func generalWithEndpoint(_ endpoint: String, + method: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, .urlError) } } - let method = HTTPMethod(rawValue: method.uppercased()) - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: method, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -85,7 +96,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -98,20 +108,16 @@ extension NextcloudKit { // MARK: - - @objc public func getExternalSite(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ externalFiles: [NKExternalSite], _ data: Data?, _ error: NKError) -> Void) { - + func getExternalSite(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ externalFiles: [NKExternalSite], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var externalSites: [NKExternalSite] = [] - let endpoint = "ocs/v2.php/apps/external/api/v1" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, externalSites, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -121,7 +127,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -131,14 +136,12 @@ extension NextcloudKit { let ocsdata = json["ocs"]["data"] for (_, subJson): (String, JSON) in ocsdata { let extrernalSite = NKExternalSite() - extrernalSite.icon = subJson["icon"].stringValue extrernalSite.idExternalSite = subJson["id"].intValue extrernalSite.lang = subJson["lang"].stringValue extrernalSite.name = subJson["name"].stringValue extrernalSite.type = subJson["type"].stringValue extrernalSite.url = subJson["url"].stringValue - externalSites.append(extrernalSite) } options.queue.async { completion(account, externalSites, jsonData, .success) } @@ -148,7 +151,7 @@ extension NextcloudKit { // MARK: - getServerStatus - public struct ServerInfo { + struct ServerInfo { public let installed: Bool public let maintenance: Bool public let needsDbUpgrade: Bool @@ -161,22 +164,19 @@ extension NextcloudKit { public let data: Data? } - public enum ServerInfoResult { + enum ServerInfoResult { case success(ServerInfo) case failure(NKError) } - public func getServerStatus(serverUrl: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (ServerInfoResult) -> Void) { - + func getServerStatus(serverUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (ServerInfoResult) -> Void) { let endpoint = "status.php" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(ServerInfoResult.failure(.urlError)) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -186,7 +186,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -216,7 +215,6 @@ extension NextcloudKit { versionMinor: versionMinor, versionMicro: versionMicro, data: jsonData) - options.queue.async { completion(ServerInfoResult.success(serverInfo)) } } } @@ -224,13 +222,11 @@ extension NextcloudKit { // MARK: - - @objc public func getPreview(url: URL, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { - + func getPreview(url: URL, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -240,7 +236,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -255,23 +250,22 @@ extension NextcloudKit { } } - public func downloadPreview(fileId: String, - fileNamePreviewLocalPath: String, - fileNameIconLocalPath: String? = nil, - widthPreview: Int = 512, - heightPreview: Int = 512, - sizeIcon: Int = 512, - compressionQualityPreview: CGFloat = 0.5, - compressionQualityIcon: CGFloat = 0.5, - etag: String? = nil, - crop: Int = 0, - cropMode: String = "fill", - forceIcon: Int = 1, - mimeFallback: Int = 0, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ imagePreview: UIImage?, _ imageIcon: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { - + func downloadPreview(fileId: String, + fileNamePreviewLocalPath: String, + fileNameIconLocalPath: String? = nil, + widthPreview: Int = 512, + heightPreview: Int = 512, + sizeIcon: Int = 512, + compressionQualityPreview: CGFloat = 0.5, + compressionQualityIcon: CGFloat = 0.5, + etag: String? = nil, + crop: Int = 1, + cropMode: String = "cover", + forceIcon: Int = 0, + mimeFallback: Int = 0, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ imagePreview: UIImage?, _ imageIcon: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { let endpoint = "index.php/core/preview?fileId=\(fileId)&x=\(widthPreview)&y=\(heightPreview)&a=\(crop)&mode=\(cropMode)&forceIcon=\(forceIcon)&mimeFallback=\(mimeFallback)" downloadPreview(fileNamePreviewLocalPath: fileNamePreviewLocalPath, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: sizeIcon, compressionQualityPreview: compressionQualityPreview, compressionQualityIcon: compressionQualityIcon, etag: etag, endpoint: endpoint, options: options) { task in @@ -281,22 +275,21 @@ extension NextcloudKit { } } - public func downloadTrashPreview(fileId: String, - fileNamePreviewLocalPath: String, - fileNameIconLocalPath: String, - widthPreview: Int = 512, - heightPreview: Int = 512, - sizeIcon: Int = 512, - compressionQualityPreview: CGFloat = 0.5, - compressionQualityIcon: CGFloat = 0.5, - crop: Int = 0, - cropMode: String = "fill", - forceIcon: Int = 1, - mimeFallback: Int = 0, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ imagePreview: UIImage?, _ imageIcon: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { - + func downloadTrashPreview(fileId: String, + fileNamePreviewLocalPath: String, + fileNameIconLocalPath: String, + widthPreview: Int = 512, + heightPreview: Int = 512, + sizeIcon: Int = 512, + compressionQualityPreview: CGFloat = 0.5, + compressionQualityIcon: CGFloat = 0.5, + crop: Int = 1, + cropMode: String = "cover", + forceIcon: Int = 0, + mimeFallback: Int = 0, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ imagePreview: UIImage?, _ imageIcon: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { let endpoint = "index.php/apps/files_trashbin/preview?fileId=\(fileId)&x=\(widthPreview)&y=\(heightPreview)&a=\(crop)&mode=\(cropMode)&forceIcon=\(forceIcon)&mimeFallback=\(mimeFallback)" downloadPreview(fileNamePreviewLocalPath: fileNamePreviewLocalPath, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: sizeIcon, compressionQualityPreview: compressionQualityPreview, compressionQualityIcon: compressionQualityIcon, etag: nil, endpoint: endpoint, options: options) { task in @@ -316,19 +309,15 @@ extension NextcloudKit { options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, completion: @escaping (_ account: String, _ imagePreview: UIImage?, _ imageIcon: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { - let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var url: URLConvertible? - if let endpoint { url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) } - guard let urlRequest = url else { return options.queue.async { completion(account, nil, nil, nil, nil, .urlError) } } - var headers = self.nkCommonInstance.getStandardHeaders(options: options) if var etag = etag { etag = "\"" + etag + "\"" @@ -342,7 +331,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -358,11 +346,11 @@ extension NextcloudKit { try data.write(to: URL(fileURLWithPath: fileNamePreviewLocalPath), options: .atomic) imagePreview = UIImage(data: data) } - if fileNameIconLocalPath != nil && sizeIcon > 0 { - imageIcon = imageOriginal.resizeImage(size: CGSize(width: sizeIcon, height: sizeIcon), isAspectRation: true) + if let fileNameIconLocalPath, sizeIcon > 0 { + imageIcon = imageOriginal.resizeImage(size: CGSize(width: sizeIcon, height: sizeIcon)) if let data = imageIcon?.jpegData(compressionQuality: compressionQualityIcon) { - try data.write(to: URL(fileURLWithPath: fileNameIconLocalPath!), options: .atomic) - imageIcon = UIImage(data: data)! + try data.write(to: URL(fileURLWithPath: fileNameIconLocalPath), options: .atomic) + imageIcon = UIImage(data: data) } } options.queue.async { completion(account, imagePreview, imageIcon, imageOriginal, etag, .success) } @@ -373,24 +361,20 @@ extension NextcloudKit { } } - @objc public func downloadAvatar(user: String, - fileNameLocalPath: String, - sizeImage: Int, - avatarSizeRounded: Int = 0, - etag: String?, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ imageAvatar: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { - + func downloadAvatar(user: String, + fileNameLocalPath: String, + sizeImage: Int, + avatarSizeRounded: Int = 0, + etag: String?, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ imageAvatar: UIImage?, _ imageOriginal: UIImage?, _ etag: String?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "index.php/avatar/\(user)/\(sizeImage)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, nil, .urlError) } } - var headers = self.nkCommonInstance.getStandardHeaders(options: options) if var etag = etag { etag = "\"" + etag + "\"" @@ -404,7 +388,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -469,17 +452,14 @@ extension NextcloudKit { } } - @objc public func downloadContent(serverUrl: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { - + func downloadContent(serverUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrl.asUrl else { return options.queue.async { completion(account, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -489,7 +469,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -506,19 +485,15 @@ extension NextcloudKit { // MARK: - - @objc public func getUserProfile(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ userProfile: NKUserProfile?, _ data: Data?, _ error: NKError) -> Void) { - + func getUserProfile(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ userProfile: NKUserProfile?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/cloud/user" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -528,7 +503,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -539,9 +513,7 @@ extension NextcloudKit { let data = ocs["data"] if json["ocs"]["meta"]["statuscode"].int == 200 { - let userProfile = NKUserProfile() - userProfile.address = data["address"].stringValue userProfile.backend = data["backend"].stringValue userProfile.backendCapabilitiesSetDisplayName = data["backendCapabilities"]["setDisplayName"].boolValue @@ -575,7 +547,6 @@ extension NextcloudKit { userProfile.website = data["website"].stringValue options.queue.async { completion(account, userProfile, jsonData, .success) } - } else { options.queue.async { completion(account, nil, jsonData, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } } @@ -583,19 +554,15 @@ extension NextcloudKit { } } - @objc public func getCapabilities(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { - + func getCapabilities(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v1.php/cloud/capabilities" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -605,7 +572,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -622,20 +588,15 @@ extension NextcloudKit { // MARK: - - @objc public func getRemoteWipeStatus(serverUrl: String, - token: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ wipe: Bool, _ data: Data?, _ error: NKError) -> Void) { - + func getRemoteWipeStatus(serverUrl: String, + token: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ wipe: Bool, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - let endpoint = "index.php/core/wipe/check" - let parameters: [String: Any] = ["token": token] - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/json") - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(account, false, nil, .urlError) } } @@ -647,7 +608,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -660,20 +620,15 @@ extension NextcloudKit { } } - @objc public func setRemoteWipeCompletition(serverUrl: String, - token: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func setRemoteWipeCompletition(serverUrl: String, + token: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - let endpoint = "index.php/core/wipe/success" - let parameters: [String: Any] = ["token": token] - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/json") - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } @@ -685,7 +640,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -698,23 +652,20 @@ extension NextcloudKit { // MARK: - - @objc public func getActivity(since: Int, - limit: Int, - objectId: String?, - objectType: String?, - previews: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ activities: [NKActivity], _ activityFirstKnown: Int, _ activityLastGiven: Int, _ data: Data?, _ error: NKError) -> Void) { - + func getActivity(since: Int, + limit: Int, + objectId: String?, + objectType: String?, + previews: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ activities: [NKActivity], _ activityFirstKnown: Int, _ activityLastGiven: Int, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var activities: [NKActivity] = [] var activityFirstKnown = 0 var activityLastGiven = 0 - var endpoint = "ocs/v2.php/apps/activity/api/v2/activity/" - var parameters: [String: Any] = [ "format": "json", "since": String(since), @@ -736,7 +687,6 @@ extension NextcloudKit { guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, activities, activityFirstKnown, activityLastGiven, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -746,7 +696,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -805,21 +754,16 @@ extension NextcloudKit { // MARK: - - @objc public func getNotifications(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ notifications: [NKNotifications]?, _ data: Data?, _ error: NKError) -> Void) { - + func getNotifications(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ notifications: [NKNotifications]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/notifications/api/v2/notifications" - var notifications: [NKNotifications] = [] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -829,7 +773,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -849,7 +792,7 @@ extension NextcloudKit { notification.app = subJson["app"].stringValue if let datetime = subJson["datetime"].string { if let date = self.nkCommonInstance.convertDate(datetime, format: "yyyy-MM-dd'T'HH:mm:ssZZZZZ") { - notification.date = date + notification.date = date as Date } } notification.icon = subJson["icon"].string @@ -872,42 +815,34 @@ extension NextcloudKit { } catch {} } notification.user = subJson["user"].stringValue - notifications.append(notification) } - options.queue.async { completion(account, notifications, jsonData, .success) } - } else { - options.queue.async { completion(account, nil, jsonData, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } } } } } - @objc public func setNotification(serverUrl: String?, - idNotification: Int, - method: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func setNotification(serverUrl: String?, + idNotification: Int, + method: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var url: URLConvertible? - if serverUrl == nil { let endpoint = "ocs/v2.php/apps/notifications/api/v2/notifications/\(idNotification)" url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) } else { - url = serverUrl!.asUrl + url = serverUrl?.asUrl } - guard let urlRequest = url else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: method) let headers = self.nkCommonInstance.getStandardHeaders(options: options) @@ -918,7 +853,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -931,25 +865,20 @@ extension NextcloudKit { // MARK: - - @objc public func getDirectDownload(fileId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getDirectDownload(fileId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/dav/api/v1/direct" - let parameters: [String: Any] = [ "fileId": fileId, "format": "json" ] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -959,7 +888,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -975,22 +903,17 @@ extension NextcloudKit { // MARK: - - public func sendClientDiagnosticsRemoteOperation(data: Data, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func sendClientDiagnosticsRemoteOperation(data: Data, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/security_guard/diagnostics" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/json") - var urlRequest: URLRequest do { try urlRequest = URLRequest(url: url, method: .put, headers: headers) @@ -1006,7 +929,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit+Assistant.swift b/Sources/NextcloudKit/NextcloudKit+Assistant.swift index 900e4fc1..7f889c55 100644 --- a/Sources/NextcloudKit/NextcloudKit+Assistant.swift +++ b/Sources/NextcloudKit/NextcloudKit+Assistant.swift @@ -25,20 +25,16 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - public func textProcessingGetTypes(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ types: [NKTextProcessingTaskType]?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func textProcessingGetTypes(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ types: [NKTextProcessingTaskType]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/textprocessing/tasktypes" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -48,7 +44,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -67,23 +62,19 @@ extension NextcloudKit { } } - public func textProcessingSchedule(input: String, - typeId: String, - appId: String = "assistant", - identifier: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ task: NKTextProcessingTask?, _ data: Data?, _ error: NKError) -> Void) { - + func textProcessingSchedule(input: String, + typeId: String, + appId: String = "assistant", + identifier: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ task: NKTextProcessingTask?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "/ocs/v2.php/textprocessing/schedule" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) let parameters: [String: Any] = ["input": input, "type": typeId, "appId": appId, "identifier": identifier] @@ -94,7 +85,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -113,20 +103,16 @@ extension NextcloudKit { } } - public func textProcessingGetTask(taskId: Int, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ task: NKTextProcessingTask?, _ data: Data?, _ error: NKError) -> Void) { - + func textProcessingGetTask(taskId: Int, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ task: NKTextProcessingTask?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "/ocs/v2.php/textprocessing/task/\(taskId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -136,7 +122,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -155,20 +140,16 @@ extension NextcloudKit { } } - public func textProcessingDeleteTask(taskId: Int, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ task: NKTextProcessingTask?, _ data: Data?, _ error: NKError) -> Void) { - + func textProcessingDeleteTask(taskId: Int, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ task: NKTextProcessingTask?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "/ocs/v2.php/textprocessing/task/\(taskId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .delete, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -178,7 +159,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -197,20 +177,16 @@ extension NextcloudKit { } } - public func textProcessingTaskList(appId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ task: [NKTextProcessingTask]?, _ data: Data?, _ error: NKError) -> Void) { - + func textProcessingTaskList(appId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ task: [NKTextProcessingTask]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "/ocs/v2.php/textprocessing/tasks/app/\(appId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -220,7 +196,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -251,7 +226,7 @@ public class NKTextProcessingTaskType { self.description = description } - init?(json: JSON) { + public init?(json: JSON) { self.id = json["id"].string self.name = json["name"].string self.description = json["description"].string @@ -286,7 +261,7 @@ public class NKTextProcessingTask { self.completionExpectedAt = completionExpectedAt } - init?(json: JSON) { + public init?(json: JSON) { self.id = json["id"].int self.type = json["type"].string self.status = json["status"].int diff --git a/Sources/NextcloudKit/NextcloudKit+Comments.swift b/Sources/NextcloudKit/NextcloudKit+Comments.swift index 447e22e1..d0257196 100644 --- a/Sources/NextcloudKit/NextcloudKit+Comments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Comments.swift @@ -24,26 +24,22 @@ import Foundation import Alamofire -extension NextcloudKit { - - @objc public func getComments(fileId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ items: [NKComments]?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func getComments(fileId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ items: [NKComments]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav let serverUrlEndpoint = urlBase + "/" + dav + "/comments/files/\(fileId)" - guard let url = serverUrlEndpoint.encodedToUrl else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let method = HTTPMethod(rawValue: "PROPFIND") let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) urlRequest.httpBody = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyComments.data(using: .utf8) @@ -74,24 +70,21 @@ extension NextcloudKit { } } - @objc public func putComments(fileId: String, - message: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func putComments(fileId: String, + message: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav let serverUrlEndpoint = urlBase + "/" + dav + "/comments/files/\(fileId)" - guard let url = serverUrlEndpoint.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/json") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: .post, headers: headers) let parameters = "{\"actorType\":\"users\",\"verb\":\"comment\",\"message\":\"" + message + "\"}" @@ -118,26 +111,23 @@ extension NextcloudKit { } } - @objc public func updateComments(fileId: String, - messageId: String, - message: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func updateComments(fileId: String, + messageId: String, + message: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav let serverUrlEndpoint = urlBase + "/" + dav + "/comments/files/\(fileId)/\(messageId)" - guard let url = serverUrlEndpoint.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: "PROPPATCH") let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) let parameters = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyCommentsUpdate, message) @@ -164,21 +154,18 @@ extension NextcloudKit { } } - @objc public func deleteComments(fileId: String, - messageId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func deleteComments(fileId: String, + messageId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav let serverUrlEndpoint = urlBase + "/" + dav + "/comments/files/\(fileId)/\(messageId)" - guard let url = serverUrlEndpoint.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -199,24 +186,21 @@ extension NextcloudKit { } } - @objc public func markAsReadComments(fileId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func markAsReadComments(fileId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav let serverUrlEndpoint = urlBase + "/" + dav + "/comments/files/\(fileId)" - guard let url = serverUrlEndpoint.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: "PROPPATCH") let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) let parameters = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyCommentsMarkAsRead) diff --git a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift index 205f6f13..280f17ce 100644 --- a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift +++ b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift @@ -25,28 +25,23 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - public func getDashboardWidget(options: NKRequestOptions = NKRequestOptions(), - request: @escaping (DataRequest?) -> Void = { _ in }, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ dashboardWidgets: [NCCDashboardWidget]?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func getDashboardWidget(options: NKRequestOptions = NKRequestOptions(), + request: @escaping (DataRequest?) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ dashboardWidgets: [NCCDashboardWidget]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var url: URLConvertible? - if let endpoint = options.endpoint { url = URL(string: endpoint) } else { let endpoint = "ocs/v2.php/apps/dashboard/api/v1/widgets" url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) } - guard let url = url else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) let dashboardRequest = sessionManager.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -56,7 +51,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .success(let jsonData): let json = JSON(jsonData) @@ -76,27 +70,23 @@ extension NextcloudKit { options.queue.async { request(dashboardRequest) } } - public func getDashboardWidgetsApplication(_ items: String, - options: NKRequestOptions = NKRequestOptions(), - request: @escaping (DataRequest?) -> Void = { _ in }, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ dashboardApplications: [NCCDashboardApplication]?, _ data: Data?, _ error: NKError) -> Void) { - + func getDashboardWidgetsApplication(_ items: String, + options: NKRequestOptions = NKRequestOptions(), + request: @escaping (DataRequest?) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ dashboardApplications: [NCCDashboardApplication]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var url: URLConvertible? - if let endpoint = options.endpoint { url = URL(string: endpoint) } else { let endpoint = "ocs/v2.php/apps/dashboard/api/v1/widget-items?widgets[]=\(items)" url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) } - guard let url = url else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) let dashboardRequest = sessionManager.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -106,7 +96,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .success(let jsonData): let json = JSON(jsonData) @@ -127,10 +116,10 @@ extension NextcloudKit { } } -@objc public class NCCDashboardApplication: NSObject { +public class NCCDashboardApplication: NSObject { - @objc public var application: String? - @objc public var items: [NCCDashboardItem]? + public var application: String? + public var items: [NCCDashboardItem]? init?(application: String, data: JSON) { self.application = application @@ -148,13 +137,12 @@ extension NextcloudKit { } } -@objc public class NCCDashboardItem: NSObject { - - @objc public let title: String? - @objc public let subtitle: String? - @objc public let link: String? - @objc public let iconUrl: String? - @objc public let sinceId: Int +public class NCCDashboardItem: NSObject { + public let title: String? + public let subtitle: String? + public let link: String? + public let iconUrl: String? + public let sinceId: Int init?(json: JSON) { self.title = json["title"].string @@ -170,13 +158,12 @@ extension NextcloudKit { } } -@objc public class NCCDashboardWidget: NSObject { - - @objc public var id, title: String - @objc public let order: Int - @objc public let iconClass, iconUrl, widgetUrl: String? - @objc public let itemIconsRound: Bool - @objc public let button: [NCCDashboardWidgetButton]? +public class NCCDashboardWidget: NSObject { + public var id, title: String + public let order: Int + public let iconClass, iconUrl, widgetUrl: String? + public let itemIconsRound: Bool + public let button: [NCCDashboardWidgetButton]? init?(application: String, data: JSON) { guard let id = data["id"].string, @@ -204,9 +191,8 @@ extension NextcloudKit { } } -@objc public class NCCDashboardWidgetButton: NSObject { - - @objc public let type, text, link: String +public class NCCDashboardWidgetButton: NSObject { + public let type, text, link: String init?(data: JSON) { guard let type = data["type"].string, diff --git a/Sources/NextcloudKit/E2EE/NextcloudKit+E2EE.swift b/Sources/NextcloudKit/NextcloudKit+E2EE.swift similarity index 83% rename from Sources/NextcloudKit/E2EE/NextcloudKit+E2EE.swift rename to Sources/NextcloudKit/NextcloudKit+E2EE.swift index 333f53ff..f4711fca 100644 --- a/Sources/NextcloudKit/E2EE/NextcloudKit+E2EE.swift +++ b/Sources/NextcloudKit/NextcloudKit+E2EE.swift @@ -25,29 +25,23 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func markE2EEFolder(fileId: String, - delete: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func markE2EEFolder(fileId: String, + delete: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/encrypted/\(fileId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let method: HTTPMethod = delete ? .delete : .put - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: method, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -57,7 +51,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -74,29 +67,24 @@ extension NextcloudKit { } } - @objc public func lockE2EEFolder(fileId: String, - e2eToken: String?, - e2eCounter: String?, - method: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ e2eToken: String?, _ data: Data?, _ error: NKError) -> Void) { - + func lockE2EEFolder(fileId: String, + e2eToken: String?, + e2eCounter: String?, + method: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ e2eToken: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/lock/\(fileId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let method = HTTPMethod(rawValue: method) - var headers = self.nkCommonInstance.getStandardHeaders(options: options) var parameters: [String: Any] = [:] @@ -115,7 +103,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -133,25 +120,21 @@ extension NextcloudKit { } } - @objc public func getE2EEMetadata(fileId: String, - e2eToken: String?, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ e2eMetadata: String?, _ signature: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getE2EEMetadata(fileId: String, + e2eToken: String?, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ e2eMetadata: String?, _ signature: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/meta-data/\(fileId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) var parameters: [String: Any] = [:] @@ -166,7 +149,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -185,30 +167,25 @@ extension NextcloudKit { } } - @objc public func putE2EEMetadata(fileId: String, - e2eToken: String, - e2eMetadata: String?, - signature: String?, - method: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ metadata: String?, _ data: Data?, _ error: NKError) -> Void) { - + func putE2EEMetadata(fileId: String, + e2eToken: String, + e2eMetadata: String?, + signature: String?, + method: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ metadata: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/meta-data/\(fileId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let method = HTTPMethod(rawValue: method) - var headers = self.nkCommonInstance.getStandardHeaders(options: options) var parameters: [String: Any] = [:] @@ -229,7 +206,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -249,21 +225,18 @@ extension NextcloudKit { // MARK: - - @objc public func getE2EECertificate(user: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ certificate: String?, _ certificateUser: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getE2EECertificate(user: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ certificate: String?, _ certificateUser: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase let userId = self.nkCommonInstance.userId - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } var endpoint = "" - if let user = user { guard let users = ("[\"" + user + "\"]").urlEncoded else { return options.queue.async { completion(account, nil, nil, nil, .urlError) } @@ -272,11 +245,9 @@ extension NextcloudKit { } else { endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/public-key" } - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -286,7 +257,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -309,23 +279,19 @@ extension NextcloudKit { } } - @objc public func getE2EEPrivateKey(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ privateKey: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getE2EEPrivateKey(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ privateKey: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/private-key" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -335,7 +301,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -353,23 +318,19 @@ extension NextcloudKit { } } - @objc public func getE2EEPublicKey(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ publicKey: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getE2EEPublicKey(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ publicKey: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/server-key" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -379,7 +340,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -397,26 +357,21 @@ extension NextcloudKit { } } - @objc public func signE2EECertificate(certificate: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ certificate: String?, _ data: Data?, _ error: NKError) -> Void) { - + func signE2EECertificate(certificate: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ certificate: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/public-key" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - let parameters = ["csr": certificate] sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -426,7 +381,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -445,26 +399,21 @@ extension NextcloudKit { } } - @objc public func storeE2EEPrivateKey(privateKey: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ privateKey: String?, _ data: Data?, _ error: NKError) -> Void) { - + func storeE2EEPrivateKey(privateKey: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ privateKey: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/private-key" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - let parameters = ["privateKey": privateKey] sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -474,7 +423,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -492,23 +440,19 @@ extension NextcloudKit { } } - @objc public func deleteE2EECertificate(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func deleteE2EECertificate(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/public-key" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -518,7 +462,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -529,23 +472,19 @@ extension NextcloudKit { } } - @objc public func deleteE2EEPrivateKey(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func deleteE2EEPrivateKey(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var version = "v1" if let optionsVesion = options.version { version = optionsVesion } let endpoint = "ocs/v2.php/apps/end_to_end_encryption/api/\(version)/private-key" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -555,7 +494,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift index f3faa608..d4b7f0d2 100644 --- a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift +++ b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift @@ -26,24 +26,18 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - // available in NC >= 24 - @objc public func lockUnlockFile(serverUrlFileName: String, - shouldLock: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func lockUnlockFile(serverUrlFileName: String, + shouldLock: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: shouldLock ? "LOCK" : "UNLOCK") - var headers = self.nkCommonInstance.getStandardHeaders(options: options) headers.update(name: "X-User-Lock", value: "1") @@ -54,7 +48,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift index 8ebb27ed..68b63269 100644 --- a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift +++ b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift @@ -25,22 +25,17 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func getGroupfolders(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ results: [NKGroupfolders]?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func getGroupfolders(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ results: [NKGroupfolders]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "index.php/apps/groupfolders/folders?applicable=1" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -50,7 +45,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -76,17 +70,16 @@ extension NextcloudKit { } } -@objc public class NKGroupfolders: NSObject { - - @objc public let id: Int - @objc public let mountPoint: String - @objc public let acl: Bool - @objc public let size: Int - @objc public let quota: Int - @objc public let manage: Data? - @objc public let groups: [String: Any]? +public class NKGroupfolders: NSObject { + public let id: Int + public let mountPoint: String + public let acl: Bool + public let size: Int + public let quota: Int + public let manage: Data? + public let groups: [String: Any]? - internal init?(json: JSON) { + init?(json: JSON) { guard let id = json["id"].int, let mountPoint = json["mount_point"].string, let acl = json["acl"].bool, diff --git a/Sources/NextcloudKit/NextcloudKit+Hovercard.swift b/Sources/NextcloudKit/NextcloudKit+Hovercard.swift index 9b858c16..9509295c 100644 --- a/Sources/NextcloudKit/NextcloudKit+Hovercard.swift +++ b/Sources/NextcloudKit/NextcloudKit+Hovercard.swift @@ -26,23 +26,18 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func getHovercard(for userId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ result: NKHovercard?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func getHovercard(for userId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ result: NKHovercard?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/hovercard/v1/\(userId)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -52,7 +47,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -73,8 +67,11 @@ extension NextcloudKit { } } -@objc public class NKHovercard: NSObject { - internal init?(jsonData: JSON) { +public class NKHovercard: NSObject { + public let userId, displayName: String + public let actions: [Action] + + init?(jsonData: JSON) { guard let userId = jsonData["userId"].string, let displayName = jsonData["displayName"].string, let actions = jsonData["actions"].array?.compactMap(Action.init) @@ -86,8 +83,14 @@ extension NextcloudKit { self.actions = actions } - @objc public class Action: NSObject { - internal init?(jsonData: JSON) { + public class Action: NSObject { + public let title: String + public let icon: String + public let hyperlink: String + public var hyperlinkUrl: URL? { URL(string: hyperlink) } + public let appId: String + + init?(jsonData: JSON) { guard let title = jsonData["title"].string, let icon = jsonData["icon"].string, let hyperlink = jsonData["hyperlink"].string, @@ -100,14 +103,5 @@ extension NextcloudKit { self.hyperlink = hyperlink self.appId = appId } - - @objc public let title: String - @objc public let icon: String - @objc public let hyperlink: String - @objc public var hyperlinkUrl: URL? { URL(string: hyperlink) } - @objc public let appId: String } - - @objc public let userId, displayName: String - @objc public let actions: [Action] } diff --git a/Sources/NextcloudKit/NextcloudKit+Livephoto.swift b/Sources/NextcloudKit/NextcloudKit+Livephoto.swift index 1c79250a..6f589252 100644 --- a/Sources/NextcloudKit/NextcloudKit+Livephoto.swift +++ b/Sources/NextcloudKit/NextcloudKit+Livephoto.swift @@ -24,24 +24,20 @@ import Foundation import Alamofire -extension NextcloudKit { - - public func setLivephoto(serverUrlfileNamePath: String, - livePhotoFile: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func setLivephoto(serverUrlfileNamePath: String, + livePhotoFile: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrlfileNamePath.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: "PROPPATCH") let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) let parameters = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyLivephoto, livePhotoFile) @@ -57,7 +53,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -67,16 +62,4 @@ extension NextcloudKit { } } } - - @available(iOS 13.0, *) - public func setLivephoto(serverUrlfileNamePath: String, - livePhotoFile: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - setLivephoto(serverUrlfileNamePath: serverUrlfileNamePath, livePhotoFile: livePhotoFile, options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } } diff --git a/Sources/NextcloudKit/NextcloudKit+Login.swift b/Sources/NextcloudKit/NextcloudKit+Login.swift index 52ef2468..e67c712d 100644 --- a/Sources/NextcloudKit/NextcloudKit+Login.swift +++ b/Sources/NextcloudKit/NextcloudKit+Login.swift @@ -25,31 +25,26 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - +public extension NextcloudKit { // MARK: - App Password - - @objc public func getAppPassword(serverUrl: String, - username: String, - password: String, - userAgent: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ token: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getAppPassword(serverUrl: String, + username: String, + password: String, + userAgent: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ token: String?, _ data: Data?, _ error: NKError) -> Void) { let endpoint = "ocs/v2.php/core/getapppassword" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(nil, nil, .urlError) } } - var headers: HTTPHeaders = [.authorization(username: username, password: password)] if let userAgent = userAgent { headers.update(.userAgent(userAgent)) } headers.update(name: "OCS-APIRequest", value: "true") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: HTTPMethod(rawValue: "GET"), headers: headers) } catch { @@ -63,7 +58,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -79,27 +73,24 @@ extension NextcloudKit { } } - @objc public func deleteAppPassword(serverUrl: String, - username: String, - password: String, - userAgent: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ data: Data?, _ error: NKError) -> Void) { - + func deleteAppPassword(serverUrl: String, + username: String, + password: String, + userAgent: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ data: Data?, _ error: NKError) -> Void) { let endpoint = "ocs/v2.php/core/apppassword" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(nil, .urlError) } } - var headers: HTTPHeaders = [.authorization(username: username, password: password)] if let userAgent = userAgent { headers.update(.userAgent(userAgent)) } headers.update(name: "OCS-APIRequest", value: "true") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: HTTPMethod(rawValue: "DELETE"), headers: headers) } catch { @@ -113,7 +104,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -126,20 +116,16 @@ extension NextcloudKit { // MARK: - Login Flow V2 - @objc public func getLoginFlowV2(serverUrl: String, - userAgent: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ token: String?, _ endpoint: String?, _ login: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getLoginFlowV2(serverUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ token: String?, _ endpoint: String?, _ login: String?, _ data: Data?, _ error: NKError) -> Void) { let endpoint = "index.php/login/v2" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(nil, nil, nil, nil, .urlError) } } - var headers: HTTPHeaders? - if let userAgent = userAgent { + if let userAgent = options.customUserAgent { headers = [HTTPHeader.userAgent(userAgent)] } @@ -150,7 +136,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -167,21 +152,17 @@ extension NextcloudKit { } } - @objc public func getLoginFlowV2Poll(token: String, - endpoint: String, - userAgent: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ server: String?, _ loginName: String?, _ appPassword: String?, _ data: Data?, _ error: NKError) -> Void) { - + func getLoginFlowV2Poll(token: String, + endpoint: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ server: String?, _ loginName: String?, _ appPassword: String?, _ data: Data?, _ error: NKError) -> Void) { let serverUrl = endpoint + "?token=" + token - guard let url = serverUrl.asUrl else { return options.queue.async { completion(nil, nil, nil, nil, .urlError) } } - var headers: HTTPHeaders? - if let userAgent = userAgent { + if let userAgent = options.customUserAgent { headers = [HTTPHeader.userAgent(userAgent)] } @@ -192,14 +173,12 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) options.queue.async { completion(nil, nil, nil, nil, error) } case .success(let jsonData): let json = JSON(jsonData) - let server = json["server"].string let loginName = json["loginName"].string let appPassword = json["appPassword"].string diff --git a/Sources/NextcloudKit/NextcloudKit+NCText.swift b/Sources/NextcloudKit/NextcloudKit+NCText.swift index c7f5b096..7639ac2a 100644 --- a/Sources/NextcloudKit/NextcloudKit+NCText.swift +++ b/Sources/NextcloudKit/NextcloudKit+NCText.swift @@ -25,24 +25,18 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func NCTextObtainEditorDetails(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ editors: [NKEditorDetailsEditors], _ creators: [NKEditorDetailsCreators], _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func NCTextObtainEditorDetails(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ editors: [NKEditorDetailsEditors], _ creators: [NKEditorDetailsCreators], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/files/api/v1/directEditing" - var editors: [NKEditorDetailsEditors] = [] var creators: [NKEditorDetailsCreators] = [] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, editors, creators, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -52,7 +46,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -88,7 +81,6 @@ extension NextcloudKit { creator.mimetype = subJson["mimetype"].stringValue creator.name = subJson["name"].stringValue creator.templates = subJson["templates"].intValue - creators.append(creator) } @@ -97,29 +89,24 @@ extension NextcloudKit { } } - @objc public func NCTextOpenFile(fileNamePath: String, - fileId: String? = nil, - editor: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { - + func NCTextOpenFile(fileNamePath: String, + fileId: String? = nil, + editor: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - guard let fileNamePath = fileNamePath.urlEncoded else { return options.queue.async { completion(account, nil, nil, .urlError) } } - var endpoint = "ocs/v2.php/apps/files/api/v1/directEditing/open?path=/\(fileNamePath)&editorId=\(editor)" if let fileId = fileId { endpoint = "ocs/v2.php/apps/files/api/v1/directEditing/open?path=/\(fileNamePath)&fileId=\(fileId)&editorId=\(editor)" } - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .post, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -129,7 +116,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -142,21 +128,16 @@ extension NextcloudKit { } } - @objc public func NCTextGetListOfTemplates(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ templates: [NKEditorTemplates], _ data: Data?, _ error: NKError) -> Void) { - + func NCTextGetListOfTemplates(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ templates: [NKEditorTemplates], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/files/api/v1/directEditing/templates/text/textdocumenttemplate" - var templates: [NKEditorTemplates] = [] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, templates, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -166,7 +147,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -182,7 +162,6 @@ extension NextcloudKit { template.identifier = subJson["id"].stringValue template.name = subJson["name"].stringValue template.preview = subJson["preview"].stringValue - templates.append(template) } @@ -191,33 +170,27 @@ extension NextcloudKit { } } - @objc public func NCTextCreateFile(fileNamePath: String, - editorId: String, - creatorId: String, - templateId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { - + func NCTextCreateFile(fileNamePath: String, + editorId: String, + creatorId: String, + templateId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - guard let fileNamePath = fileNamePath.urlEncoded else { return options.queue.async { completion(account, nil, nil, .urlError) } } - var endpoint = "" - if templateId.isEmpty { endpoint = "ocs/v2.php/apps/files/api/v1/directEditing/create?path=/\(fileNamePath)&editorId=\(editorId)&creatorId=\(creatorId)" } else { endpoint = "ocs/v2.php/apps/files/api/v1/directEditing/create?path=/\(fileNamePath)&editorId=\(editorId)&creatorId=\(creatorId)&templateId=\(templateId)" } - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .post, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -227,7 +200,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit+PushNotification.swift b/Sources/NextcloudKit/NextcloudKit+PushNotification.swift index 134e9b2c..003f063a 100644 --- a/Sources/NextcloudKit/NextcloudKit+PushNotification.swift +++ b/Sources/NextcloudKit/NextcloudKit+PushNotification.swift @@ -25,31 +25,26 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func subscribingPushNotification(serverUrl: String, - account: String, - user: String, - password: String, - pushTokenHash: String, - devicePublicKey: String, - proxyServerUrl: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ deviceIdentifier: String?, _ signature: String?, _ publicKey: String?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func subscribingPushNotification(serverUrl: String, + account: String, + user: String, + password: String, + pushTokenHash: String, + devicePublicKey: String, + proxyServerUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ deviceIdentifier: String?, _ signature: String?, _ publicKey: String?, _ data: Data?, _ error: NKError) -> Void) { let endpoint = "ocs/v2.php/apps/notifications/api/v2/push" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, nil, nil, .urlError) } } - let parameters = [ "pushTokenHash": pushTokenHash, "devicePublicKey": devicePublicKey, "proxyServer": proxyServerUrl ] - let headers = self.nkCommonInstance.getStandardHeaders(user: user, password: password, appendHeaders: options.customHeader, customUserAgent: options.customUserAgent) sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -59,7 +54,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -79,20 +73,17 @@ extension NextcloudKit { } } - @objc public func unsubscribingPushNotification(serverUrl: String, - account: String, - user: String, - password: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func unsubscribingPushNotification(serverUrl: String, + account: String, + user: String, + password: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let endpoint = "ocs/v2.php/apps/notifications/api/v2/push" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: serverUrl, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(user: user, password: password, appendHeaders: options.customHeader, customUserAgent: options.customUserAgent) sessionManager.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -102,7 +93,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -113,29 +103,25 @@ extension NextcloudKit { } } - @objc public func subscribingPushProxy(proxyServerUrl: String, - pushToken: String, - deviceIdentifier: String, - signature: String, - publicKey: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ error: NKError) -> Void) { - + func subscribingPushProxy(proxyServerUrl: String, + pushToken: String, + deviceIdentifier: String, + signature: String, + publicKey: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ error: NKError) -> Void) { let endpoint = "devices?format=json" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: proxyServerUrl, endpoint: endpoint), let userAgent = options.customUserAgent else { return options.queue.async { completion(.urlError) } } - let parameters = [ "pushToken": pushToken, "deviceIdentifier": deviceIdentifier, "deviceIdentifierSignature": signature, "userPublicKey": publicKey ] - let headers = HTTPHeaders(arrayLiteral: .userAgent(userAgent)) sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -145,7 +131,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -156,27 +141,23 @@ extension NextcloudKit { } } - @objc public func unsubscribingPushProxy(proxyServerUrl: String, - deviceIdentifier: String, - signature: String, - publicKey: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ error: NKError) -> Void) { - + func unsubscribingPushProxy(proxyServerUrl: String, + deviceIdentifier: String, + signature: String, + publicKey: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ error: NKError) -> Void) { let endpoint = "devices" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: proxyServerUrl, endpoint: endpoint), let userAgent = options.customUserAgent else { return options.queue.async { completion(.urlError) } } - let parameters = [ "deviceIdentifier": deviceIdentifier, "deviceIdentifierSignature": signature, "userPublicKey": publicKey ] - let headers = HTTPHeaders(arrayLiteral: .userAgent(userAgent)) sessionManager.request(url, method: .delete, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -186,7 +167,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift b/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift index d2574b06..215193e5 100644 --- a/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift @@ -25,24 +25,18 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func createUrlRichdocuments(fileID: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func createUrlRichdocuments(fileID: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/richdocuments/api/v1/document" - let parameters: [String: Any] = ["fileId": fileID] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -52,7 +46,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -69,20 +62,16 @@ extension NextcloudKit { } } - @objc public func getTemplatesRichdocuments(typeTemplate: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ templates: [NKRichdocumentsTemplate]?, _ data: Data?, _ error: NKError) -> Void) { - + func getTemplatesRichdocuments(typeTemplate: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ templates: [NKRichdocumentsTemplate]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/richdocuments/api/v1/templates/\(typeTemplate)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -92,7 +81,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -111,7 +99,6 @@ extension NextcloudKit { template.name = templateJSON["name"].stringValue template.preview = templateJSON["preview"].stringValue template.type = templateJSON["type"].stringValue - templates.append(template) } options.queue.async { completion(account, templates, jsonData, .success) } @@ -122,23 +109,18 @@ extension NextcloudKit { } } - @objc public func createRichdocuments(path: String, - templateId: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { - + func createRichdocuments(path: String, + templateId: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/richdocuments/api/v1/templates/new" - let parameters: [String: Any] = ["path": path, "template": templateId] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -148,7 +130,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -165,22 +146,17 @@ extension NextcloudKit { } } - @objc public func createAssetRichdocuments(path: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { - + func createAssetRichdocuments(path: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ url: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "index.php/apps/richdocuments/assets" - let parameters: [String: Any] = ["path": path] - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -190,7 +166,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit+Search.swift b/Sources/NextcloudKit/NextcloudKit+Search.swift index fda46024..165ad45e 100644 --- a/Sources/NextcloudKit/NextcloudKit+Search.swift +++ b/Sources/NextcloudKit/NextcloudKit+Search.swift @@ -26,8 +26,7 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - +public extension NextcloudKit { /// Available NC >= 20 /// Search many different datasources in the cloud and combine them into one result. /// @@ -42,26 +41,22 @@ extension NextcloudKit { /// - filter: Filter search provider that should be searched. Default is all available provider.. /// - update: Callback, notifying that a search provider return its result. Does not include previous results. /// - completion: Callback, notifying that all search providers have been searched. The search is done. Includes all search results. - public func unifiedSearch(term: String, - options: NKRequestOptions = NKRequestOptions(), - timeout: TimeInterval = 30, - timeoutProvider: TimeInterval = 60, - filter: @escaping (NKSearchProvider) -> Bool = { _ in true }, - request: @escaping (DataRequest?) -> Void, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - providers: @escaping (_ account: String, _ searchProviders: [NKSearchProvider]?) -> Void, - update: @escaping (_ account: String, _ searchResult: NKSearchResult?, _ provider: NKSearchProvider, _ error: NKError) -> Void, - completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { - + func unifiedSearch(term: String, + timeout: TimeInterval = 30, + timeoutProvider: TimeInterval = 60, + options: NKRequestOptions = NKRequestOptions(), + filter: @escaping (NKSearchProvider) -> Bool = { _ in true }, + request: @escaping (DataRequest?) -> Void, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + providers: @escaping (_ account: String, _ searchProviders: [NKSearchProvider]?) -> Void, + update: @escaping (_ account: String, _ searchResult: NKSearchResult?, _ provider: NKSearchProvider, _ error: NKError) -> Void, + completion: @escaping (_ account: String, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/search/providers" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return completion(account, nil, .urlError) } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) let requestUnifiedSearch = sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -71,7 +66,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .success(let jsonData): let json = JSON(jsonData) @@ -79,7 +73,6 @@ extension NextcloudKit { guard let allProvider = NKSearchProvider.factory(jsonArray: providerData) else { return completion(account, jsonData, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } - providers(account, allProvider) let filteredProviders = allProvider.filter(filter) @@ -120,34 +113,27 @@ extension NextcloudKit { /// - timeout: Filter search provider that should be searched. Default is all available provider.. /// - update: Callback, notifying that a search provider return its result. Does not include previous results. /// - completion: Callback, notifying that all search results. - @discardableResult - public func searchProvider(_ id: String, - account: String, - term: String, - limit: Int? = nil, - cursor: Int? = nil, - options: NKRequestOptions = NKRequestOptions(), - timeout: TimeInterval = 60, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ accoun: String, NKSearchResult?, _ data: Data?, _ error: NKError) -> Void) -> DataRequest? { - + func searchProvider(_ id: String, + account: String, + term: String, + limit: Int? = nil, + cursor: Int? = nil, + options: NKRequestOptions = NKRequestOptions(), + timeout: TimeInterval = 60, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ accoun: String, NKSearchResult?, _ data: Data?, _ error: NKError) -> Void) -> DataRequest? { let urlBase = self.nkCommonInstance.urlBase - guard let term = term.urlEncoded else { completion(account, nil, nil, .urlError) return nil } - var endpoint = "ocs/v2.php/search/providers/\(id)/search?term=\(term)" - if let limit = limit { endpoint += "&limit=\(limit)" } - if let cursor = cursor { endpoint += "&cursor=\(cursor)" } - guard let url = self.nkCommonInstance.createStandardUrl( serverUrl: urlBase, endpoint: endpoint) @@ -155,10 +141,9 @@ extension NextcloudKit { completion(account, nil, nil, .urlError) return nil } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: .get, headers: headers) urlRequest.timeoutInterval = timeout @@ -192,12 +177,11 @@ extension NextcloudKit { } } -@objc public class NKSearchResult: NSObject { - - @objc public let id: String - @objc public let name: String - @objc public let isPaginated: Bool - @objc public let entries: [NKSearchEntry] +public class NKSearchResult: NSObject { + public let id: String + public let name: String + public let isPaginated: Bool + public let entries: [NKSearchEntry] public let cursor: Int? init?(json: JSON, id: String) { @@ -213,21 +197,18 @@ extension NextcloudKit { } } -@objc public class NKSearchEntry: NSObject { - - @objc public let thumbnailURL: String - @objc public let title, subline: String - @objc public let resourceURL: String - @objc public let icon: String - @objc public let rounded: Bool - @objc public let attributes: [String: Any]? - +public class NKSearchEntry: NSObject { + public let thumbnailURL: String + public let title, subline: String + public let resourceURL: String + public let icon: String + public let rounded: Bool + public let attributes: [String: Any]? public var fileId: Int? { guard let fileAttribute = attributes?["fileId"] as? String else { return nil } return Int(fileAttribute) } - - @objc public var filePath: String? { + public var filePath: String? { attributes?["path"] as? String } @@ -255,7 +236,9 @@ extension NextcloudKit { } } -@objc public class NKSearchProvider: NSObject { +public class NKSearchProvider: NSObject { + public let id, name: String + public let order: Int init?(json: JSON) { guard let id = json["id"].string, @@ -267,9 +250,6 @@ extension NextcloudKit { self.order = order } - @objc public let id, name: String - @objc public let order: Int - static func factory(jsonArray: JSON) -> [NKSearchProvider]? { guard let allProvider = jsonArray.array else { return nil } return allProvider.compactMap(NKSearchProvider.init) diff --git a/Sources/NextcloudKit/NextcloudKit+Share.swift b/Sources/NextcloudKit/NextcloudKit+Share.swift index f52a1d43..27d08118 100644 --- a/Sources/NextcloudKit/NextcloudKit+Share.swift +++ b/Sources/NextcloudKit/NextcloudKit+Share.swift @@ -25,14 +25,34 @@ import Foundation import Alamofire import SwiftyJSON -@objc public class NKShareParameter: NSObject { +public class NKShareParameter: NSObject { + let path: String? + let idShare: Int + let reshares: Bool + let subfiles: Bool + let sharedWithMe: Bool + internal var endpoint: String { + guard idShare > 0 else { + return "ocs/v2.php/apps/files_sharing/api/v1/shares" + } + return "ocs/v2.php/apps/files_sharing/api/v1/shares/\(idShare)" + } + internal var queryParameters: [String: String] { + var parameters = [ + "reshares": reshares ? "true" : "false", + "subfiles": subfiles ? "true" : "false", + "shared_with_me": sharedWithMe ? "true" : "false" + ] + parameters["path"] = path + return parameters + } /// - Parameters: /// - path: Path to file or folder /// - reshares: If set to false (default), only shares owned by the current user are returned. If set to true, shares owned by any user from the given file are returned. /// - subfiles: If set to false (default), lists only the folder being shared. If set to true, all shared files within the folder are returned. /// - sharedWithMe: (?) retrieve all shares, if set to true - @objc public init(path: String? = nil, reshares: Bool = false, subfiles: Bool = false, sharedWithMe: Bool = false) { + public init(path: String? = nil, reshares: Bool = false, subfiles: Bool = false, sharedWithMe: Bool = false) { self.path = path self.idShare = 0 self.reshares = reshares @@ -45,53 +65,26 @@ import SwiftyJSON /// - reshares: If set to false (default), only shares owned by the current user are returned. If set to true, shares owned by any user from the given file are returned. /// - subfiles: If set to false (default), lists only the folder being shared. If set to true, all shared files within the folder are returned. /// - sharedWithMe: (?) retrieve all shares, if set to true - @objc public init(idShare: Int, reshares: Bool = false, subfiles: Bool = false, sharedWithMe: Bool = false) { + public init(idShare: Int, reshares: Bool = false, subfiles: Bool = false, sharedWithMe: Bool = false) { self.path = nil self.idShare = idShare self.reshares = reshares self.subfiles = subfiles self.sharedWithMe = sharedWithMe } - - let path: String? - let idShare: Int - let reshares: Bool - let subfiles: Bool - let sharedWithMe: Bool - - internal var endpoint: String { - guard idShare > 0 else { - return "ocs/v2.php/apps/files_sharing/api/v1/shares" - } - return "ocs/v2.php/apps/files_sharing/api/v1/shares/\(idShare)" - } - - internal var queryParameters: [String: String] { - var parameters = [ - "reshares": reshares ? "true" : "false", - "subfiles": subfiles ? "true" : "false", - "shared_with_me": sharedWithMe ? "true" : "false" - ] - parameters["path"] = path - return parameters - } } -extension NextcloudKit { - - @objc public func readShares(parameters: NKShareParameter, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ shares: [NKShare]?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func readShares(parameters: NKShareParameter, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ shares: [NKShare]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: parameters.endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: parameters.queryParameters, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -101,7 +94,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -132,31 +124,24 @@ extension NextcloudKit { * @param perPage The number of items per page (default 200) * @param lookup Default false, for global search use true */ - - @objc public func searchSharees(search: String = "", - page: Int = 1, perPage: Int = 200, - itemType: String = "file", - lookup: Bool = false, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ sharees: [NKSharee]?, _ data: Data?, _ error: NKError) -> Void) { - + func searchSharees(search: String = "", + page: Int = 1, perPage: Int = 200, + itemType: String = "file", + lookup: Bool = false, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ sharees: [NKSharee]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/files_sharing/api/v1/sharees" - var lookupString = "false" if lookup { lookupString = "true" } - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - let parameters = [ "search": search, "page": String(page), @@ -172,7 +157,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -197,7 +181,7 @@ extension NextcloudKit { sharee.circleOwner = subJson["value"]["circleOwner"].stringValue if let clearAt = subJson["status"]["clearAt"].double { - let date = Date(timeIntervalSince1970: clearAt) as NSDate + let date = Date(timeIntervalSince1970: clearAt) sharee.userClearAt = date } sharee.userIcon = subJson["status"]["icon"].stringValue @@ -220,7 +204,7 @@ extension NextcloudKit { sharee.circleOwner = subJson["value"]["circleOwner"].stringValue if let clearAt = subJson["status"]["clearAt"].double { - let date = Date(timeIntervalSince1970: clearAt) as NSDate + let date = Date(timeIntervalSince1970: clearAt) sharee.userClearAt = date } sharee.userIcon = subJson["status"]["icon"].stringValue @@ -257,15 +241,14 @@ extension NextcloudKit { * @param attributes There is currently only one share attribute “download” from the scope “permissions”. This attribute is only valid for user and group shares, not for public link shares. */ - @objc public func createShareLink(path: String, - hideDownload: Bool = false, - publicUpload: Bool = false, - password: String? = nil, - permissions: Int = 1, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ share: NKShare?, _ data: Data?, _ error: NKError) -> Void) { - + func createShareLink(path: String, + hideDownload: Bool = false, + publicUpload: Bool = false, + password: String? = nil, + permissions: Int = 1, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ share: NKShare?, _ data: Data?, _ error: NKError) -> Void) { createShare(path: path, shareType: 3, shareWith: nil, publicUpload: publicUpload, hideDownload: hideDownload, password: password, permissions: permissions, options: options) { task in task.taskDescription = options.taskDescription taskHandler(task) @@ -274,17 +257,16 @@ extension NextcloudKit { } } - @objc public func createShare(path: String, - shareType: Int, - shareWith: String, - password: String? = nil, - note: String? = nil, - permissions: Int = 1, - options: NKRequestOptions = NKRequestOptions(), - attributes: String? = nil, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ share: NKShare?, _ data: Data?, _ error: NKError) -> Void) { - + func createShare(path: String, + shareType: Int, + shareWith: String, + password: String? = nil, + note: String? = nil, + permissions: Int = 1, + attributes: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ share: NKShare?, _ data: Data?, _ error: NKError) -> Void) { createShare(path: path, shareType: shareType, shareWith: shareWith, publicUpload: false, note: note, hideDownload: false, password: password, permissions: permissions, attributes: attributes, options: options) { task in task.taskDescription = options.taskDescription taskHandler(task) @@ -308,15 +290,11 @@ extension NextcloudKit { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/files_sharing/api/v1/shares" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var parameters = [ "path": path, "shareType": String(shareType), @@ -348,7 +326,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -385,30 +362,25 @@ extension NextcloudKit { * @param attributes There is currently only one share attribute “download” from the scope “permissions”. This attribute is only valid for user and group shares, not for public link shares. */ - @objc public func updateShare(idShare: Int, - password: String? = nil, - expireDate: String? = nil, - permissions: Int = 1, - publicUpload: Bool = false, - note: String? = nil, - label: String? = nil, - hideDownload: Bool, - attributes: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ share: NKShare?, _ data: Data?, _ error: NKError) -> Void) { - + func updateShare(idShare: Int, + password: String? = nil, + expireDate: String? = nil, + permissions: Int = 1, + publicUpload: Bool = false, + note: String? = nil, + label: String? = nil, + hideDownload: Bool, + attributes: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ share: NKShare?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/files_sharing/api/v1/shares/\(idShare)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var parameters = [ "permissions": String(permissions) ] @@ -439,7 +411,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -459,21 +430,16 @@ extension NextcloudKit { /* * @param idShare Identifier of the share to update */ - - @objc public func deleteShare(idShare: Int, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func deleteShare(idShare: Int, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/files_sharing/api/v1/shares/\(idShare)" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -483,7 +449,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -505,7 +470,7 @@ extension NextcloudKit { share.displaynameFileOwner = json["displayname_file_owner"].stringValue share.displaynameOwner = json["displayname_owner"].stringValue if let expiration = json["expiration"].string, let date = self.nkCommonInstance.convertDate(expiration, format: "YYYY-MM-dd HH:mm:ss") { - share.expirationDate = date + share.expirationDate = date as NSDate } share.fileParent = json["file_parent"].intValue share.fileSource = json["file_source"].intValue @@ -527,7 +492,7 @@ extension NextcloudKit { share.shareWith = json["share_with"].stringValue share.shareWithDisplayname = json["share_with_displayname"].stringValue if let stime = json["stime"].double { - let date = Date(timeIntervalSince1970: stime) as NSDate + let date = Date(timeIntervalSince1970: stime) share.date = date } share.storage = json["storage"].intValue @@ -537,7 +502,7 @@ extension NextcloudKit { share.uidOwner = json["uid_owner"].stringValue share.url = json["url"].stringValue if let clearAt = json["status"]["clearAt"].double { - let date = Date(timeIntervalSince1970: clearAt) as NSDate + let date = Date(timeIntervalSince1970: clearAt) share.userClearAt = date } share.userIcon = json["status"]["icon"].stringValue @@ -549,43 +514,42 @@ extension NextcloudKit { } } -@objc public class NKShare: NSObject { - - @objc public var account = "" - @objc public var canEdit: Bool = false - @objc public var canDelete: Bool = false - @objc public var date: NSDate? - @objc public var displaynameFileOwner = "" - @objc public var displaynameOwner = "" - @objc public var expirationDate: NSDate? - @objc public var fileParent: Int = 0 - @objc public var fileSource: Int = 0 - @objc public var fileTarget = "" - @objc public var hideDownload: Bool = false - @objc public var idShare: Int = 0 - @objc public var itemSource: Int = 0 - @objc public var itemType = "" - @objc public var label = "" - @objc public var mailSend: Bool = false - @objc public var mimeType = "" - @objc public var note = "" - @objc public var parent = "" - @objc public var password = "" - @objc public var path = "" - @objc public var permissions: Int = 0 - @objc public var sendPasswordByTalk: Bool = false - @objc public var shareType: Int = 0 - @objc public var shareWith = "" - @objc public var shareWithDisplayname = "" - @objc public var storage: Int = 0 - @objc public var storageId = "" - @objc public var token = "" - @objc public var uidFileOwner = "" - @objc public var uidOwner = "" - @objc public var url = "" - @objc public var userClearAt: NSDate? - @objc public var userIcon = "" - @objc public var userMessage = "" - @objc public var userStatus = "" - @objc public var attributes: String? +public class NKShare: NSObject { + public var account = "" + public var canEdit: Bool = false + public var canDelete: Bool = false + public var date: Date? + public var displaynameFileOwner = "" + public var displaynameOwner = "" + public var expirationDate: NSDate? + public var fileParent: Int = 0 + public var fileSource: Int = 0 + public var fileTarget = "" + public var hideDownload: Bool = false + public var idShare: Int = 0 + public var itemSource: Int = 0 + public var itemType = "" + public var label = "" + public var mailSend: Bool = false + public var mimeType = "" + public var note = "" + public var parent = "" + public var password = "" + public var path = "" + public var permissions: Int = 0 + public var sendPasswordByTalk: Bool = false + public var shareType: Int = 0 + public var shareWith = "" + public var shareWithDisplayname = "" + public var storage: Int = 0 + public var storageId = "" + public var token = "" + public var uidFileOwner = "" + public var uidOwner = "" + public var url = "" + public var userClearAt: Date? + public var userIcon = "" + public var userMessage = "" + public var userStatus = "" + public var attributes: String? } diff --git a/Sources/NextcloudKit/NextcloudKit+UserStatus.swift b/Sources/NextcloudKit/NextcloudKit+UserStatus.swift index 3be34d80..eaa58f94 100644 --- a/Sources/NextcloudKit/NextcloudKit+UserStatus.swift +++ b/Sources/NextcloudKit/NextcloudKit+UserStatus.swift @@ -25,25 +25,20 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func getUserStatus(userId: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ clearAt: NSDate?, _ icon: String?, _ message: String?, _ messageId: String?, _ messageIsPredefined: Bool, _ status: String?, _ statusIsUserDefined: Bool, _ userId: String?, _ data: Data?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func getUserStatus(userId: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ clearAt: Date?, _ icon: String?, _ message: String?, _ messageId: String?, _ messageIsPredefined: Bool, _ status: String?, _ statusIsUserDefined: Bool, _ userId: String?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - var endpoint = "ocs/v2.php/apps/user_status/api/v1/user_status" if let userId = userId { endpoint = "ocs/v2.php/apps/user_status/api/v1/user_status/\(userId)" } - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, nil, nil, false, nil, false, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -53,7 +48,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -63,9 +57,9 @@ extension NextcloudKit { let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if statusCode == 200 { - var clearAt: NSDate? + var clearAt: Date? if let clearAtDouble = json["ocs"]["data"]["clearAt"].double { - clearAt = Date(timeIntervalSince1970: clearAtDouble) as NSDate + clearAt = Date(timeIntervalSince1970: clearAtDouble) } let icon = json["ocs"]["data"]["icon"].string let message = json["ocs"]["data"]["message"].string @@ -83,22 +77,17 @@ extension NextcloudKit { } } - @objc public func setUserStatus(status: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func setUserStatus(status: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/user_status/api/v1/user_status/status" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - let parameters = [ "statusType": String(status) ] @@ -110,7 +99,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -127,23 +115,18 @@ extension NextcloudKit { } } - @objc public func setCustomMessagePredefined(messageId: String, - clearAt: Double, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func setCustomMessagePredefined(messageId: String, + clearAt: Double, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/user_status/api/v1/user_status/message/predefined" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var parameters = [ "messageId": String(messageId) ] @@ -158,7 +141,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -176,24 +158,19 @@ extension NextcloudKit { } } - @objc public func setCustomMessageUserDefined(statusIcon: String?, - message: String, - clearAt: Double, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func setCustomMessageUserDefined(statusIcon: String?, + message: String, + clearAt: Double, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/user_status/api/v1/user_status/message/custom" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var parameters = [ "message": String(message) ] @@ -211,15 +188,14 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) options.queue.async { completion(account, error) } case .success(let jsonData): let json = JSON(jsonData) - let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError + if statusCode == 200 { options.queue.async { completion(account, .success) } } else { @@ -229,19 +205,15 @@ extension NextcloudKit { } } - @objc public func clearMessage(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func clearMessage(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase - let endpoint = "ocs/v2.php/apps/user_status/api/v1/user_status/message" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -251,15 +223,14 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) options.queue.async { completion(account, error) } case .success(let jsonData): let json = JSON(jsonData) - let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError + if statusCode == 200 { options.queue.async { completion(account, .success) } } else { @@ -269,20 +240,16 @@ extension NextcloudKit { } } - @objc public func getUserStatusPredefinedStatuses(options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ userStatuses: [NKUserStatus]?, _ data: Data?, _ error: NKError) -> Void) { - + func getUserStatusPredefinedStatuses(options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ userStatuses: [NKUserStatus]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var userStatuses: [NKUserStatus] = [] - let endpoint = "ocs/v2.php/apps/user_status/api/v1/predefined_statuses" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) sessionManager.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in @@ -292,7 +259,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -301,8 +267,8 @@ extension NextcloudKit { let json = JSON(jsonData) let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if statusCode == 200 { - let ocsdata = json["ocs"]["data"] + for (_, subJson): (String, JSON) in ocsdata { let userStatus = NKUserStatus() @@ -316,10 +282,8 @@ extension NextcloudKit { userStatus.id = subJson["id"].string userStatus.message = subJson["message"].string userStatus.predefined = true - userStatuses.append(userStatus) } - options.queue.async { completion(account, userStatuses, jsonData, .success) } } else { options.queue.async { completion(account, nil, jsonData, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } @@ -328,24 +292,19 @@ extension NextcloudKit { } } - @objc public func getUserStatusRetrieveStatuses(limit: Int, - offset: Int, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ userStatuses: [NKUserStatus]?, _ data: Data?, _ error: NKError) -> Void) { - + func getUserStatusRetrieveStatuses(limit: Int, + offset: Int, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ userStatuses: [NKUserStatus]?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let urlBase = self.nkCommonInstance.urlBase var userStatuses: [NKUserStatus] = [] - let endpoint = "ocs/v2.php/apps/user_status/api/v1/statuses" - guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: urlBase, endpoint: endpoint) else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - let parameters = [ "limit": String(limit), "offset": String(offset) @@ -358,7 +317,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -367,28 +325,24 @@ extension NextcloudKit { let json = JSON(jsonData) let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if statusCode == 200 { - let ocsdata = json["ocs"]["data"] + for (_, subJson): (String, JSON) in ocsdata { let userStatus = NKUserStatus() if let value = subJson["clearAt"].double { if value > 0 { - userStatus.clearAt = NSDate(timeIntervalSince1970: value) + userStatus.clearAt = Date(timeIntervalSince1970: value) } } userStatus.icon = subJson["icon"].string userStatus.message = subJson["message"].string userStatus.predefined = false userStatus.userId = subJson["userId"].string - userStatuses.append(userStatus) } - options.queue.async { completion(account, userStatuses, jsonData, .success) } - } else { - options.queue.async { completion(account, nil, jsonData, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } } } diff --git a/Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV.swift b/Sources/NextcloudKit/NextcloudKit+WebDAV.swift similarity index 72% rename from Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV.swift rename to Sources/NextcloudKit/NextcloudKit+WebDAV.swift index 124ef509..21b47540 100644 --- a/Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV.swift +++ b/Sources/NextcloudKit/NextcloudKit+WebDAV.swift @@ -25,24 +25,19 @@ import Foundation import Alamofire import SwiftyJSON -extension NextcloudKit { - - @objc public func createFolder(serverUrlFileName: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ ocId: String?, _ date: NSDate?, _ error: NKError) -> Void) { - +public extension NextcloudKit { + func createFolder(serverUrlFileName: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ ocId: String?, _ date: Date?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, nil, nil, .urlError) } } - let method = HTTPMethod(rawValue: "MKCOL") - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) urlRequest.timeoutInterval = options.timeout @@ -57,7 +52,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -77,20 +71,17 @@ extension NextcloudKit { } } - @objc public func deleteFileOrFolder(serverUrlFileName: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func deleteFileOrFolder(serverUrlFileName: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let headers = self.nkCommonInstance.getStandardHeaders(options: options) - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: .delete, headers: headers) urlRequest.timeoutInterval = options.timeout @@ -105,7 +96,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -116,21 +106,17 @@ extension NextcloudKit { } } - @objc public func moveFileOrFolder(serverUrlFileNameSource: String, - serverUrlFileNameDestination: String, - overwrite: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func moveFileOrFolder(serverUrlFileNameSource: String, + serverUrlFileNameDestination: String, + overwrite: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrlFileNameSource.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: "MOVE") - var headers = self.nkCommonInstance.getStandardHeaders(options: options) headers.update(name: "Destination", value: serverUrlFileNameDestination.urlEncoded ?? "") if overwrite { @@ -138,8 +124,8 @@ extension NextcloudKit { } else { headers.update(name: "Overwrite", value: "F") } - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) urlRequest.timeoutInterval = options.timeout @@ -154,7 +140,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -165,21 +150,17 @@ extension NextcloudKit { } } - @objc public func copyFileOrFolder(serverUrlFileNameSource: String, - serverUrlFileNameDestination: String, - overwrite: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func copyFileOrFolder(serverUrlFileNameSource: String, + serverUrlFileNameDestination: String, + overwrite: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account - guard let url = serverUrlFileNameSource.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: "COPY") - var headers = self.nkCommonInstance.getStandardHeaders(options: options) headers.update(name: "Destination", value: serverUrlFileNameDestination.urlEncoded ?? "") if overwrite { @@ -187,8 +168,8 @@ extension NextcloudKit { } else { headers.update(name: "Overwrite", value: "F") } - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) urlRequest.timeoutInterval = options.timeout @@ -203,7 +184,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -214,15 +194,14 @@ extension NextcloudKit { } } - @objc public func readFileOrFolder(serverUrlFileName: String, - depth: String, - showHiddenFiles: Bool = true, - includeHiddenFiles: [String] = [], - requestBody: Data? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { - + func readFileOrFolder(serverUrlFileName: String, + depth: String, + showHiddenFiles: Bool = true, + includeHiddenFiles: [String] = [], + requestBody: Data? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let user = self.nkCommonInstance.user let userId = self.nkCommonInstance.userId @@ -230,30 +209,26 @@ extension NextcloudKit { let dav = self.nkCommonInstance.dav var files: [NKFile] = [] var serverUrlFileName = serverUrlFileName - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, files, nil, .urlError) } } - if depth == "0", serverUrlFileName.last == "/" { serverUrlFileName = String(serverUrlFileName.dropLast()) } else if depth != "0", serverUrlFileName.last != "/" { serverUrlFileName = serverUrlFileName + "/" } - let method = HTTPMethod(rawValue: "PROPFIND") - var headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") headers.update(name: "Depth", value: depth) - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) - if requestBody != nil { - urlRequest.httpBody = requestBody! + if let requestBody { + urlRequest.httpBody = requestBody urlRequest.timeoutInterval = options.timeout } else { - urlRequest.httpBody = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyFile.data(using: .utf8) + urlRequest.httpBody = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodyFile(createProperties: options.createProperties, removeProperties: options.removeProperties).data(using: .utf8) } } catch { return options.queue.async { completion(account, files, nil, NKError(error: error)) } @@ -266,7 +241,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -282,23 +256,21 @@ extension NextcloudKit { } } - @objc public func getFileFromFileId(fileId: String? = nil, - link: String? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ file: NKFile?, _ data: Data?, _ error: NKError) -> Void) { - + func getFileFromFileId(fileId: String? = nil, + link: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ file: NKFile?, _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let userId = self.nkCommonInstance.userId let urlBase = self.nkCommonInstance.urlBase var httpBody: Data? - if let fileId = fileId { - httpBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodySearchFileId, userId, fileId).data(using: .utf8)! + httpBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodySearchFileId(createProperties: options.createProperties, removeProperties: options.removeProperties), userId, fileId).data(using: .utf8) } else if let link = link { let linkArray = link.components(separatedBy: "/") if let fileId = linkArray.last { - httpBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodySearchFileId, userId, fileId).data(using: .utf8)! + httpBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodySearchFileId(createProperties: options.createProperties, removeProperties: options.removeProperties), userId, fileId).data(using: .utf8) } } guard let httpBody = httpBody else { @@ -313,96 +285,90 @@ extension NextcloudKit { } } - @objc public func searchBodyRequest(serverUrl: String, - requestBody: String, - showHiddenFiles: Bool, - includeHiddenFiles: [String] = [], - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { - - let httpBody = requestBody.data(using: .utf8)! - - search(serverUrl: serverUrl, httpBody: httpBody, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { task in - taskHandler(task) - } completion: { account, files, data, error in - options.queue.async { completion(account, files, data, error) } + func searchBodyRequest(serverUrl: String, + requestBody: String, + showHiddenFiles: Bool, + includeHiddenFiles: [String] = [], + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { + if let httpBody = requestBody.data(using: .utf8) { + search(serverUrl: serverUrl, httpBody: httpBody, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { task in + taskHandler(task) + } completion: { account, files, data, error in + options.queue.async { completion(account, files, data, error) } + } } } - @objc public func searchLiteral(serverUrl: String, - depth: String, - literal: String, - showHiddenFiles: Bool, - includeHiddenFiles: [String] = [], - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { - + func searchLiteral(serverUrl: String, + depth: String, + literal: String, + showHiddenFiles: Bool, + includeHiddenFiles: [String] = [], + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let userId = self.nkCommonInstance.userId - guard let href = ("/files/" + userId).urlEncoded else { return options.queue.async { completion(account, [], nil, .urlError) } } - - let requestBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodySearchFileName, href, depth, "%" + literal + "%") - let httpBody = requestBody.data(using: .utf8)! - - search(serverUrl: serverUrl, httpBody: httpBody, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { task in - taskHandler(task) - } completion: { account, files, data, error in - options.queue.async { completion(account, files, data, error) } + let requestBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodySearchFileName(createProperties: options.createProperties, removeProperties: options.removeProperties), href, depth, "%" + literal + "%") + if let httpBody = requestBody.data(using: .utf8) { + search(serverUrl: serverUrl, httpBody: httpBody, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { task in + taskHandler(task) + } completion: { account, files, data, error in + options.queue.async { completion(account, files, data, error) } + } } } - @objc public func searchMedia(path: String = "", - lessDate: Any, - greaterDate: Any, - elementDate: String, - limit: Int, - showHiddenFiles: Bool, - includeHiddenFiles: [String] = [], - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { - + func searchMedia(path: String = "", + lessDate: Any, + greaterDate: Any, + elementDate: String, + limit: Int, + showHiddenFiles: Bool, + includeHiddenFiles: [String] = [], + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let userId = self.nkCommonInstance.userId let urlBase = self.nkCommonInstance.urlBase let files: [NKFile] = [] var greaterDateString: String?, lessDateString: String? let href = "/files/" + userId + path - if let lessDate = lessDate as? Date { lessDateString = self.nkCommonInstance.convertDate(lessDate, format: "yyyy-MM-dd'T'HH:mm:ssZZZZZ") } else if let lessDate = lessDate as? Int { lessDateString = String(lessDate) } - if let greaterDate = greaterDate as? Date { greaterDateString = self.nkCommonInstance.convertDate(greaterDate, format: "yyyy-MM-dd'T'HH:mm:ssZZZZZ") } else if let greaterDate = greaterDate as? Int { greaterDateString = String(greaterDate) } - if lessDateString == nil || greaterDateString == nil { return options.queue.async { completion(account, files, nil, .invalidDate) } } - var requestBody = "" - if limit > 0 { - requestBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodySearchMediaWithLimit, href, elementDate, elementDate, lessDateString!, elementDate, greaterDateString!, String(limit)) - } else { - requestBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodySearchMedia, href, elementDate, elementDate, lessDateString!, elementDate, greaterDateString!) - } - let httpBody = requestBody.data(using: .utf8)! + if let lessDateString, let greaterDateString { + if limit > 0 { + requestBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodySearchMediaWithLimit(createProperties: options.createProperties, removeProperties: options.removeProperties), href, elementDate, elementDate, lessDateString, elementDate, greaterDateString, String(limit)) + } else { + requestBody = String(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodySearchMedia(createProperties: options.createProperties, removeProperties: options.removeProperties), href, elementDate, elementDate, lessDateString, elementDate, greaterDateString) + } + } - search(serverUrl: urlBase, httpBody: httpBody, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { task in - taskHandler(task) - } completion: { account, files, data, error in - options.queue.async { completion(account, files, data, error) } + if let httpBody = requestBody.data(using: .utf8) { + search(serverUrl: urlBase, httpBody: httpBody, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { task in + taskHandler(task) + } completion: { account, files, data, error in + options.queue.async { completion(account, files, data, error) } + } } } @@ -413,22 +379,17 @@ extension NextcloudKit { options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { - let account = self.nkCommonInstance.account let user = self.nkCommonInstance.user let userId = self.nkCommonInstance.userId let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav var files: [NKFile] = [] - guard let url = (serverUrl + "/" + dav).encodedToUrl else { return options.queue.async { completion(account, files, nil, .urlError) } } - let method = HTTPMethod(rawValue: "SEARCH") - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest do { try urlRequest = URLRequest(url: url, method: method, headers: headers) @@ -445,7 +406,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -461,27 +421,23 @@ extension NextcloudKit { } } - @objc public func setFavorite(fileName: String, - favorite: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ error: NKError) -> Void) { - + func setFavorite(fileName: String, + favorite: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let userId = self.nkCommonInstance.userId let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav let serverUrlFileName = urlBase + "/" + dav + "/files/" + userId + "/" + fileName - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, .urlError) } } - let method = HTTPMethod(rawValue: "PROPPATCH") - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) let body = NSString(format: NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyFileSetFavorite as NSString, (favorite ? 1 : 0)) as String @@ -498,7 +454,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -509,12 +464,11 @@ extension NextcloudKit { } } - @objc public func listingFavorites(showHiddenFiles: Bool, - includeHiddenFiles: [String] = [], - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { - + func listingFavorites(showHiddenFiles: Bool, + includeHiddenFiles: [String] = [], + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ files: [NKFile], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let user = self.nkCommonInstance.user let userId = self.nkCommonInstance.userId @@ -522,19 +476,16 @@ extension NextcloudKit { let dav = self.nkCommonInstance.dav let serverUrlFileName = urlBase + "/" + dav + "/files/" + userId var files: [NKFile] = [] - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, files, nil, .urlError) } } - let method = HTTPMethod(rawValue: "REPORT") - let headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) - urlRequest.httpBody = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyFileListingFavorites.data(using: .utf8) + urlRequest.httpBody = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).getRequestBodyFileListingFavorites(createProperties: options.createProperties, removeProperties: options.removeProperties).data(using: .utf8) urlRequest.timeoutInterval = options.timeout } catch { return options.queue.async { completion(account, files, nil, NKError(error: error)) } @@ -547,7 +498,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) @@ -563,12 +513,11 @@ extension NextcloudKit { } } - @objc public func listingTrash(filename: String? = nil, - showHiddenFiles: Bool, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - completion: @escaping (_ account: String, _ items: [NKTrash], _ data: Data?, _ error: NKError) -> Void) { - + func listingTrash(filename: String? = nil, + showHiddenFiles: Bool, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ items: [NKTrash], _ data: Data?, _ error: NKError) -> Void) { let account = self.nkCommonInstance.account let userId = self.nkCommonInstance.userId let urlBase = self.nkCommonInstance.urlBase @@ -578,17 +527,14 @@ extension NextcloudKit { serverUrlFileName = serverUrlFileName + filename } var items: [NKTrash] = [] - guard let url = serverUrlFileName.encodedToUrl else { return options.queue.async { completion(account, items, nil, .urlError) } } - let method = HTTPMethod(rawValue: "PROPFIND") - var headers = self.nkCommonInstance.getStandardHeaders(options.customHeader, customUserAgent: options.customUserAgent, contentType: "application/xml") headers.update(name: "Depth", value: "1") - var urlRequest: URLRequest + do { try urlRequest = URLRequest(url: url, method: method, headers: headers) urlRequest.httpBody = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).requestBodyTrash.data(using: .utf8) @@ -604,7 +550,6 @@ extension NextcloudKit { if self.nkCommonInstance.levelLog > 0 { debugPrint(response) } - switch response.result { case .failure(let error): let error = NKError(error: error, afResponse: response, responseData: response.data) diff --git a/Sources/NextcloudKit/NextcloudKit.swift b/Sources/NextcloudKit/NextcloudKit.swift index ab4d4fb1..cfb7f3a4 100644 --- a/Sources/NextcloudKit/NextcloudKit.swift +++ b/Sources/NextcloudKit/NextcloudKit.swift @@ -29,14 +29,12 @@ import UIKit import Alamofire import SwiftyJSON -@objc open class NextcloudKit: SessionDelegate { - @objc public static let shared: NextcloudKit = { +open class NextcloudKit: SessionDelegate { + public static let shared: NextcloudKit = { let instance = NextcloudKit() return instance }() - internal lazy var internalSessionManager: Alamofire.Session = { - return Alamofire.Session(configuration: nkCommonInstance.sessionConfiguration, delegate: self, rootQueue: nkCommonInstance.rootQueue, @@ -49,17 +47,14 @@ import SwiftyJSON cachedResponseHandler: nil, eventMonitors: [AlamofireLogger(nkCommonInstance: self.nkCommonInstance)]) }() - public var sessionManager: Alamofire.Session { return internalSessionManager } - #if !os(watchOS) private let reachabilityManager = Alamofire.NetworkReachabilityManager() #endif // private var cookies: [String:[HTTPCookie]] = [:] - - @objc public let nkCommonInstance = NKCommon() + public let nkCommonInstance = NKCommon() override public init(fileManager: FileManager = .default) { super.init(fileManager: fileManager) @@ -76,16 +71,14 @@ import SwiftyJSON // MARK: - Setup - @objc public func setup(account: String? = nil, user: String, userId: String, password: String, urlBase: String, userAgent: String, nextcloudVersion: Int, delegate: NKCommonDelegate?) { - + public func setup(account: String? = nil, user: String, userId: String, password: String, urlBase: String, userAgent: String, nextcloudVersion: Int, delegate: NKCommonDelegate?) { self.setup(account: account, user: user, userId: userId, password: password, urlBase: urlBase) self.setup(userAgent: userAgent) self.setup(nextcloudVersion: nextcloudVersion) self.setup(delegate: delegate) } - @objc public func setup(account: String? = nil, user: String, userId: String, password: String, urlBase: String) { - + public func setup(account: String? = nil, user: String, userId: String, password: String, urlBase: String) { if (self.nkCommonInstance.account != account) || (self.nkCommonInstance.urlBase != urlBase && self.nkCommonInstance.user != user) { if let cookieStore = sessionManager.session.configuration.httpCookieStorage { for cookie in cookieStore.cookies ?? [] { @@ -106,26 +99,22 @@ import SwiftyJSON self.nkCommonInstance.internalUrlBase = urlBase } - @objc public func setup(delegate: NKCommonDelegate?) { - + public func setup(delegate: NKCommonDelegate?) { self.nkCommonInstance.delegate = delegate } - @objc public func setup(userAgent: String) { - + public func setup(userAgent: String) { self.nkCommonInstance.internalUserAgent = userAgent } - @objc public func setup(nextcloudVersion: Int) { - + public func setup(nextcloudVersion: Int) { self.nkCommonInstance.internalNextcloudVersion = nextcloudVersion } - @objc public func setupSessionManager(sessionConfiguration: URLSessionConfiguration?, - rootQueue: DispatchQueue?, - requestQueue: DispatchQueue?, - serializationQueue: DispatchQueue?) { - + public func setupSessionManager(sessionConfiguration: URLSessionConfiguration?, + rootQueue: DispatchQueue?, + requestQueue: DispatchQueue?, + serializationQueue: DispatchQueue?) { if let sessionConfiguration = sessionConfiguration { self.nkCommonInstance.sessionConfiguration = sessionConfiguration } @@ -168,39 +157,33 @@ import SwiftyJSON // MARK: - Reachability #if !os(watchOS) - @objc public func isNetworkReachable() -> Bool { + public func isNetworkReachable() -> Bool { return reachabilityManager?.isReachable ?? false } private func startNetworkReachabilityObserver() { - reachabilityManager?.startListening(onUpdatePerforming: { status in switch status { - case .unknown: - self.nkCommonInstance.delegate?.networkReachabilityObserver?(NKCommon.TypeReachability.unknown) - + self.nkCommonInstance.delegate?.networkReachabilityObserver(NKCommon.TypeReachability.unknown) case .notReachable: - self.nkCommonInstance.delegate?.networkReachabilityObserver?(NKCommon.TypeReachability.notReachable) - + self.nkCommonInstance.delegate?.networkReachabilityObserver(NKCommon.TypeReachability.notReachable) case .reachable(.ethernetOrWiFi): - self.nkCommonInstance.delegate?.networkReachabilityObserver?(NKCommon.TypeReachability.reachableEthernetOrWiFi) - + self.nkCommonInstance.delegate?.networkReachabilityObserver(NKCommon.TypeReachability.reachableEthernetOrWiFi) case .reachable(.cellular): - self.nkCommonInstance.delegate?.networkReachabilityObserver?(NKCommon.TypeReachability.reachableCellular) + self.nkCommonInstance.delegate?.networkReachabilityObserver(NKCommon.TypeReachability.reachableCellular) } }) } private func stopNetworkReachabilityObserver() { - reachabilityManager?.stopListening() } #endif // MARK: - Session utility - @objc public func getSessionManager() -> URLSession { + public func getSessionManager() -> URLSession { return sessionManager.session } @@ -229,74 +212,44 @@ import SwiftyJSON // MARK: - download / upload - @objc public func download(serverUrlFileName: Any, - fileNameLocalPath: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - progressHandler: @escaping (_ progress: Progress) -> Void = { _ in }, - completionHandler: @escaping (_ account: String, _ etag: String?, _ date: NSDate?, _ lenght: Int64, _ allHeaderFields: [AnyHashable: Any]?, _ nkError: NKError) -> Void) { - - download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, options: options) { _ in - // not available in objc - } taskHandler: { task in - taskHandler(task) - } progressHandler: { progress in - progressHandler(progress) - } completionHandler: { account, etag, date, lenght, allHeaderFields, _, nkError in - // error not available in objc - completionHandler(account, etag, date, lenght, allHeaderFields, nkError) - } - } - public func download(serverUrlFileName: Any, fileNameLocalPath: String, options: NKRequestOptions = NKRequestOptions(), requestHandler: @escaping (_ request: DownloadRequest) -> Void = { _ in }, taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, progressHandler: @escaping (_ progress: Progress) -> Void = { _ in }, - completionHandler: @escaping (_ account: String, _ etag: String?, _ date: NSDate?, _ lenght: Int64, _ allHeaderFields: [AnyHashable: Any]?, _ afError: AFError?, _ nKError: NKError) -> Void) { - + completionHandler: @escaping (_ account: String, _ etag: String?, _ date: Date?, _ lenght: Int64, _ allHeaderFields: [AnyHashable: Any]?, _ afError: AFError?, _ nKError: NKError) -> Void) { let account = self.nkCommonInstance.account var convertible: URLConvertible? - if serverUrlFileName is URL { convertible = serverUrlFileName as? URLConvertible } else if serverUrlFileName is String || serverUrlFileName is NSString { convertible = (serverUrlFileName as? String)?.encodedToUrl } - guard let url = convertible else { options.queue.async { completionHandler(account, nil, nil, 0, nil, nil, .urlError) } return } - var destination: Alamofire.DownloadRequest.Destination? let fileNamePathLocalDestinationURL = NSURL.fileURL(withPath: fileNameLocalPath) let destinationFile: DownloadRequest.Destination = { _, _ in return (fileNamePathLocalDestinationURL, [.removePreviousFile, .createIntermediateDirectories]) } destination = destinationFile - let headers = self.nkCommonInstance.getStandardHeaders(options: options) let request = sessionManager.download(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil, to: destination).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in - task.taskDescription = options.taskDescription options.queue.async { taskHandler(task) } - } .downloadProgress { progress in - options.queue.async { progressHandler(progress) } - } .response(queue: self.nkCommonInstance.backgroundQueue) { response in - switch response.result { case .failure(let error): let resultError = NKError(error: error, afResponse: response, responseData: nil) options.queue.async { completionHandler(account, nil, nil, 0, nil, error, resultError) } case .success: - - var date: NSDate? + var date: Date? var etag: String? var length: Int64 = 0 let allHeaderFields = response.response?.allHeaderFields @@ -304,17 +257,14 @@ import SwiftyJSON if let result = response.response?.allHeaderFields["Content-Length"] as? String { length = Int64(result) ?? 0 } - if self.nkCommonInstance.findHeader("oc-etag", allHeaderFields: response.response?.allHeaderFields) != nil { etag = self.nkCommonInstance.findHeader("oc-etag", allHeaderFields: response.response?.allHeaderFields) } else if self.nkCommonInstance.findHeader("etag", allHeaderFields: response.response?.allHeaderFields) != nil { etag = self.nkCommonInstance.findHeader("etag", allHeaderFields: response.response?.allHeaderFields) } - if etag != nil { - etag = etag!.replacingOccurrences(of: "\"", with: "") + etag = etag?.replacingOccurrences(of: "\"", with: "") } - if let dateString = self.nkCommonInstance.findHeader("Date", allHeaderFields: response.response?.allHeaderFields) { date = self.nkCommonInstance.convertDate(dateString, format: "EEE, dd MMM y HH:mm:ss zzz") } @@ -326,27 +276,6 @@ import SwiftyJSON options.queue.async { requestHandler(request) } } - @objc public func upload(serverUrlFileName: String, - fileNameLocalPath: String, - dateCreationFile: Date? = nil, - dateModificationFile: Date? = nil, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - progressHandler: @escaping (_ progress: Progress) -> Void = { _ in }, - completionHandler: @escaping (_ account: String, _ ocId: String?, _ etag: String?, _ date: NSDate?, _ size: Int64, _ allHeaderFields: [AnyHashable: Any]?, _ nkError: NKError) -> Void) { - - upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: dateCreationFile, dateModificationFile: dateModificationFile, options: options) { _ in - // not available in objc - } taskHandler: { task in - taskHandler(task) - } progressHandler: { progress in - progressHandler(progress) - } completionHandler: { account, ocId, etag, date, size, allHeaderFields, _, nkError in - // error not available in objc - completionHandler(account, ocId, etag, date, size, allHeaderFields, nkError) - } - } - public func upload(serverUrlFileName: Any, fileNameLocalPath: String, dateCreationFile: Date? = nil, @@ -355,27 +284,21 @@ import SwiftyJSON requestHandler: @escaping (_ request: UploadRequest) -> Void = { _ in }, taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, progressHandler: @escaping (_ progress: Progress) -> Void = { _ in }, - completionHandler: @escaping (_ account: String, _ ocId: String?, _ etag: String?, _ date: NSDate?, _ size: Int64, _ allHeaderFields: [AnyHashable: Any]?, _ afError: AFError?, _ nkError: NKError) -> Void) { - + completionHandler: @escaping (_ account: String, _ ocId: String?, _ etag: String?, _ date: Date?, _ size: Int64, _ allHeaderFields: [AnyHashable: Any]?, _ afError: AFError?, _ nkError: NKError) -> Void) { let account = self.nkCommonInstance.account var convertible: URLConvertible? var size: Int64 = 0 - if serverUrlFileName is URL { convertible = serverUrlFileName as? URLConvertible } else if serverUrlFileName is String || serverUrlFileName is NSString { convertible = (serverUrlFileName as? String)?.encodedToUrl } - guard let url = convertible else { options.queue.async { completionHandler(account, nil, nil, nil, 0, nil, nil, .urlError) } return } - let fileNameLocalPathUrl = URL(fileURLWithPath: fileNameLocalPath) - var headers = self.nkCommonInstance.getStandardHeaders(options: options) - // Epoch of linux do not permitted negativ value if let dateCreationFile, dateCreationFile.timeIntervalSince1970 > 0 { headers.update(name: "X-OC-CTime", value: "\(dateCreationFile.timeIntervalSince1970)") @@ -386,17 +309,12 @@ import SwiftyJSON } let request = sessionManager.upload(fileNameLocalPathUrl, to: url, method: .put, headers: headers, interceptor: nil, fileManager: .default).validate(statusCode: 200..<300).onURLSessionTaskCreation(perform: { task in - task.taskDescription = options.taskDescription options.queue.async { taskHandler(task) } - }) .uploadProgress { progress in - options.queue.async { progressHandler(progress) } size = progress.totalUnitCount - } .response(queue: self.nkCommonInstance.backgroundQueue) { response in - switch response.result { case .failure(let error): let resultError = NKError(error: error, afResponse: response, responseData: response.data) @@ -404,21 +322,19 @@ import SwiftyJSON case .success: var ocId: String?, etag: String? let allHeaderFields = response.response?.allHeaderFields - if self.nkCommonInstance.findHeader("oc-fileid", allHeaderFields: response.response?.allHeaderFields) != nil { ocId = self.nkCommonInstance.findHeader("oc-fileid", allHeaderFields: response.response?.allHeaderFields) } else if self.nkCommonInstance.findHeader("fileid", allHeaderFields: response.response?.allHeaderFields) != nil { ocId = self.nkCommonInstance.findHeader("fileid", allHeaderFields: response.response?.allHeaderFields) } - if self.nkCommonInstance.findHeader("oc-etag", allHeaderFields: response.response?.allHeaderFields) != nil { etag = self.nkCommonInstance.findHeader("oc-etag", allHeaderFields: response.response?.allHeaderFields) } else if self.nkCommonInstance.findHeader("etag", allHeaderFields: response.response?.allHeaderFields) != nil { etag = self.nkCommonInstance.findHeader("etag", allHeaderFields: response.response?.allHeaderFields) } - - if etag != nil { etag = etag!.replacingOccurrences(of: "\"", with: "") } - + if etag != nil { + etag = etag?.replacingOccurrences(of: "\"", with: "") + } if let dateString = self.nkCommonInstance.findHeader("date", allHeaderFields: response.response?.allHeaderFields) { if let date = self.nkCommonInstance.convertDate(dateString, format: "EEE, dd MMM y HH:mm:ss zzz") { options.queue.async { completionHandler(account, ocId, etag, date, size, allHeaderFields, nil, .success) } @@ -462,12 +378,10 @@ import SwiftyJSON progressHandler: @escaping (_ totalBytesExpected: Int64, _ totalBytes: Int64, _ fractionCompleted: Double) -> Void = { _, _, _ in }, uploaded: @escaping (_ fileChunk: (fileName: String, size: Int64)) -> Void = { _ in }, completion: @escaping (_ account: String, _ filesChunk: [(fileName: String, size: Int64)]?, _ file: NKFile?, _ afError: AFError?, _ error: NKError) -> Void) { - let account = self.nkCommonInstance.account let userId = self.nkCommonInstance.userId let urlBase = self.nkCommonInstance.urlBase let dav = self.nkCommonInstance.dav - let fileNameLocalSize = self.nkCommonInstance.getFileSize(filePath: directory + "/" + fileName) let serverUrlChunkFolder = urlBase + "/" + dav + "/uploads/" + userId + "/" + chunkFolder let serverUrlFileName = urlBase + "/" + dav + "/files/" + userId + self.nkCommonInstance.returnPathfromServerUrl(serverUrl) + "/" + fileName @@ -506,7 +420,6 @@ import SwiftyJSON #endif func createFolder(completion: @escaping (_ errorCode: NKError) -> Void) { - readFileOrFolder(serverUrlFileName: serverUrlChunkFolder, depth: "0", options: options) { _, _, _, error in if error == .success { completion(NKError()) @@ -521,11 +434,9 @@ import SwiftyJSON } createFolder { error in - guard error == .success else { return completion(account, nil, nil, nil, NKError(errorCode: NKError.chunkCreateFolder, errorDescription: error.errorDescription)) } - var uploadNKError = NKError() var uploadAFError: AFError? @@ -539,22 +450,18 @@ import SwiftyJSON let error = NKError(errorCode: NKError.chunkFilesNull, errorDescription: "_chunk_files_null_") return completion(account, nil, nil, nil, error) } - var filesChunkOutput = filesChunk start(filesChunkOutput) for fileChunk in filesChunk { - let serverUrlFileName = serverUrlChunkFolder + "/" + fileChunk.fileName let fileNameLocalPath = directory + "/" + fileChunk.fileName - let fileSize = self.nkCommonInstance.getFileSize(filePath: fileNameLocalPath) if fileSize == 0 { // The file could not be sent let error = NKError(errorCode: NKError.chunkFileNull, errorDescription: "_chunk_file_null_") return completion(account, nil, nil, .explicitlyCancelled, error) } - let semaphore = DispatchSemaphore(value: 0) self.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, options: options, requestHandler: { request in requestHandler(request) @@ -595,7 +502,6 @@ import SwiftyJSON if let date, date.timeIntervalSince1970 > 0 { options.customHeader?["X-OC-MTime"] = "\(date.timeIntervalSince1970)" } - // Calculate Assemble Timeout let assembleSizeInGB = Double(fileNameLocalSize) / 1e9 let assembleTimePerGB: Double = 3 * 60 // 3 min @@ -604,7 +510,6 @@ import SwiftyJSON options.timeout = max(assembleTimeMin, min(assembleTimePerGB * assembleSizeInGB, assembleTimeMax)) self.moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileName, overwrite: true, options: options) { _, error in - guard error == .success else { return completion(account, filesChunkOutput, nil, nil, NKError(errorCode: NKError.chunkMoveFile, errorDescription: error.errorDescription)) } @@ -624,12 +529,11 @@ import SwiftyJSON // MARK: - SessionDelegate public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - if self.nkCommonInstance.delegate == nil { self.nkCommonInstance.writeLog("[WARNING] URLAuthenticationChallenge, no delegate found, perform with default handling") completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) } else { - self.nkCommonInstance.delegate?.authenticationChallenge?(session, didReceive: challenge, completionHandler: { authChallengeDisposition, credential in + self.nkCommonInstance.delegate?.authenticationChallenge(session, didReceive: challenge, completionHandler: { authChallengeDisposition, credential in if self.nkCommonInstance.levelLog > 1 { self.nkCommonInstance.writeLog("[INFO AUTH] Challenge Disposition: \(authChallengeDisposition.rawValue)") } @@ -647,13 +551,9 @@ final class AlamofireLogger: EventMonitor { } func requestDidResume(_ request: Request) { - if self.nkCommonInstance.levelLog > 0 { - self.nkCommonInstance.writeLog("Network request started: \(request)") - if self.nkCommonInstance.levelLog > 1 { - let allHeaders = request.request.flatMap { $0.allHTTPHeaderFields.map { $0.description } } ?? "None" let body = request.request.flatMap { $0.httpBody.map { String(decoding: $0, as: UTF8.self) } } ?? "None" @@ -664,25 +564,20 @@ final class AlamofireLogger: EventMonitor { } func request(_ request: DataRequest, didParseResponse response: AFDataResponse) { - guard let date = self.nkCommonInstance.convertDate(Date(), format: "yyyy-MM-dd' 'HH:mm:ss") else { return } let responseResultString = String("\(response.result)") let responseDebugDescription = String("\(response.debugDescription)") let responseAllHeaderFields = String("\(String(describing: response.response?.allHeaderFields))") if self.nkCommonInstance.levelLog > 0 { - if self.nkCommonInstance.levelLog == 1 { - if let request = response.request { let requestString = "\(request)" self.nkCommonInstance.writeLog("Network response request: " + requestString + ", result: " + responseResultString) } else { self.nkCommonInstance.writeLog("Network response result: " + responseResultString) } - } else { - self.nkCommonInstance.writeLog("Network response result: \(date) " + responseDebugDescription) self.nkCommonInstance.writeLog("Network response all headers: \(date) " + responseAllHeaderFields) } diff --git a/Sources/NextcloudKit/NextcloudKitBackground.swift b/Sources/NextcloudKit/NextcloudKitBackground.swift index e6993a22..b52ce971 100644 --- a/Sources/NextcloudKit/NextcloudKitBackground.swift +++ b/Sources/NextcloudKit/NextcloudKitBackground.swift @@ -23,7 +23,7 @@ import Foundation -@objc public class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDelegate, URLSessionDownloadDelegate { +public class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDelegate, URLSessionDownloadDelegate { let nkCommonInstance: NKCommon public init(nkCommonInstance: NKCommon) { @@ -33,21 +33,17 @@ import Foundation // MARK: - Download - @objc public func download(serverUrlFileName: Any, - fileNameLocalPath: String, - taskDescription: String? = nil, - session: URLSession) -> URLSessionDownloadTask? { - + public func download(serverUrlFileName: Any, + fileNameLocalPath: String, + taskDescription: String? = nil, + session: URLSession) -> URLSessionDownloadTask? { var url: URL? - if serverUrlFileName is URL { url = serverUrlFileName as? URL } else if serverUrlFileName is String || serverUrlFileName is NSString { url = (serverUrlFileName as? String)?.encodedToUrl as? URL } - guard let urlForRequest = url else { return nil } - var request = URLRequest(url: urlForRequest) let loginString = "\(self.nkCommonInstance.user):\(self.nkCommonInstance.password)" guard let loginData = loginString.data(using: String.Encoding.utf8) else { @@ -68,26 +64,22 @@ import Foundation // MARK: - Upload - @objc public func upload(serverUrlFileName: Any, - fileNameLocalPath: String, - dateCreationFile: Date?, - dateModificationFile: Date?, - taskDescription: String? = nil, - session: URLSession) -> URLSessionUploadTask? { - + public func upload(serverUrlFileName: Any, + fileNameLocalPath: String, + dateCreationFile: Date?, + dateModificationFile: Date?, + taskDescription: String? = nil, + session: URLSession) -> URLSessionUploadTask? { var url: URL? - if serverUrlFileName is URL { url = serverUrlFileName as? URL } else if serverUrlFileName is String || serverUrlFileName is NSString { url = (serverUrlFileName as? String)?.encodedToUrl as? URL } - guard let urlForRequest = url else { return nil } var request = URLRequest(url: urlForRequest) - let loginString = "\(self.nkCommonInstance.user):\(self.nkCommonInstance.password)" guard let loginData = loginString.data(using: String.Encoding.utf8) else { return nil @@ -117,40 +109,36 @@ import Foundation // MARK: - SessionDelegate public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { - guard totalBytesExpectedToWrite != NSURLSessionTransferSizeUnknown else { return } guard let url = downloadTask.currentRequest?.url?.absoluteString.removingPercentEncoding else { return } let fileName = (url as NSString).lastPathComponent let serverUrl = url.replacingOccurrences(of: "/" + fileName, with: "") let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite) - self.nkCommonInstance.delegate?.downloadProgress?(progress, totalBytes: totalBytesWritten, totalBytesExpected: totalBytesExpectedToWrite, fileName: fileName, serverUrl: serverUrl, session: session, task: downloadTask) + self.nkCommonInstance.delegate?.downloadProgress(progress, totalBytes: totalBytesWritten, totalBytesExpected: totalBytesExpectedToWrite, fileName: fileName, serverUrl: serverUrl, session: session, task: downloadTask) } public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { - self.nkCommonInstance.delegate?.downloadingFinish?(session, downloadTask: downloadTask, didFinishDownloadingTo: location) + self.nkCommonInstance.delegate?.downloadingFinish(session, downloadTask: downloadTask, didFinishDownloadingTo: location) } public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { - guard totalBytesExpectedToSend != NSURLSessionTransferSizeUnknown else { return } guard let url = task.currentRequest?.url?.absoluteString.removingPercentEncoding else { return } let fileName = (url as NSString).lastPathComponent let serverUrl = url.replacingOccurrences(of: "/" + fileName, with: "") let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend) - self.nkCommonInstance.delegate?.uploadProgress?(progress, totalBytes: totalBytesSent, totalBytesExpected: totalBytesExpectedToSend, fileName: fileName, serverUrl: serverUrl, session: session, task: task) + self.nkCommonInstance.delegate?.uploadProgress(progress, totalBytes: totalBytesSent, totalBytesExpected: totalBytesExpectedToSend, fileName: fileName, serverUrl: serverUrl, session: session, task: task) } public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - - var fileName: String = "", serverUrl: String = "", etag: String?, ocId: String?, date: NSDate?, dateLastModified: NSDate?, length: Int64 = 0 + var fileName: String = "", serverUrl: String = "", etag: String?, ocId: String?, date: Date?, dateLastModified: Date?, length: Int64 = 0 let url = task.currentRequest?.url?.absoluteString.removingPercentEncoding - if url != nil { - fileName = (url! as NSString).lastPathComponent - serverUrl = url!.replacingOccurrences(of: "/" + fileName, with: "") + if let url { + fileName = (url as NSString).lastPathComponent + serverUrl = url.replacingOccurrences(of: "/" + fileName, with: "") } - var nkError: NKError = .success if let httpResponse = (task.response as? HTTPURLResponse) { @@ -178,7 +166,7 @@ import Foundation } else if self.nkCommonInstance.findHeader("etag", allHeaderFields: header) != nil { etag = self.nkCommonInstance.findHeader("etag", allHeaderFields: header) } - if etag != nil { etag = etag!.replacingOccurrences(of: "\"", with: "") } + if etag != nil { etag = etag?.replacingOccurrences(of: "\"", with: "") } if let dateString = self.nkCommonInstance.findHeader("date", allHeaderFields: header) { date = self.nkCommonInstance.convertDate(dateString, format: "EEE, dd MMM y HH:mm:ss zzz") } @@ -189,9 +177,9 @@ import Foundation } if task is URLSessionDownloadTask { - self.nkCommonInstance.delegate?.downloadComplete?(fileName: fileName, serverUrl: serverUrl, etag: etag, date: date, dateLastModified: dateLastModified, length: length, task: task, error: nkError) + self.nkCommonInstance.delegate?.downloadComplete(fileName: fileName, serverUrl: serverUrl, etag: etag, date: date, dateLastModified: dateLastModified, length: length, task: task, error: nkError) } else if task is URLSessionUploadTask { - self.nkCommonInstance.delegate?.uploadComplete?(fileName: fileName, serverUrl: serverUrl, ocId: ocId, etag: etag, date: date, size: task.countOfBytesExpectedToSend, task: task, error: nkError) + self.nkCommonInstance.delegate?.uploadComplete(fileName: fileName, serverUrl: serverUrl, ocId: ocId, etag: etag, date: date, size: task.countOfBytesExpectedToSend, task: task, error: nkError) } if nkError.errorCode == 0 { @@ -202,12 +190,11 @@ import Foundation } public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - if self.nkCommonInstance.delegate == nil { self.nkCommonInstance.writeLog("[WARNING] URLAuthenticationChallenge, no delegate found, perform with default handling") completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) } else { - self.nkCommonInstance.delegate?.authenticationChallenge?(session, didReceive: challenge, completionHandler: { authChallengeDisposition, credential in + self.nkCommonInstance.delegate?.authenticationChallenge(session, didReceive: challenge, completionHandler: { authChallengeDisposition, credential in if self.nkCommonInstance.levelLog > 1 { self.nkCommonInstance.writeLog("[INFO AUTH] Challenge Disposition: \(authChallengeDisposition.rawValue)") } @@ -217,6 +204,6 @@ import Foundation } public func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { - self.nkCommonInstance.delegate?.urlSessionDidFinishEvents?(forBackgroundURLSession: session) + self.nkCommonInstance.delegate?.urlSessionDidFinishEvents(forBackgroundURLSession: session) } } diff --git a/Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV_Async.swift b/Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV_Async.swift deleted file mode 100644 index 7f1015e8..00000000 --- a/Sources/NextcloudKit/WebDAV/NextcloudKit+WebDAV_Async.swift +++ /dev/null @@ -1,101 +0,0 @@ -// -// NextcloudKit+WebDAV_Async.swift -// NextcloudKit -// -// Created by Marino Faggiana on 19/10/22. -// -// Copyright © 2022 Marino Faggiana. All rights reserved. -// Author Marino Faggiana -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -import Foundation - -@available(iOS 13.0, *) -extension NextcloudKit { - - public func createFolder(serverUrlFileName: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, ocId: String?, date: NSDate?, error: NKError) { - - await withUnsafeContinuation({ continuation in - createFolder(serverUrlFileName: serverUrlFileName, options: options) { account, ocId, date, error in - continuation.resume(returning: (account: account, ocId: ocId, date: date, error: error)) - } - }) - } - - public func deleteFileOrFolder(serverUrlFileName: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - deleteFileOrFolder(serverUrlFileName: serverUrlFileName, options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } - - public func readFileOrFolder(serverUrlFileName: String, - depth: String, - showHiddenFiles: Bool = true, - requestBody: Data? = nil, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, files: [NKFile], data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: depth, showHiddenFiles: showHiddenFiles, requestBody: requestBody, options: options) { account, files, data, error in - continuation.resume(returning: (account: account, files: files, data: data, error: error)) - } - }) - } - - public func copyFileOrFolder(serverUrlFileNameSource: String, - serverUrlFileNameDestination: String, - overwrite: Bool, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - copyFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite, options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } - - public func moveFileOrFolder(serverUrlFileNameSource: String, - serverUrlFileNameDestination: String, - overwrite: Bool, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, error: NKError) { - - await withUnsafeContinuation({ continuation in - moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite, options: options) { account, error in - continuation.resume(returning: (account: account, error: error)) - } - }) - } - - public func searchMedia(path: String = "", - lessDate: Any, - greaterDate: Any, - elementDate: String, - limit: Int, - showHiddenFiles: Bool, - includeHiddenFiles: [String] = [], - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, files: [NKFile], data: Data?, error: NKError) { - - await withUnsafeContinuation({ continuation in - searchMedia(path: path, lessDate: lessDate, greaterDate: greaterDate, elementDate: elementDate, limit: limit, showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, options: options) { account, files, data, error in - continuation.resume(returning: (account, files, data, error)) - } - }) - } -}