投稿時間:2023-06-19 03:07:28 RSSフィード2023-06-19 03:00 分まとめ(9件)

カテゴリー等 サイト名等 記事タイトル・トレンドワード等 リンクURL 頻出ワード・要約等/検索ボリューム 登録日
海外TECH DEV Community Create, Push, and Present Any View Controller in 1 LOC using Metaprogramming https://dev.to/ivangoremykin/create-push-and-present-any-view-controller-in-1-loc-using-metaprogramming-4o8d Create Push and Present Any View Controller in LOC using Metaprogramming TL DRWe make view controller instantiation more type safe by eliminating string IDs and use metaprogramming to generate functions that let you create push and present any view controller in LOC so you can save LOC whenever you want to perform push or present It works both with storyboard based view controllers and code only ones The generated code is autocomplete friendly Here is the full source code example ForewordAlthough SwiftUI is gaining popularity the traditional UIKit workflow will remain with us for some time I d like to share our approach to managing boilerplate code for UIViewController instantiation and navigation MotivationStoryboards are great when you need to design the appearance of your screen They are not so great when it comes to writing code required for view controller instantiation or setting up transitions via segue mechanism especially when you need tochange the existing screen sequence implement dynamic screen sequence instantiate an array of view controllers Here is the vanilla approach to dealing with view controller instantiation setting up its parameters and pushing onto the navigation stack func preCreateMyViewController Create using a string identifier MyStoryboard let storyboard UIStoryboard name MyStoryboard bundle nil Create using a string identifier MyViewController self myViewController storyboard instantiateViewController withIdentifier MyViewController as MyViewController Set parameters known at instantiation time self myViewController param I may be paranoid but not an android self myViewController param func pushMyViewController Push pre created view controller onto navigation stack navigationController pushViewController self myViewController animated true override func prepare for segue UIStoryboardSegue sender Any if let myViewController segue destination as MyViewController Set parameters known at prepare for segue time myViewController param white There are several problems with this approach Strings as identifiersSince both storyboard and view controller are accessed by string IDs MyStoryboard and MyViewController you can simply misspell them and get no compile time error at all For example you could change the storyboard s file name and forget to change corresponding string IDs in every call of UIStoryboard name MyStoryboard bundle nil and no compile time error will occur Non atomic instantiationBy non atomic I mean that a view controller is not instantiated by a single function call In order to have a fully functional view controller you ll have to do these steps Instantiate view controller from storyboard Setup parameters that are known at instantiation time Setup parameters that are known at prepare for segue time Hence the full setup process is spread across several files that leads us to a plethora of problems you might forget to do any of these steps and still get no compilation error you might copy and paste only of the required steps and still get no compilation error making any changes e g adding to the view controller a new parameter known at prepare for segue time has to be done in every prepare for sender implementation and if you forget ーyou know what You don t get a compilation error All these situations will silently leave you with a half initialized view controller which is a splendid thing to discover at runtime Lots of boilerplate and code duplicationIt costs us LOC for view controller instantiation preparing for a segue and pushing a view controller onto the navigation stack It s just annoying to repeat those lines in any other place that leads to your view controller It should be only LOC SolutionOver the years we have shifted to the “design in a storyboard compose in code approach We do not use segues for transitioning between screens hence we do not pass parameters between screens in prepare for sender Instead we do our design in a storyboard and instantiate compose and route the screens in code Another important aspect of our programming approach is to move as much of runtime errors to compile time as possible so we could get closer to the holy grail of the “if no errors at build time then no errors at runtime paradigm There are many possible types of errors that might occur at runtime There are not so many mechanics to detect and prevent those runtime errors at the build time There is one tool at our disposal that flawlessly works at the build time ーthe type system Hence we try to express our runtime problems as compile time type problems in order to prevent runtime errors by getting compile time errors Let the compiler help you We will modify our vanilla example in easy steps Eliminate String IdentifiersMake Instantiation AtomicCreate LOC NavigationEliminate Boilerplate with MetaprogrammingAdd Resource Consistency Tests using Metaprogramming Eliminate String IdentifiersLet s get rid of those string identifiers Instead oflet storyboard UIStoryboard name MyStoryboard bundle nil let myViewController storyboard instantiateViewController withIdentifier MyViewController as MyViewController…we will writelet myViewController UIViewController instantiate myStoryboard MyViewController self We assume that view controller s Storyboard ID is equal to its type name UIViewController instantiate is a utility function It creates a view controller and casts it to the specified type hence the client doesn t have to write cast herself extension UIViewController static func instantiate lt ViewController UIViewController gt storyboardName UIStoryboard Name viewControllerType ViewController Type gt ViewController let storyboard UIStoryboard name storyboardName rawValue bundle nil return storyboard instantiateViewController withIdentifier String describing ViewController self as ViewController UIStoryboard Name is a project specific enum extension UIStoryboard enum Name String case main case myStoryboard case yourStoryboard If you misspell the storyboard name when calling UIViewController instantiate then it just won t compile If you type the wrong view controller type name then it just won t compile Type system to the rescue This approach is not persistent to changes of a storyboard file name or changes of a view controller type name In order to guarantee correct naming at runtime we generate resource consistency tests We will cover this later in the corresponding section Make Instantiation AtomicSince we want our view controllers to be instantiated by a single function call we completely drop segues and instead of this let myViewController UIViewController instantiate myStoryboard MyViewController self Set parameters known at instantiation timeself myViewController param I may be paranoid but not an android self myViewController param override func prepare for segue UIStoryboardSegue sender Any if let myViewController segue destination as MyViewController Set parameters known at prepare for segue time myViewController param white …we writelet myViewController createMyViewController I may be paranoid but not an android white For each view controller there is a createMyViewController function that takes all parameters required for the view controller to be initialized and operational We oblige all our view controllers to implement an initialize function that takes all parameters required for this view controller class MyViewController UIViewController MARK Parameters var param String var param Int var param UIColor MARK Initialization func initialize param String param Int param UIColor self param param self param param self param param Hence the createMyViewController function will look like this func createMyViewController param String param Int param UIColor gt MyViewController let myViewController UIViewController instantiate myStoryboard MyViewController self myViewController initialize param param param param param param return myViewController The initialize should only be called once and only by a create function The initialize is written by hand but createMyViewController is generated by a metaprogramming template We will discuss code generation later Now we have an atomic instantiation of our view controller provided by createMyViewController functions These functions are safer for copy pasting since you can t copy half of a function call and deal with a half initialized view controller as a result If you forget to pass some parameters to createMyViewController function then the compiler will be happy to let you know Once again type system to the rescue Create LOC NavigationNow that we have createMyViewController we want to push or present our view controller In many cases we create a view controller only to pass it to the navigation controller let myViewController createMyViewController I may be paranoid but not an android white navigationController pushViewController myViewController animated animated It would be much nicer if we could just write navigationController pushMyViewController I may be paranoid but not an android white animated For each view controller we have pushMyViewController and presentMyViewController which are generated by a metaprogramming template that will be discussed later in the corresponding section Don t Pollute the Global NamespaceIf you work on a moderate size project then you are probably going to have screens That means that you will have create push and present functions generated for you Since we don t want to pollute the global namespace with these functions we need a place to store all these functions Where do we put them A hint might be found in the essay Learnable Programming by Bret Victor where he writes Strangely I don t actually know of any APIs that are intentionally designed with autocomplete in mind We are going to fix that This is how our create functions will look like UIViewController create myViewController param param param UIViewController create yourViewController param param The implementation is trivial extension UIViewController static let create UIViewControllerCreate class UIViewControllerCreate func myViewController param param param gt MyViewController … func yourViewController param param gt YourViewController … Same for navigation we will write our push and present functions just like this navigationController push myViewController param param param animated yourViewController present myViewController param param param animated This implementation is a bit different since we want our functions to be called on an instance of UINavigationController in case of push and on an instance of UIViewController in case of present extension UINavigationController var push UINavigationControllerPush return UIViewControllerFactory self class UINavigationControllerPush weak var navigationController UINavigationController init navigationController UINavigationController self navigationController navigationController func myViewController param String param Int param UIColor animated Bool … func yourViewController param String param Double animated Bool … We have just added a single extension property to UINavigationController class and extension properties to UIViewController Each of those extension properties has functions Eliminate Boilerplate with MetaprogrammingNow that we have designed our APIs we can generate the code For each view controller in our project we are going to generate functions create push and present We are going to generate code with Sourcery ーa tool developed by Krzysztof Zabłocki Despite the recent announcement of Swift Macros the development workflow built on Sourcery has proven to be efficient and we ve only just begun discussions about transitioning to Swift Macros Sourcery operates as follows you provide a template file Sourcery parses your source code and then generates code based on your template and the parsed source code Sourcery can be used as a standalone executable or embedded right into the Xcode building process as a Run Script phase It automatically regenerates code on any changes in your template file or in the project source files We write our templates in Swift Sourcery s API is way richer than Swift s native reflection You can iterate over types presented in your project filter them and access all their functions variable names template arguments and so on This is how you iterate over all view controllers that have an initialize method types classes filter inheritedTypes contains UIViewController amp amp hasMethod named initialize map name sorted by lt forEach print The functions to be generated ーcreate push and present ーhave almost the same signature as initialize the only difference is the animated parameter in the latter two HandwrittenmyViewController initialize param param param GeneratedUIViewController create myViewController param param param navigationController push myViewController param param param animated yourViewController present myViewController param param param animated In our Sourcery template we iterate over all view controllers look at their initialize methods and replicate the same signature in create push and present and add an animated parameter at the end of push and present If a view controller doesn t need parameters to be set and hence doesn t have an initialize method then its create function will not have parameters and push and present will get only the animated parameter There is one more thing to be considered regarding the create function We need to know UIStoryboard Name for those view controllers that are instantiated from a storyboard We make all such view controllers conform to StoryboardInstantiatable protocol protocol StoryboardInstantiatable UIViewController static var storyboardName UIStoryboard Name get We could use Sourcery annotations to specify the UIStoryboard Name but it wouldn t work with the Xcode refactoring tool when we need to rename those UIStoryboard Name cases This is how MyViewController conforms to StoryboardInstantiatable protocol extension MyViewController StoryboardInstantiatable static var storyboardName UIStoryboard Name return myStoryboard It is extremely valuable when you want to add a new parameter to the initialize function and those changes are instantly reflected in create push and present since Sourcery automatically regenerates them after every change of initialize No need to manually forward a new parameter to functions Add Resource Consistency Tests using MetaprogrammingNow that we have dropped string identifiers the instantiation of a storyboard based view controller looks like this let myViewController UIViewController instantiate myStoryboard MyViewController self If a storyboard file name or a view controller type name is changed then the compile time error will not occur If we can t catch errors at compile time then we catch them at test time Once again Sourcery comes to the rescue In order to guarantee the correct naming of all related resources storyboard file names view controllers storyboard IDs we generate resource consistency tests There are groups of these tests storyboard tests and view controller tests Storyboard tests are intended to check whether every case from UIStoryboard Name enum successfully loads a storyboard by its rawValue Here is an example of such a test for one case class StoryboardNameTests XCTestCase func testStoryboardA XCTAssertNotNil getPath for storyboardA private func getPath for storyboardName UIStoryboard Name gt String return Bundle main path forResource storyboardName fileName ofType storyboardc View controller tests are intended to check whether every view controller that conforms to StoryboardInstantiatable protocol can be instantiated from its storyboard their type names must equal their Storyboard IDs Here is an example of such a test class InstantiateUIViewControllerTests XCTestCase func testMyViewController XCTAssertTrue canBeInstantiated MyViewController self private func canBeInstantiated lt ViewController StoryboardInstantiatable gt viewControllerType ViewController Type gt Bool return UIViewController instantiate storyBoardName ViewController storyboardName fileName viewControllerId String describing ViewController self is ViewController It is important to say that there is an elegant solution to the resource consistency problem that we haven t adapted yet Instead of testing raw values of UIStoryboard Name cases we could just generate the UIStoryboard Name enum Please refer to SwiftGen for the details DiscussionIn order to eliminate error prone and boilerplate code we have developed a type safe solution using metaprogramming We don t pollute the global namespace and design our API with autocomplete in mind In every place where you want to push a view controller instead of LOC now you can write only navigationController pushMyViewController I may be paranoid but not an android white animated The less code the more opportunities for new pattern discovery and further improvements For the sake of simplicity we have been working with vanilla UINavigationController The presented metaprogramming approach can be adapted to more sophisticated navigation architectures such as coordinators and other forms of user interactions We prefer functional programming over object oriented that s why UIViewController multilevel inheritance is not supported in our templates One of the drawbacks of our approach is that initialize is not a private method If we want to have our view controller in one file and all generated code in another then we can t make the initialize function private since createMyViewController must access initialize At the same time Sourcery supports inlining generated code right into the source files instead of separate files but we just don t even want to look at this boilerplate while programming our view controllers Therefore there is a tacit convention “don t manually call an initialize method luckily our programmers are intelligent enough to follow it The full example Xcode project with a typical project structure including all discussed Sourcery templates can be found here AcknowledgmentsI would like to thank Dmitry Cherednikov and Vyacheslav Shakaev for their constructive criticism and valuable comments on the draft version of this text I would also like to thank Michael Goremykin for his contribution to the templates source code 2023-06-18 17:39:11
海外TECH Engadget Microsoft confirms June Outlook and OneDrive outages were caused by DDoS attacks https://www.engadget.com/microsoft-confirms-june-outlook-and-onedrive-outages-were-caused-by-ddos-attacks-173431319.html?src=rss Microsoft confirms June Outlook and OneDrive outages were caused by DDoS attacksEarlier this month a group known as Anonymous Sudan took credit for a service outage that disrupted access to Outlook OneDrive and a handful of other Microsoft online services After initially sharing little information about the incident the company confirmed late Friday it had been the target of a series of distributed denial of service attacks In a blog post spotted by the Associated Press via The Verge Microsoft said the attacks “temporarily impacted the availability of some services adding they were primarily designed to generate “publicity for a threat actor the company has dubbed Storm Under Microsoft s threat actor naming convention Storm is a temporary designator the company employs for groups whose affiliation it hasn t definitively established yet “We have seen no evidence that customer data has been accessed or compromised the company said In a statement Microsoft shared with the Associated Press the tech giant confirmed Anonymous Sudan was responsible for the attacks It s not clear how many Microsoft customers were affected by the attacks or if the impact was global The company believes Storm likely relied on a combination of virtual private servers and rented cloud infrastructure to carry out its operation Per Bleeping Computer Anonymous Sudan began carrying out cyberattacks at the start of At the time the group claimed it was targeting countries that meddle in Sudanese politics and promote anti Muslim policies However some cybersecurity researchers believe the group is in fact an offshoot of the Kremlin affiliated Killnet gang and the reference to Sudan is a false flag designed to mislead casual onlookers The likelihood of that link became more apparent on Friday when Anonymous Sudan said it was forming a “Darknet Parliament with Killnet and Revil another pro Russian gang As a first order of business the alliance threatened to target SWIFT the international interbanking system the United States and European Union cut Russia off from in response to its invasion of Ukraine in early This article originally appeared on Engadget at 2023-06-18 17:34:31
ニュース BBC News - Home Graeme Souness: Football legend swims Channel for £1m fundraiser https://www.bbc.co.uk/news/uk-england-dorset-65944866?at_medium=RSS&at_campaign=KARANGA challenge 2023-06-18 17:54:58
ニュース BBC News - Home Birmingham police save 'slippery customer' boa constrictor spotted in road https://www.bbc.co.uk/news/uk-england-birmingham-65943681?at_medium=RSS&at_campaign=KARANGA birmingham 2023-06-18 17:07:09
ニュース BBC News - Home Couple and pets saved after lightning strike house blaze https://www.bbc.co.uk/news/uk-england-essex-65943092?at_medium=RSS&at_campaign=KARANGA service 2023-06-18 17:05:04
ニュース BBC News - Home The Ashes 2023: Australia hit England between Edgbaston showers https://www.bbc.co.uk/sport/cricket/65944876?at_medium=RSS&at_campaign=KARANGA The Ashes Australia hit England between Edgbaston showersEngland are hit by a one two punch from Australia in a devastating minute break in the rain that ruined the third day of the first Ashes Test 2023-06-18 17:16:03
ニュース BBC News - Home The Ashes 2023: England struggle as the rain takes over on day three https://www.bbc.co.uk/sport/av/cricket/65943790?at_medium=RSS&at_campaign=KARANGA The Ashes England struggle as the rain takes over on day threeWatch highlights of day three of the Ashes as Australia lose their last four wickets for runs in balls and England lose two openers before the rain stops play 2023-06-18 17:23:44
ビジネス ダイヤモンド・オンライン - 新着記事 やることが3個以上あるとパニック…発達障害の僕が発見した「先延ばしグセ」に効くスゴ技【書籍オンライン編集部セレクション】 - 発達障害サバイバルガイド https://diamond.jp/articles/-/324164 2023-06-19 02:55:00
海外TECH reddit Excel vs. Fnatic / LEC 2023 Summer - Week 1 / Post-Match Discussion https://www.reddit.com/r/leagueoflegends/comments/14cq77b/excel_vs_fnatic_lec_2023_summer_week_1_postmatch/ Excel vs Fnatic LEC Summer Week Post Match DiscussionLEC SUMMER Official page Leaguepedia Liquipedia Eventvods com New to LoL Fnatic Excel Esports FNC Leaguepedia Liquipedia Website Twitter Facebook YouTube Subreddit XL Leaguepedia Liquipedia Website Twitter Facebook YouTube MATCH FNC vs XL Winner Fnatic in m POG Noah Bans Bans G K T D B FNC draven poppy neeko wukong malphite k I B I I XL vi leblanc milio maokai viego k HT H O H FNC vs XL Oscarinin ksante TOP renekton Odoamne Razork kindred JNG sejuani Peach Humanoid annie MID ahri Abbedagge Noah aphelios BOT zeri Patrik Trymbi yuumi SUP rakan LIMIT This thread was created by the Post Match Team submitted by u Embarrassed Can to r leagueoflegends link comments 2023-06-18 17:36:27

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)