I want to migrate our large Objective-C-based iOS project to Swift. So what's the best way: Import Swift files into Objective-C, or import the Objective-C project into a fresh new Swift project? What will be the fastest ?
Thanks
After time I spent of the project migration to the Swift I can say that it is no silver bullet in this question. It is really depending on the flow that is set-app in the team that you are working.
From my point of view and experience you should take existing project and start to write all new logic using Swift and in parallel try to rewrite business lawyers of the application in the modern way. For example network layer, database layer. In this way you reduce regression of the application and receive controlled migration flow.
Pros:
New logic will be in Swift.
Step by step migration will balance
regression.
Suport of legacy code that impossible to rewrite to Swift
Writing code in Swift way (Protocols, Function, Generics, Structures)
Cons:
Time
Regression of the app
Quite big rewriting of the code.
If you are starting a fresh project with the aim to only use Swift in the future, then I would create a new Swift project and then link to your Objective-C framework. This is what we did where I work, and slowly over time we have been deleting from the Objective-C project anything that is not being used. This may not be quicker than importing everything into the same project, but will give your code some separation from the old Objective-C code.
It's a very complex question and the answer is: Depends...
I think there are a few questions to make before answer yours:
Is your project "open", your team is developing new features on the same code base? or has a solid and reliable code base and just a little changes?
Can your company afford a "NEW VERSION" entirely made in Swift with new engineering?
Basically, make a big refactor (as language migration) involves a re-engineering job too, most things will not work if you just transcript the code base and if you do so, you are losing all the Swift benefits and there is no Win situation to change your code.
In my point of view, creating a new project is just a good thing to do if you will make a new version of your app. Is cleaner, is better, but like I've said there will be a lot of job and re-engineering.
Otherwise, just embed Swift code into an Objective-C running app, will cause a lot of trouble and confusion. But is faster and you can continue with new features and implementing improvements on your app.
So, here is my 2 cents to your problem:
I would recommend slow code conversion or rather refactoring to Swift if required for new code parts.
Furthermore, if the converted code is currently being used in other side projects (feature branches etc.) you could not ensure that it would still work accordingly.
I hope you got unit tests in place, because those could make life easiert. Anyway, consider the aspect of regression testing of your application's features. Libraries you use, would now have to be frameworks (some Libraries might not compile as Framework, be aware of that).
IF you really want to convert the code base, I would do this hirarchically.
Consider an entire Application Layer and within this layer
specific classes.
Start writing tests for those classes (you can do that in Swift, too), Unit Test, Integration Test, UI Tests
Convert the class to a swift class (be aware that some logic might change and other functions would be affected, too)
Implement bridging header (if necessary) that you can use as Application Layer interface to the other interfaces - this would even improve your understanding of the different code parts play together. If you notice some weird declarations. Stuff being public, too much random accesses fro different classes or something. Don't touch that yet. In fact, note that down
Perform extensive tests of your small change
Start over again with the next class
If all classes have finished on your current Application Layer and you broke nothing. Good job. Now have a look for your notes.
Continue with the next layer.
In Short: I would only convert those parts to Swift that need to be changed anyway (refactoring, new features, bugs, whatever). If the code was working, and you don't see another reason than "well, now it is Swift", I would only take the conversion into account, if I really had time for that, else you might break working code or even the architecture that was setup, which differs for Swift and Objective-C in some ways.
If you really feel like you are the man for this: I would start to write tests ;-)
Unit-, Integration and UI Tests. This will help you with your CURRENT code base, but also with your future code base, whether is in Objective-C or Swift.
And it is a great help for converting the code into Swift.
I think the best way is to import the Objective-C project into a fresh new Swift. Because you can use objective c to swift converter. It saves thousands of work hours.
Related
Background:
I need to start working on project which we are hoping to maintain it for long time (Basically reusable components which will be reused in multiple projects). I was exploring the Reactive Programming and the benefits Reactive Programming brings to the table is way to high to ignore it.
I started exploring various FRP frameworks available and RxSwift, ReactiveCocoa were few such examples. But looking at the community support and swift implementation, RxSwift was obviously the choice.
Now RxSwift4 came with some breaking changes as RxSwift3 wasn't compatible with Swift4. Now community did a great job to bridge the changes smooth, though but things like DelegateProxy implemented in RxSwift3 started breaking in RxSwift4. So for those who used RxSwift3 it wasn't just a pod update but involved loads of changes as well. On following the RxSwift Git hub issue realized that its because of Swift4 changes which lead to this break.
Question:
Now its a very common risk that we take on using all third party frameworks, but with most of the frameworks I used, if broke they would have break a feature or two in app but if I write a complete app in RxSwift and future updates break, finding a replaceable library and replacing it would be a enormous job.
Here is why?
For example, if you use Alamofire, usually you will have your own Network layer in app which would expose certain API to app and app quite frankly wont worry about the library used under the hood. So replacing it is quite a easy task. But with RxSwift all asynchronous tools like delegates, blocks,notifications are already wrapped in RxSwift components like Observables,Subjects,Units etc to which we cant write a wrapper of our own and if Current RxSwift version breaks in future update we will be left with no other solution than to literally fix them one by one, as replacing library would mean complete re writing of project.
I know its a kind of opinion based question, but the problem is there is no much guiding opinion on web for the same. I would really appreciate, if somebody who used FRP frameworks in their project post the best practice to use them so that dependency on framework will be minimal and allow us to shift to new FRP framework easily in future.
EDIT:
The mention of Alamofire above is just to show how easy it is to wrap other frameworks that we use in our app only and has nothing to do with RxSwift in itself. So please don't get carried away by that :)
My short opinion-based answer is that it is safe enough starting from Swift3 because backwards-compatibility is guaranteed starting from Swift3 onwards. I use RxSwift and a bunch of derived frameworks (RxCoreData, RxCloudKit, RxGesture, RxCoreMotion and RaspSwift) extensively for about a year now, never encountered anything particularly troublesome. But then again, you mentioned some frameworks which I did not use that gave compatibility troubles. So apparently there might be unpleasant surprises, which are usually fixed quick enough by the open-source community.
I'm trying to find a straightforward way to consume arbitrary iOS libraries from MonoTouch. At the moment, I need this calendar functionality, but the question applies to any such component.
I've read the Xamarin article on creating iOS bindings, but the process of building these bindings looks so complex (and tedious and likely error prone) that I think it would actually be easier for me to re-implement the given functionality in C# from scratch than it would to go through this process. Creating these bindings would require a deep dive into ObjectiveC, and I'm using Xamarin precisely so I don't have to do that.
As it stands, I am torn because I really want the ability to access some iOS libs, but don't have the time to master this process enough to create these bindings. Is there any other way to access these libraries?
(I wonder if there is or could be any sort of automated binding generator? It seems to me that 95% of the work is boilerplate translation of ObjectiveC headers to C# idioms, and an automated tool could do this, and then the final tweaking could be done by hand.)
You can:
Consume the ones that are already bound: you can find many on github, in particular in monotouch-bindings, and in the (just announced) Xamarin's Components Store;
Bind them yourself. That does require some Objective-C knowledge. Some tools/scripts exists but, in the end, the manual by hand editing is where the Objective-C knowledge is needed. There are general unit test (e.g. for Touch.Unit) that you can re-use that will dramatically reduce the number of bugs in them (blog post will be coming up soon to describe them in details).
Convert (or write from scratch) some into C# components;
I've been browsing the DeHL repository on GoogleCode, and it looks really good to me.
Many interesting features that make basic programming tasks easier; Some neat things that are in the DotNet FCL, but are missing from the Delphi RTL can be found in this library;
Coded in a modern way, making good use of new language features;
Each class, record type, member function and parameter is documented in such a way that it'll show in the code completion of the Delphi IDE;
Well-organized and clean code;
Plenty of unit tests;
Open source and Free;
Basically, it looks like this library should've been included with Delphi, as part of the RTL.
One major drawback: The project has been discontinued. :-(
Now my question is:
Would it be safe to rely on this library for future projects, and use it as a base framework to build upon?
Basically I'd like to hear from somebody who's actually used this library whether or not it's worth it to invest time in getting to know this library, and why.
IIRC the project was discontinued because it was an over-engineered first attempt and a lot of its features turned out really messy and bloated. You should look at Alex Ciobanu's second attempt, which is simply called Collections. It contains most of the interesting features from DeHL, but leaner.
Be careful, though. It still makes heavy use of generics, which will make your binary size really big if you use it a lot, because the compiler team hasn't implemented a way to collapse duplicate code yet.
I am a total beginner in iOS development. However, I've done Java, PHP and Javascript at work for severals years, so I am pretty experienced with OOP and design patterns.
Xcode 4.2 adds the new storyboarding capability for laying out interfaces in iOS 5.0. Is storyboarding simply a wizard for beginner developers or does it have advantages for more experienced developers as well?
My coworkers and I (both beginners in iOS development) are debating whether one should learn and program iOS using traditional NIBs vs storyboards. What are the advantages that storyboarding provides over previous ways of laying out iOS interfaces? Are there disadvantages to this approach?
Learn the old way in case you have to do both (or read some legacy code). This goes for Arc too; I shudder to think of new Cocoa/Cocoa Touch developers not understanding the old managed memory model.
I think the automated and convenience methods will always cover the "common" cases, and that story-boarding is an example of that. A convenience which greatly simplifies and accelerates the development process. However, there will always be cases where these methods do not provide you with all you need in a given, unusual situation. Just like using the UI elements does not stop developers from going under the hood with core graphics, core audio and so on when they need to. It is definitely, I think, a part of the future of iOS development, but only being aware of that part would be a handicap. So would not being aware of it.
I, personally, dislike automated tools. I have no idea what happens below, what sort of surplus code is inserted, the style of code is not mine and hence I need to work on another person's code. I'm the one that needs to support it for rest of time, not whatever automated tool I may have used.
It is all the tedious abstractions that will help you understand what is going on, especially when you are new to a field.
I'm personally like the traditional nib file approach, where I have more control over its behavior programatically and not having to hack the stroyboard backward to get things done. And of cause, if you have few developer working in a project, it's always good that you don't have to spend time merging changes (since you have several nib file compare to storyboard file)
storyboard files seem to be more readable than xibs.
both are xml files but the xibs seem to have unnecessary baggage and complexity.
I have compiled a list of about 15 reasons against using Storyboards: When to use Storyboard and when to use XIBs
Also, here's a tool that takes some of the pain away: http://github.com/jfahrenkrug/StoryboardLint
I have been assigned the task to refactor a Delphi unit. Wow. 10000 lines of code, no documentation, tons of copy and paste code.
THere are many methods made with copy and paste that could be refactored, anyway I am lost in all those lines, I have the interface section where I can "find my way", but in general what do yuo suggest for tackling this kind of task?
Thanks.
Get yourself a copy of Working Effectively with Legacy Code by Michael Feathers. It has all kinds of techniques for safely refactoring code to get it running under a test framework. Examples are mostly in Java and C++ but should be easy enough to figure out.
Install a third-party refactoring tool (or multiple) such as CodeRush for Delphi(sadly no longer developed), Castalia or ModelMaker Code Explorer. Delphi has some refactoring support built in but in my experience it is too limited and tends to choke on very large code bases.
Buy a copy of Simian. It doesn't have direct support for Object Pascal but its plain text parser works well enough. If enough people request support for Object Pascal I'm sure they'd add it. I haven't found any other code duplication detection tool as capable as Simian.
I would also recommend bookmarking http://www.refactoring.com/catalog/ and http://www.industriallogic.com/xp/refactoring/catalog.html.
It also wouldn't hurt to get a copy of Clean Code: A Handbook of Agile Software Craftsmanship by Robert "Uncle Bob" Martin et al. It's easy to recognize bad code. It's much harder know when you're writing good code.
A word of caution: Focus on refactoring the code you need to work on. Its easy to start down the rabbit hole and wind up spending months refactoring code that wasn't immediately relevant to the task at hand.
And save your self some trouble. Don't try to "fix" code and refactor it at the same time. Refactor first, then fix bugs or add that new feature. Remember, refactoring is modifying without changing external behavior.
Resist the urge to attempt a complete rewrite. I learned the hard way that crappy code that meets the user's requirements is preferable to clean code that doesn't. Crappy code can always be incrementally improved until its something to be proud of.
I think the best thing you can do is to write DUnit Tests for the interface. It forces you to understand the existing code, helps during debugging and it ensures that the interface acts the same after refactoring.
The Top 12 Reasons to Write Unit Tests apply perfectly in your case:
Tests Reduce Bugs in New Features.
Tests Reduce Bugs in Existing Features.
Tests Are Good Documentation.
Tests Reduce the Cost of Change.
Tests Improve Design.
Tests Allow Refactoring.
Tests Constrain Features
Tests Defend Against Other Programmers
Testing Is Fun
Testing Forces You to Slow Down and Think
Testing Makes Development Faster
Tests Reduce Fear (Fear of change, Fear of breakage, Fear of updates)
I've faced similar situations. My condolences to you!
In my opinion, the most important thing is that you actually understand all the code as it is today. Minds better than mine may be able to simply read the code and understand it. However, I can't.
After reading the code for a general overview, I usually repeatedly single step through it in the debugger until I begin to see some patterns of operation and recognize code that I've read before. Maybe this is obvious, but thought I'd mention it.
You might also think about creating a good test suite that runs on the current code.
Does the interface section contain a bunch of class definitions? If so, create a new unit for every class and move each class to it's own unit.If you use Delphi 2007 or better, you can use the "refactor/Move" option to move those classes to the new (namespace) units.The next step is splitting the large classes into smaller classes. That's just a lot of manual work.Once your code is divided over multiple units, you can examine each unit, detect identical code and generate base classes that would be used as parent for the two classes that share similar functionality.
In addition of understanding the code etc, these tools may help refactoring and reorganizing the project:
Model Maker is powerful design, reverse-engineer and refactoring tool: http://www.modelmakertools.com/modelmaker/index.html
Model Maker Code Explorer is powerful plugin for Delphi IDE to help with refactoring, code navigation etc: http://www.modelmakertools.com/code-explorer/index.html
I would use some sort of UML tool to generate som class diagrams and other diagrams to get an overview of the system, and start splitting up and commenting like #Workshop Alex said.
Use a tool like Doxygen to help you map the code.
Help on that is here
Start out small and eventually do a partial or full rewrite. Start creating base classes to accomplish pieces of the puzzle without changing the output. Rinse-repeat until you have a new, supportable codebase.
Once you hit those copy-n-paste routines, you'll have base classes to do the work and it'll really help accelerate the task.