tag:blogger.com,1999:blog-366450982024-03-14T06:03:11.449-07:00Digerati IlluminatusIn this blog I will share insights and information concerning software development. The target audience includes Software Engineers, Software Project personnel, Software Product personnel, Management, and Executives.Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.comBlogger106125tag:blogger.com,1999:blog-36645098.post-31273686856091319012023-12-06T08:52:00.000-08:002023-12-06T08:52:46.406-08:00SpringBootApplication Simple Unit Test<p>This is an example of how to call SpringBootApplication "Application.main" in a Java unit test.</p><p>You should have setup a Spring Boot application already.</p><p>Here is an example of a simple Application class.</p><p><span style="font-family: courier;"><span style="font-size: xx-small;">@SpringBootApplication(scanBasePackages = {"com.company.stuff"})<br />public class Application<br />{<br /><br /> private static ConfigurableApplicationContext configurableApplicationContext = null;<br /><br /> public static void main(String[] args)<br /> {<br /> configurableApplicationContext = SpringApplication.run(Application.class, args);<br /> }<br /><br /> public static void shutdown()<br /> {<br /> if(null != configurableApplicationContext) {<br /> SpringApplication.exit(configurableApplicationContext);<br /> }<br /> }<br /><br />}</span></span><br /></p><p><br /></p><p>Here is an example of a unit test that starts the application on a specified port, makes a call to the application via a RestTemplate, and then shuts down the application.</p><p><br /></p><p><br /><span style="font-family: courier;"><span style="font-size: xx-small;">public class ApplicationMainTest<br />{<br /> RestTemplate restTemplate = new RestTemplate();<br /><br /> @Test<br /> public void testMain() throws Exception {<br /><br /> try {<br /> Application.main(new String[]{"--server.port=8093"});<br /><br /> String url = "http://localHost:8093";<br /> ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);<br /> assertNotNull(response);<br /><br /> }<br /> catch (Exception ignored) {<br /> //ignored<br /> }<br /> finally {<br /> Thread.sleep(10000);<br /> Application.shutdown();<br /> }<br /> }<br />}</span></span><br /></p>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-90027078000299449952023-05-06T17:21:00.009-07:002023-05-10T07:51:34.328-07:00SwiftUI Challenge Edutainment Multiplication Game<p> This is going to show the development of my solution to the <a href="https://www.hackingwithswift.com/guide/ios-swiftui/3/3/challenge">Edutainment challenge</a>.</p><p><br /></p><p>First I used a VStack and HStack to create a table layout.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv3W84JsgXs0wvya6Hn6gMXzdcBAwOVXXMeZ1VE5UoclJNioRpx5IZqbbT7njGsAD8ZSPLZF45EWPMSMgnhcd84ByWX7fXTYCvcgXZPgRKU3kgcvNt4VUZovA23CrYc4uELL9OPGtodla_A7Bn35Xogq5Sm5V6IBBM2v2JvVNAEdH-t0p3Rw/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2008.25.57.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv3W84JsgXs0wvya6Hn6gMXzdcBAwOVXXMeZ1VE5UoclJNioRpx5IZqbbT7njGsAD8ZSPLZF45EWPMSMgnhcd84ByWX7fXTYCvcgXZPgRKU3kgcvNt4VUZovA23CrYc4uELL9OPGtodla_A7Bn35Xogq5Sm5V6IBBM2v2JvVNAEdH-t0p3Rw/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2008.25.57.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Based on position I began to change the attributes of the Text.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5dD11Mv1qtYeRYDc3JjusAWp27xWUNlWsW7yAtCZGjgCLEb6ryTJ6WuX-lgGnMcTxfJuMSBXtL6BeKf95eSdpHX6-7Rs1MT9f4t9uelzbPYtxQqk4kBnKpsfiKb2PpCLMyuwVHBMZ4BBGSzHEQk3CJfOkRfFom8d1GLVSGb-ACBhhQDL0uw/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2008.59.28.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5dD11Mv1qtYeRYDc3JjusAWp27xWUNlWsW7yAtCZGjgCLEb6ryTJ6WuX-lgGnMcTxfJuMSBXtL6BeKf95eSdpHX6-7Rs1MT9f4t9uelzbPYtxQqk4kBnKpsfiKb2PpCLMyuwVHBMZ4BBGSzHEQk3CJfOkRfFom8d1GLVSGb-ACBhhQDL0uw/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2008.59.28.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">If an entry in the table is "masked" I change the output.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtho8tMzJ1cY8Z_okULZKkC_-K-iJfWgJooMPcu_cUZkN6kmQkVn1nXAMVjvgT-0l4ONQ_Fan3P6aehXAsGQsu7Du06e4tsS6G0YTnDsggwyyrWFeiZ8PtQtvaqmsYlXT6Her81xYh6BKqgCasA4s-96YTIaspb4GwkiHfwknW_FDqVJtAmw/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2008.59.38.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtho8tMzJ1cY8Z_okULZKkC_-K-iJfWgJooMPcu_cUZkN6kmQkVn1nXAMVjvgT-0l4ONQ_Fan3P6aehXAsGQsu7Du06e4tsS6G0YTnDsggwyyrWFeiZ8PtQtvaqmsYlXT6Her81xYh6BKqgCasA4s-96YTIaspb4GwkiHfwknW_FDqVJtAmw/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2008.59.38.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Then I changed the Text entries in the table to be Buttons and added a background image.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIjkbrHFMSpjcMQPdYq54V55gAehlA490XRY-PFIuCHaeqEXcw_5DlNw59VZyMMaEA9_iSPV-hRkHQogm66U3SPxF_OnKXMqg8Na31oHbUIad8eQKKefpA-Ogr5hsfXmYj87HCOPNS8KebRA7lxZfpzLMHG-MbHIjm01CaAFKUJ0RPT_SN2A/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2017.59.38.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIjkbrHFMSpjcMQPdYq54V55gAehlA490XRY-PFIuCHaeqEXcw_5DlNw59VZyMMaEA9_iSPV-hRkHQogm66U3SPxF_OnKXMqg8Na31oHbUIad8eQKKefpA-Ogr5hsfXmYj87HCOPNS8KebRA7lxZfpzLMHG-MbHIjm01CaAFKUJ0RPT_SN2A/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2017.59.38.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">For now every time the "Mask" button is pressed I randomly mask out a value. I change the mask from "*" to "??" and change the color and size on the masked value.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz-pY9TFGcViJVeuQFoB9bzyRxF3C8VWDRNuTm8Ket-bOzKswjI3di1N7_NcDkioXYnHqiCwKSnDOnGNw-dza9j9KVjcUWeaN0loVRXH9h0PtVVQRrrqrxXXsRnnaXrA0cKUOI3ZKZ7agd37gc0G6SsgqyRV3a6XHwuHYwOKj11iFwVOlSng/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.03.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz-pY9TFGcViJVeuQFoB9bzyRxF3C8VWDRNuTm8Ket-bOzKswjI3di1N7_NcDkioXYnHqiCwKSnDOnGNw-dza9j9KVjcUWeaN0loVRXH9h0PtVVQRrrqrxXXsRnnaXrA0cKUOI3ZKZ7agd37gc0G6SsgqyRV3a6XHwuHYwOKj11iFwVOlSng/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.03.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">When you tap a masked entry a question is displayed in an alert.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheCkMsSmQXvA9hra-6CTeiyKXymypH0H78qoJQbcZy00S03AtYqwhHSS2deaU6K5CPVCQE_GYMk3esPs7yCSs_91uctigUhu-6Wlnlsx_nobo_al3Gh87q0BM0sTZfwnIFJuQATUqyPvhdzEikGhFX---2iBIHKHKL6j5AwDq2n0xMVJUsYQ/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.15.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheCkMsSmQXvA9hra-6CTeiyKXymypH0H78qoJQbcZy00S03AtYqwhHSS2deaU6K5CPVCQE_GYMk3esPs7yCSs_91uctigUhu-6Wlnlsx_nobo_al3Gh87q0BM0sTZfwnIFJuQATUqyPvhdzEikGhFX---2iBIHKHKL6j5AwDq2n0xMVJUsYQ/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.15.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">If you enter the correct value another alert acknowledges and the mask is taken off the entry in the table.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT2wNZBkMvDhxpIKO0ta9LkOpN69-gt03cOxhpBtDclp8egXUIPSsis_eE-WGVKTIfg6fNB93290eAdB2vDSxtNIKa-pty0IDKN_Z5ugmM6xIJgtuLgdEwhjOhZfRqlj02baf0SiBJlFouyYpO7MfzVN6JjMTB2xzloOSpiw9aOdWgI6uj4g/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.31.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT2wNZBkMvDhxpIKO0ta9LkOpN69-gt03cOxhpBtDclp8egXUIPSsis_eE-WGVKTIfg6fNB93290eAdB2vDSxtNIKa-pty0IDKN_Z5ugmM6xIJgtuLgdEwhjOhZfRqlj02baf0SiBJlFouyYpO7MfzVN6JjMTB2xzloOSpiw9aOdWgI6uj4g/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.31.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">5 x 2 is no longer masked because of the correct answer.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" width="296" /></a><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">To get this to work I had to learn how to use an ObservableObject.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">The next thing was to select the multipliers. This is done by tapping a row or column header.</div><div class="separator" style="clear: both; text-align: left;">This allows the user to select what they want to practice. Here the user has selected column "3" and row "10". The values are masked for 3 and 10 for both the rows and the columns. This is because 3 x 5 is the same as 5 x 3.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSgFzWbiUtMhyL2VQDafPCd__lTtGD1r25qYGko9ithqbYwC_eDsnfTqYkPRuhqN2sJiXzlhMRKaodCiHQNLmrP0Hytmc_baUMbQQedc7uVJE0HJdlDYvXdmrEhaHlmIotQ6x4FZok4p2lSymjyclp06-1Xkr9A-OFNu9f9cWMXdzzkug50g/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-08%20at%2008.30.27.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSgFzWbiUtMhyL2VQDafPCd__lTtGD1r25qYGko9ithqbYwC_eDsnfTqYkPRuhqN2sJiXzlhMRKaodCiHQNLmrP0Hytmc_baUMbQQedc7uVJE0HJdlDYvXdmrEhaHlmIotQ6x4FZok4p2lSymjyclp06-1Xkr9A-OFNu9f9cWMXdzzkug50g/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-08%20at%2008.30.27.png" width="296" /></a><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Next I begin the View that will allow the user to play the game.</div><div class="separator" style="clear: both; text-align: center;"><br /></div></div><div class="separator" style="clear: both; text-align: center;"><span style="color: #0000ee;"><span style="caret-color: rgb(0, 0, 238);"><u><br /></u></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="color: #0000ee;"><span style="caret-color: rgb(0, 0, 238);"><u><br /></u></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="color: #0000ee;"><span style="caret-color: rgb(0, 0, 238);"><u><br /></u></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="color: #0000ee;"><span style="caret-color: rgb(0, 0, 238);"><u><br /></u></span></span><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUlSoMx4NpU2TD25VdKUobuvI3hdKN6Vz-zi2BZMvTZsbCgwhZVnRhrwAAIVxw3OUZIgL4CnrmlBr42wWp3g6PQAsM0naOT8sBsa8vdkk0XEz_UBvoLWx6J2gMxzNC5aO0HLGQF7yHC4N9Hvx5_QcJjuROyF02_UsgqEVAAK_3AJvymXn7A/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-08%20at%2008.29.48.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUlSoMx4NpU2TD25VdKUobuvI3hdKN6Vz-zi2BZMvTZsbCgwhZVnRhrwAAIVxw3OUZIgL4CnrmlBr42wWp3g6PQAsM0naOT8sBsa8vdkk0XEz_UBvoLWx6J2gMxzNC5aO0HLGQF7yHC4N9Hvx5_QcJjuROyF02_UsgqEVAAK_3AJvymXn7A/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-08%20at%2008.29.48.png" width="296" /></a></div></div><div class="separator" style="clear: both; text-align: center;"><span style="color: #0000ee;"><span style="caret-color: rgb(0, 0, 238);"><u><br /></u></span></span></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Next I created a new UIView and used @Binding to share the needed data. For now I just rough out the random generation of questions.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">The way it works is that the user taps a row or column header. The row or column header is currently blue when selected. Then a set of random questions are generated. I put them in a list for now. I am not sure how the UI will end up.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRuI34jhDJnpOAc16RynYfKwLPQzpx8KCywAiDDcNQKH1ZlVRVtqCl8hAQR5Ikh58xgDzrEBTIn7tC13ZFk2OMGM3FGuGoqq47tJfXMWLAXjublkO_yQsYBMJpLjhR40T92C_4QIHLL9BU8mD5joZwQKnzi5zXuyUMnJsUhJzpt9QNSr1yAA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-08%20at%2021.59.46.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRuI34jhDJnpOAc16RynYfKwLPQzpx8KCywAiDDcNQKH1ZlVRVtqCl8hAQR5Ikh58xgDzrEBTIn7tC13ZFk2OMGM3FGuGoqq47tJfXMWLAXjublkO_yQsYBMJpLjhR40T92C_4QIHLL9BU8mD5joZwQKnzi5zXuyUMnJsUhJzpt9QNSr1yAA/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-08%20at%2021.59.46.png" width="296" /></a></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">After running into bugs where all the Buttons in a Form view perform their action when any button is selected and the annoyance that an array in an Observable object doesn't update I have finally got to my final solution.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM5KQo7OXfqhrqCGr-5zcG5AAVFWSq2FkAJ4JcJX8gKwLgDx2pLlke_VYzixOC_jwNcwVx_7SpyXGFip0mjaq8HDZvoznjQnCSG50PpMEg7yzWF60F8hO-LS_uIMO6wm1ZKgzXiFt2BCiDXnIvyUE_RxbUO148YCSbfLq3LOJJdW95VF7x9Q/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-09%20at%2008.11.52.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM5KQo7OXfqhrqCGr-5zcG5AAVFWSq2FkAJ4JcJX8gKwLgDx2pLlke_VYzixOC_jwNcwVx_7SpyXGFip0mjaq8HDZvoznjQnCSG50PpMEg7yzWF60F8hO-LS_uIMO6wm1ZKgzXiFt2BCiDXnIvyUE_RxbUO148YCSbfLq3LOJJdW95VF7x9Q/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-09%20at%2008.11.52.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Changing buttons and such...</div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf3tCHlYCf9kfOuLW-hJxIxC9mVpcKGcBh2tlIyVAHMavVUTtH8HmTsWxNL9Vj3yVqjBfQTrUporXjOii_o0UQ9TO7qbsmz4Q8X0-FO_G82CH_5fkr8syBEtub_xyN25MndOynB6nqa8eCeg_VyebbCPxyW4xJedvgaK0gBr5AWiqZEcYOhg/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2006.00.53.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf3tCHlYCf9kfOuLW-hJxIxC9mVpcKGcBh2tlIyVAHMavVUTtH8HmTsWxNL9Vj3yVqjBfQTrUporXjOii_o0UQ9TO7qbsmz4Q8X0-FO_G82CH_5fkr8syBEtub_xyN25MndOynB6nqa8eCeg_VyebbCPxyW4xJedvgaK0gBr5AWiqZEcYOhg/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2006.00.53.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Getting an array of responses by using an Observable Object.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpGwfFF7ltgFEYZPYO42oWGf_JvjaNAZPcz12pEwTbmx8xTOAHBtLlnK4Vdx_qIg7mP8GvC_A3jT2gXOC5k0dXIvBr5vYgbYYunKL6H7kIGcrmKm3DYaLKN00VICNTuVsO4n-ooGIT4LfCt6I6jsPGXYTtogFaQKPZSiwUi76xBl0f3A5YOA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.00.34.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpGwfFF7ltgFEYZPYO42oWGf_JvjaNAZPcz12pEwTbmx8xTOAHBtLlnK4Vdx_qIg7mP8GvC_A3jT2gXOC5k0dXIvBr5vYgbYYunKL6H7kIGcrmKm3DYaLKN00VICNTuVsO4n-ooGIT4LfCt6I6jsPGXYTtogFaQKPZSiwUi76xBl0f3A5YOA/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.00.34.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Changing the colors.</div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCAg52k__8IlqjRzGYvjA8Wh1Pe_eRXa11jOGJqMhXbuZpUtHKgfKkPKByPTH6KhmpLoymTvadNai3rQTTYFzCFikKgACQLtco7K4jFDJqjn2A132wA-MF__LRYBefeYy1mNfGLkNNmUvtg8fYKlZpS-8nsYFtZ4hC0ChIzZTnLohDuk5Adw/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.38.50.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCAg52k__8IlqjRzGYvjA8Wh1Pe_eRXa11jOGJqMhXbuZpUtHKgfKkPKByPTH6KhmpLoymTvadNai3rQTTYFzCFikKgACQLtco7K4jFDJqjn2A132wA-MF__LRYBefeYy1mNfGLkNNmUvtg8fYKlZpS-8nsYFtZ4hC0ChIzZTnLohDuk5Adw/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.38.50.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Click a row or column label to select which number you want to practice.</div><div class="separator" style="clear: both; text-align: left;">Click Play and it will mask out the answers for how many questions you want.</div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvPh4V2rAfGihTNPb1oeg7vjXhSTayRRu7F7qm8ZCKkWEcvwPvNOXJejjr2NkhSiQlshjBfmEvRsppcrtquM_TxT0JlZkTlHvCmnOXRoVzGQwaQI1R4GGiQgOZ02o_RTHpdHoCJ77YFiCDOfopqOQeuTOLQpb8iKTqD7TiVRc-_30J8jkp7w/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.14.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvPh4V2rAfGihTNPb1oeg7vjXhSTayRRu7F7qm8ZCKkWEcvwPvNOXJejjr2NkhSiQlshjBfmEvRsppcrtquM_TxT0JlZkTlHvCmnOXRoVzGQwaQI1R4GGiQgOZ02o_RTHpdHoCJ77YFiCDOfopqOQeuTOLQpb8iKTqD7TiVRc-_30J8jkp7w/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.14.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Click a masked entry and the app prompts you.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRXVa1GUegRXeJwTKi083nel3q7mxAL55a5Ps_fd9pCc_cpdttHsgt6gwiSAUFV7I79c7ps7dd65zjG-G6OBKMxbnviLHs6YzNcIpGeMWFs4RqZ-O1TX3X2HGnXbVzdxCZuR4oJ8fQ9y-1cQp4yOm0y72iJQS2zzD3pIyee4S5tyc9R-ynww/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.30.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRXVa1GUegRXeJwTKi083nel3q7mxAL55a5Ps_fd9pCc_cpdttHsgt6gwiSAUFV7I79c7ps7dd65zjG-G6OBKMxbnviLHs6YzNcIpGeMWFs4RqZ-O1TX3X2HGnXbVzdxCZuR4oJ8fQ9y-1cQp4yOm0y72iJQS2zzD3pIyee4S5tyc9R-ynww/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.30.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgso5ouWNiWlVxeneoYWBl2ya12xGvaCEuoakFPk0afXcyh0y_5MqisweGyL9i_gUz5foQPPC_X1j9HhQ73aGX_dO-T5e5A6wVZunlHlBW1EZG2ggemjm7iCN6TtSLxWCO4Wr6NoZVKWC5Ff0cpUzO5a3A4ZVGKf1QcgQMZORuJrHuVrNmKag/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.40.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgso5ouWNiWlVxeneoYWBl2ya12xGvaCEuoakFPk0afXcyh0y_5MqisweGyL9i_gUz5foQPPC_X1j9HhQ73aGX_dO-T5e5A6wVZunlHlBW1EZG2ggemjm7iCN6TtSLxWCO4Wr6NoZVKWC5Ff0cpUzO5a3A4ZVGKf1QcgQMZORuJrHuVrNmKag/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.40.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdw7gQpMEBuHz4WZg96S3kP7fle2XZzpfO4xdhgfkuQZw4yTjL7eZ8znx6PyeSUifKRrKTZfR1XCYMxbHKGiJTBdsNM_B4NHaA-laXzYm5KESasERxFbkJr2yJI5LbaPmLLNWADpdq5Q7W9ibb0jmaw3zLj_EYI60hgP7OjGYL5kMr8WlJrA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.56.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdw7gQpMEBuHz4WZg96S3kP7fle2XZzpfO4xdhgfkuQZw4yTjL7eZ8znx6PyeSUifKRrKTZfR1XCYMxbHKGiJTBdsNM_B4NHaA-laXzYm5KESasERxFbkJr2yJI5LbaPmLLNWADpdq5Q7W9ibb0jmaw3zLj_EYI60hgP7OjGYL5kMr8WlJrA/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.39.56.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">The app keeps a list of your answers. If your answer is incorrect the value remains masked in the multiplication table.</div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbGFUmEURKIhIDSSLm6BFdvgcmqSzFOetPtFOxyvaXNl99HnT98lUVIf30bUaTP7K3es1p4ppOp5FPsg-eRKsQ2ZEkPfpxldDzqMj0nHCMnAPN457psEEcLLjQjJ2h3ZySdGcyWCBhCkKKRbW8ccybb5uKPBtD5FhAoeZ3dyw47jPf1-ilDw/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.40.07.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="1" data-original-height="2556" data-original-width="1179" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbGFUmEURKIhIDSSLm6BFdvgcmqSzFOetPtFOxyvaXNl99HnT98lUVIf30bUaTP7K3es1p4ppOp5FPsg-eRKsQ2ZEkPfpxldDzqMj0nHCMnAPN457psEEcLLjQjJ2h3ZySdGcyWCBhCkKKRbW8ccybb5uKPBtD5FhAoeZ3dyw47jPf1-ilDw/w296-h640/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-10%20at%2008.40.07.png" width="296" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: left;">I probably over did the assignment but I wanted to dig deeper.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="caret-color: rgb(0, 0, 0); color: black; text-align: left; text-decoration: none;"><br /></span></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="caret-color: rgb(0, 0, 0); color: black; text-align: left; text-decoration: none;"><br /></span></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKT_QsNmLDLa62j9J8X9W-2FhlkdPVYaZ9Ei_ufarVCI4MhSrCA1TJR_ObkRQd73KRAR57cG_SiqhzTp125KAtwtqtXvKW1z1J1hD-EF9rrvk6wNLyF5-88hHEA6l34Al0NP1qFi13-zRmKSfFwAvASA6HBmdnHQuHJMT-4KRD4E3TqXWJfA/s2556/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20-%202023-05-06%20at%2018.00.42.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-33730947114202599542023-05-03T08:17:00.000-07:002023-05-03T08:17:02.596-07:00Java JDK on Mac<div style="text-align: left;"> These are my notes on how I setup a Java JDK on my mac.<br /><br />Currently I have several JDK's installed.</div><div style="text-align: left;">To see the installations go to:<br />/usr/libexec<br /><br />Run:<br /></div><div style="text-align: left;">./java_home -V<br />Matching Java Virtual Machines (5):<br /> 17.0.1 (x86_64) "Homebrew" - "OpenJDK 17.0.1" /usr/local/Cellar/openjdk/17.0.1/libexec/openjdk.jdk/Contents/Home<br /> 17.0.1 (x86_64) "Amazon.com Inc." - "Amazon Corretto 17" /Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home<br /> 11.0.19 (x86_64) "Amazon.com Inc." - "Amazon Corretto 11" /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home<br /> 1.8.0_322 (x86_64) "Amazon" - "Amazon Corretto 8" /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home<br /><br />I use a symbolic link in /usr/local/opt to point to the java I want to use.</div><div style="text-align: left;">I make the symbolic link as follows:<br /><br />ln -sfn /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home currentjdk</div><div style="text-align: left;">Now the symbolic link "currentjdk" points to the JDK that I want.</div><div style="text-align: left;">Next I edit /etc/profile<br /><br /># System-wide .profile for sh(1)<br /><br />if [ -x /usr/libexec/path_helper ]; then<br /> eval `/usr/libexec/path_helper -s`<br />fi<br /><br />if [ "${BASH-no}" != "no" ]; then<br /> [ -r /etc/bashrc ] && . /etc/bashrc<br />fi<br /><br /><br />export JAVA_HOME="/usr/local/opt/currentjdk"<br /><br />export PATH=$JAVA_HOME/bin:$PATH</div><div style="text-align: left;"><br /></div><div style="text-align: left;">After you edit the profile you can create a new terminal and see the current version of java:<br /><br />$java -version<br />openjdk version "11.0.19" 2023-04-18 LTS<br />OpenJDK Runtime Environment Corretto-11.0.19.7.1 (build 11.0.19+7-LTS)<br />OpenJDK 64-Bit Server VM Corretto-11.0.19.7.1 (build 11.0.19+7-LTS, mixed mode)<br /><br /></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-16617183181870095892023-04-19T17:16:00.000-07:002023-04-19T17:16:46.569-07:00Swift Functions as Parameters and Trailing Closure<p>Place the following code in an XCode Play Ground:</p><p><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>import</b></span> UIKit</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #9b2393; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><b>struct</b><span style="color: rgba(0, 0, 0, 0.85);"> </span><span style="color: #0b4f79;">Person</span><span style="color: rgba(0, 0, 0, 0.85);"> {</span></p><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: rgba(0, 0, 0, 0.85);"> </span><span style="color: #9b2393;"><b>let</b></span><span style="color: rgba(0, 0, 0, 0.85);"> </span>birthYear<span style="color: rgba(0, 0, 0, 0.85);"> : </span><span style="color: #3900a0;">Int</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> <span style="color: #0f68a0;">name</span> : <span style="color: #3900a0;">String</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> <span style="color: #0f68a0;">tag</span> : <span style="color: #3900a0;">String</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//The build function allows a builder function to be passed in. That function</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//can create a new person based on the paramaters passed in</p><p style="background-color: white; color: #9b2393; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><b>extension</b><span style="color: rgba(0, 0, 0, 0.85);"> </span><span style="color: #0b4f79;">Person</span><span style="color: rgba(0, 0, 0, 0.85);"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>static</b></span> <span style="color: #9b2393;"><b>func</b></span> <span style="color: #0f68a0;">build</span>(<span style="color: #0f68a0;">birthYear</span>: <span style="color: #3900a0;">Int</span>, <span style="color: #0f68a0;">name</span>: <span style="color: #3900a0;">String</span>, <span style="color: #0f68a0;">tag</span>: <span style="color: #3900a0;">String</span>, <span style="color: #0f68a0;">builder</span>: (_ birthYear: <span style="color: #3900a0;">Int</span>, _ name : <span style="color: #3900a0;">String</span>, _ tag: <span style="color: #3900a0;">String</span>) -> Person) -> Person {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> builder(birthYear, name, tag)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//Functions can have argument labels and parameter names</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//Argument labels and Parameter names</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>func</b></span> <span style="color: #0f68a0;">personBuilderOne</span>(<span style="color: #0f68a0;">theBirthYear</span> birthYear: <span style="color: #3900a0;">Int</span>, <span style="color: #0f68a0;">theName</span> name: <span style="color: #3900a0;">String</span>, <span style="color: #0f68a0;">theTag</span> tag: <span style="color: #3900a0;">String</span>) -> Person {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> Person(birthYear: birthYear, name: name, tag: tag + <span style="color: #c41a16;">" Builder One"</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//No Argument labels, just parameter names</p><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>func</b></span><span style="color: rgba(0, 0, 0, 0.85);"> </span>personBuilderTwo<span style="color: rgba(0, 0, 0, 0.85);">(</span>birthYear<span style="color: rgba(0, 0, 0, 0.85);">: </span><span style="color: #3900a0;">Int</span><span style="color: rgba(0, 0, 0, 0.85);">, </span>name<span style="color: rgba(0, 0, 0, 0.85);">: </span><span style="color: #3900a0;">String</span><span style="color: rgba(0, 0, 0, 0.85);">, </span>tag<span style="color: rgba(0, 0, 0, 0.85);">: </span><span style="color: #3900a0;">String</span><span style="color: rgba(0, 0, 0, 0.85);">) -> Person {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> Person(birthYear: birthYear, name: name, tag: tag + <span style="color: #c41a16;">" Builder Two"</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//Parameter names are not needed when calling</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>func</b></span> <span style="color: #0f68a0;">personBuilderThree</span>(<span style="color: #0f68a0;">_</span> birthYear: <span style="color: #3900a0;">Int</span>, <span style="color: #0f68a0;">_</span> name: <span style="color: #3900a0;">String</span>, <span style="color: #0f68a0;">_</span> tag: <span style="color: #3900a0;">String</span>) -> Person {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> Person(birthYear: birthYear, name: name, tag: tag + <span style="color: #c41a16;">" Builder Three"</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//----------------------------------------------------------</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//Notice how the signature changes for the function paramter</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>var</b></span> <span style="color: #0f68a0;">person</span> = Person.build(birthYear: <span style="color: #1c00cf;">1900</span>, name: <span style="color: #c41a16;">"John"</span>, tag: <span style="color: #c41a16;">"tag"</span>, builder: personBuilderOne(theBirthYear:theName:theTag:))</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #6c36a9;">print</span><span style="color: rgba(0, 0, 0, 0.85);">(</span>person<span style="color: rgba(0, 0, 0, 0.85);">)</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #326d74;">person</span> = Person.build(birthYear: <span style="color: #1c00cf;">1900</span>, name: <span style="color: #c41a16;">"John"</span>, tag: <span style="color: #c41a16;">"tag"</span>, builder: personBuilderTwo(birthYear:<span style="color: #6c36a9;">name</span>:<span style="color: #6c36a9;">tag</span>:))</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #6c36a9;">print</span><span style="color: rgba(0, 0, 0, 0.85);">(</span>person<span style="color: rgba(0, 0, 0, 0.85);">)</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #326d74;">person</span> = Person.build(birthYear: <span style="color: #1c00cf;">1900</span>, name: <span style="color: #c41a16;">"John"</span>, tag: <span style="color: #c41a16;">"tag"</span>, builder: personBuilderThree(_:_:_:))</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #6c36a9;">print</span><span style="color: rgba(0, 0, 0, 0.85);">(</span>person<span style="color: rgba(0, 0, 0, 0.85);">)</span></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//----------------------------------------------------------</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//The builder can be done by using a closure</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">//The closure params are contrived just to show how they are used</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #326d74;">person</span> = Person.build(birthYear: <span style="color: #1c00cf;">1910</span>, name: <span style="color: #c41a16;">"Mary"</span>, tag: <span style="color: #c41a16;">"tag"</span>) { bYear, theName, theTag <span style="color: #9b2393;"><b>in</b></span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> Person(birthYear: bYear, name: theName, tag: theTag + <span style="color: #c41a16;">" Closure"</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="color: #6c36a9;">print</span><span style="color: rgba(0, 0, 0, 0.85);">(</span>person<span style="color: rgba(0, 0, 0, 0.85);">)</span></p><div><span style="color: rgba(0, 0, 0, 0.85);"><br /></span></div><div><span style="color: rgba(0, 0, 0, 0.85);">The output:</span></div><div><span style="color: rgba(0, 0, 0, 0.85);"><br /></span></div><div><p style="color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-variant-ligatures: no-common-ligatures;"><b>Person(birthYear: 1900, name: "John", tag: "tag Builder One")</b></span></p>
<p style="color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-variant-ligatures: no-common-ligatures;"><b>Person(birthYear: 1900, name: "John", tag: "tag Builder Two")</b></span></p>
<p style="color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-variant-ligatures: no-common-ligatures;"><b>Person(birthYear: 1900, name: "John", tag: "tag Builder Three")</b></span></p>
<p style="color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-variant-ligatures: no-common-ligatures;"><b>Person(birthYear: 1910, name: "Mary", tag: "tag Closure")</b></span></p></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-60482148860761591312023-01-02T10:06:00.003-08:002023-01-02T10:19:10.798-08:00UILabel UITextField UIStackView Horizontal<h1 style="text-align: left;">Introduction</h1><p><br /></p><p>This is "one" approach of using a horizontal StackView to have a label next to a text input field that keeps the space between the label and the text field during device rotation and on different screen sizes.</p><p>This approach does not use custom values for "Content Hugging Priority" or "Content Compression Resistance Priority".</p><p>There is one custom class that is needed. I called it UIViewExtended. You can call it anything you like.</p><p><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">//</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">// UIViewExtended.swift</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">// UITests</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">//</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">// Created by Geoffrey Slinker on 12/24/22.</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">//</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>import</b></span> Foundation</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>import</b></span> UIKit</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #0b4f79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>class</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>UIViewExtended<span color="rgba(0, 0, 0, 0.85)"> : </span><span style="color: #3900a0;">UIView</span><span color="rgba(0, 0, 0, 0.85)"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>enum</b></span> <span style="color: #0b4f79;">Keys</span>: <span style="color: #3900a0;">String</span> {</p><p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>case</b></span><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">proportionalSize</span><span color="rgba(0, 0, 0, 0.85)"> = </span>"ProportionalSize"</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>var</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize<span color="rgba(0, 0, 0, 0.85)"> : </span><span style="color: #3900a0;">CGSize</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><b>override</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>init</b><span color="rgba(0, 0, 0, 0.85)">(</span><span style="color: #0f68a0;">frame</span><span color="rgba(0, 0, 0, 0.85)">: </span><span style="color: #3900a0;">CGRect</span><span color="rgba(0, 0, 0, 0.85)">) {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = <span style="color: #3900a0;">CGSize</span>(<span style="color: #6c36a9;">width</span>:<span style="color: #1c00cf;">1.0</span>, <span style="color: #6c36a9;">height</span>:<span style="color: #1c00cf;">1.0</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>super</b></span>.<span style="color: #6c36a9;">init</span>(<span style="color: #6c36a9;">frame</span>:frame)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>required</b></span> <span style="color: #9b2393;"><b>init</b></span>?(<span style="color: #0f68a0;">coder</span> aDecoder: <span style="color: #3900a0;">NSCoder</span>) {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> tempSize : <span style="color: #3900a0;">CGSize</span>? = aDecoder.<span style="color: #6c36a9;">decodeCGSize</span>(<span style="color: #6c36a9;">forKey</span>: <span style="color: #1c464a;">Keys</span>.<span style="color: #326d74;">proportionalSize</span>.<span style="color: #6c36a9;">rawValue</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>if</b></span> tempSize != <span style="color: #9b2393;"><b>nil</b></span> && ( tempSize?.<span style="color: #6c36a9;">width</span> != <span style="color: #1c00cf;">0</span> && tempSize?.<span style="color: #6c36a9;">height</span> != <span style="color: #1c00cf;">0</span> ) {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = tempSize!</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>else</b></span> {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = <span style="color: #3900a0;">CGSize</span>(<span style="color: #6c36a9;">width</span>:<span style="color: #1c00cf;">1.0</span>, <span style="color: #6c36a9;">height</span>:<span style="color: #1c00cf;">1.0</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>super</b></span>.<span style="color: #6c36a9;">init</span>(<span style="color: #6c36a9;">coder</span>: aDecoder)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>override</b></span> <span style="color: #9b2393;"><b>func</b></span> <span style="color: #0f68a0;">encode</span>(<span style="color: #0f68a0;">with</span> coder: <span style="color: #3900a0;">NSCoder</span>) {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> coder.</span><span style="color: #6c36a9;">encode</span><span color="rgba(0, 0, 0, 0.85)">(</span><span style="color: #9b2393;"><b>self</b></span><span color="rgba(0, 0, 0, 0.85)">.</span>proportionalSize<span color="rgba(0, 0, 0, 0.85)">, </span><span style="color: #6c36a9;">forKey</span><span color="rgba(0, 0, 0, 0.85)">: </span><span style="color: #1c464a;">Keys</span><span color="rgba(0, 0, 0, 0.85)">.</span>proportionalSize<span color="rgba(0, 0, 0, 0.85)">.</span><span style="color: #6c36a9;">rawValue</span><span color="rgba(0, 0, 0, 0.85)">)</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>super</b></span>.<span style="color: #6c36a9;">encode</span>(<span style="color: #6c36a9;">with</span>: coder)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><b>@IBInspectable</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>var</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">intrinsicSize</span><span color="rgba(0, 0, 0, 0.85)">: </span><span style="color: #3900a0;">CGSize</span><span color="rgba(0, 0, 0, 0.85)"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>get</b></span> {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>return</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>set</b></span> {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = newValue</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>override</b></span><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>open</b></span><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>var</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>intrinsicContentSize<span color="rgba(0, 0, 0, 0.85)"> : </span><span style="color: #3900a0;">CGSize</span><span color="rgba(0, 0, 0, 0.85)"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>get</b></span> {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>return</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p><div><br /></div><p><br /></p><p><br /></p><p>The approach is to use UIViews to contain the label and text views. I call this the nested view approach.</p><p>Here is the entire layout.</p><p><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXK4B8V1M-RGLgYtfN5GrMlm0YhCJrLVEQYx04ISBUM2A8ZLFhFQ9-c7BtfJETlxlVpoc5j3jyQnkpLuRlXV6KPXtV3pdfNIzn8wsaxN1B40WZVSzHyCeGwnR9gcjWl9mfVQqXOJVVYGFNEhQ8qz2J_PsSvWqLN5TwQ0XpdWfnPi8nsZytRw/s1569/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="947" data-original-width="1569" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXK4B8V1M-RGLgYtfN5GrMlm0YhCJrLVEQYx04ISBUM2A8ZLFhFQ9-c7BtfJETlxlVpoc5j3jyQnkpLuRlXV6KPXtV3pdfNIzn8wsaxN1B40WZVSzHyCeGwnR9gcjWl9mfVQqXOJVVYGFNEhQ8qz2J_PsSvWqLN5TwQ0XpdWfnPi8nsZytRw/s16000/1.png" /></a></div><br /><p><br /></p><h1 style="text-align: left;">Steps</h1><h2 style="text-align: left;">I</h2><div>Using XCode create an iOS app with a single view. Add a ContainerView. Inside the Container View (image above - center panel - the Container View is on the right). Inside the Container View add a UIStackView Vertical.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzkFpKZqK2npSvn9qg0iMOJiNrLjmVIioT2ha7CEdZjb1F1VeK73BPqQHjCISsb4_cvXQdwYBx4uVFzviF1KdpninXFKcvJ_mtMkRdMCmhSrpzhx1iukTWdZwfo14k-tTpzqsXVQCsixccO1lts-WOQ8VzwHu3-MutYda8nXOovJisCoHXOw/s1166/2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="910" data-original-width="1166" height="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzkFpKZqK2npSvn9qg0iMOJiNrLjmVIioT2ha7CEdZjb1F1VeK73BPqQHjCISsb4_cvXQdwYBx4uVFzviF1KdpninXFKcvJ_mtMkRdMCmhSrpzhx1iukTWdZwfo14k-tTpzqsXVQCsixccO1lts-WOQ8VzwHu3-MutYda8nXOovJisCoHXOw/w640-h500/2.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Configure the UIStackView's alignment to be "fill" and distribution to be "fill".</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhns5Zh2mi0Inn1JDbwqcDgyy5cUg2WHA6jNGkY3-iEXi43iIi_Tz6w4TTvxwr1BZZfsrI-r9vp6Jx7DLPbxdKyKp3ih7cYNHgRn8w5whgVoZ003M3v-paGH4iZICZp0B_8q5OOXGF_rIoIJzljSKC1Jy3-F0lzSRepP4KA9dLbPjafGyBOew/s1166/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="910" data-original-width="1166" height="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhns5Zh2mi0Inn1JDbwqcDgyy5cUg2WHA6jNGkY3-iEXi43iIi_Tz6w4TTvxwr1BZZfsrI-r9vp6Jx7DLPbxdKyKp3ih7cYNHgRn8w5whgVoZ003M3v-paGH4iZICZp0B_8q5OOXGF_rIoIJzljSKC1Jy3-F0lzSRepP4KA9dLbPjafGyBOew/w640-h500/3.png" width="640" /></a></div><br /><div><br /></div><div>Configure the UIStackView to fill the Container View. Set the constraints as shown above.</div><div><br /></div><div><h2>II</h2><div>Add three UIViews to the UIStackView. The top two views will hold other views and the bottom view is used to control spacing.</div></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGmPIFVIpX6zu-wHxj2U1XnDWMb1uox_DAUgHh5ZuXFGxNSBC1u7Anoqf6zvnojwWbqAqlROvkOu5Ac7NRbFgWwT0iSLnobXqPMutw_4Xksk3ZEQckWJbIxJsravySWbSz-_SMH6B30DATSqWSRRM7GzgLgGN8iemGCWTR2RbxGSkxNyjQpA/s904/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="904" data-original-width="858" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGmPIFVIpX6zu-wHxj2U1XnDWMb1uox_DAUgHh5ZuXFGxNSBC1u7Anoqf6zvnojwWbqAqlROvkOu5Ac7NRbFgWwT0iSLnobXqPMutw_4Xksk3ZEQckWJbIxJsravySWbSz-_SMH6B30DATSqWSRRM7GzgLgGN8iemGCWTR2RbxGSkxNyjQpA/w608-h640/4.png" width="608" /></a></div><br /><div>Take notice of the constraints for these three views. The top two views have a height constraint of 40.</div><div><br /></div><div>I set the background color of each view to something different so that I can see their locations and boundaries more easily.</div><div><br /></div><div><h2>III</h2><div>In the top two views add to each a UIStackView that is horizontal.</div></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8rxvbpn5Y-mbaI4dGYb6OUMNxD6wTHJ3lEpC9eus1r_mY4_s9CuNFcHxz0kv4luuN79GhlPWnPVml_paPjCqqlNxV3jf97TZ2gPGrmISY4vBr7WbofoGKePzbz4_vmpn2YLJQCyd_eqTobITv8Cts3IoUMt4lQ3X56a8DhhR1MpqXqNS4zg/s1164/5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="904" data-original-width="1164" height="498" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8rxvbpn5Y-mbaI4dGYb6OUMNxD6wTHJ3lEpC9eus1r_mY4_s9CuNFcHxz0kv4luuN79GhlPWnPVml_paPjCqqlNxV3jf97TZ2gPGrmISY4vBr7WbofoGKePzbz4_vmpn2YLJQCyd_eqTobITv8Cts3IoUMt4lQ3X56a8DhhR1MpqXqNS4zg/w640-h498/5.png" width="640" /></a></div><br /><div>Set alignment to "Fill" and distribution to "Fill Proportionally".</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinoK92y7DqSVSOBPlGqp0OEo62oo0aQ9dQryR0_XGhiHwYU0LYD3s_b46xdPuCnz5S1ssaNC2W18DnHjAHsQOpRlzJZYH1MlkH3slsHJXfJSQjtwO4OzgEOpx0KUhHrt0hlD-vKb9eMqp4IZXvhnZhBkJAY4yi2xZdzbN-2Llw1a62jJ9kGA/s1164/6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="904" data-original-width="1164" height="498" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinoK92y7DqSVSOBPlGqp0OEo62oo0aQ9dQryR0_XGhiHwYU0LYD3s_b46xdPuCnz5S1ssaNC2W18DnHjAHsQOpRlzJZYH1MlkH3slsHJXfJSQjtwO4OzgEOpx0KUhHrt0hlD-vKb9eMqp4IZXvhnZhBkJAY4yi2xZdzbN-2Llw1a62jJ9kGA/w640-h498/6.png" width="640" /></a></div><br /><div>Constrain the UIStackViews to fill the UIView in which they are contained.</div><div><br /></div><div><br /></div><div><br /></div><h2 style="text-align: left;">IV</h2><div><br /></div><div>Now that you have two UIStackViews you can add views that will eventually contain the UILabel and the UITextField.</div><div><br /></div><div>Add two UIViews to the top horizontal UIStackView. Change their type to UIViewExtended. UIViewExtended will allow you to set the proportions for the view so that it fills the UIStackView in a definable manner.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwQgYxEBmU7vXLpZCERoo47hme1BEl1oF1VcOL6XKkhovYyJCbaarRA9tvXibbsRTJBqjXs1khuP6HTMnPrkPBUuD00nj4qoDx-JF9I-vCGsQ6uM6CoSSbXcE1Rdkk5mOWYtxzBFq-N6SMTN6q87Lamb-Db6KwVhlTIY6F3-EJJffb-ldZWw/s1164/7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="904" data-original-width="1164" height="497" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwQgYxEBmU7vXLpZCERoo47hme1BEl1oF1VcOL6XKkhovYyJCbaarRA9tvXibbsRTJBqjXs1khuP6HTMnPrkPBUuD00nj4qoDx-JF9I-vCGsQ6uM6CoSSbXcE1Rdkk5mOWYtxzBFq-N6SMTN6q87Lamb-Db6KwVhlTIY6F3-EJJffb-ldZWw/w640-h497/7.png" width="640" /></a></div><br /><div>For the left UIViewExtended set the constraints as shown below.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjJ65x6DGydF47TLwMPOnTEwEvByh1EKlFT5Hl2PYauhtlYfyEd7Xq9sQwfBqScq8G317aWImo0GFvrXRJZNzxbhdvDMRkj1X15hFFVXFuh7l8e4_gY1A926hERVj-pv1zq29duERW4xp_tss4YtOqbABtCLP0gG8pBjBFRVt9UpMipusmOQ/s1164/8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="904" data-original-width="1164" height="498" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjJ65x6DGydF47TLwMPOnTEwEvByh1EKlFT5Hl2PYauhtlYfyEd7Xq9sQwfBqScq8G317aWImo0GFvrXRJZNzxbhdvDMRkj1X15hFFVXFuh7l8e4_gY1A926hERVj-pv1zq29duERW4xp_tss4YtOqbABtCLP0gG8pBjBFRVt9UpMipusmOQ/w640-h498/8.png" width="640" /></a></div><br /><div><br /></div><div><br /></div><div>Also, for the left UIViewExtended set the extended attributes for the intrinsic size (4,0) :</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA0oo-eSfSB7rHSddl4y0SQ5t5hXwqlRvsuaJCPfrO11XTGCv1Fn-9c7lOgvm3cEWf-VVMW9jukMkrlUtyVaoxD3F8u3EnFhoSZVba2uVz-CyWNJde2F2IwMfxYA7pLIjzTSXkImHUk9diQYDRYHI5Jx62iOvp3be_lslFPnz1lGzCxYTXmA/s521/9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="521" data-original-width="307" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA0oo-eSfSB7rHSddl4y0SQ5t5hXwqlRvsuaJCPfrO11XTGCv1Fn-9c7lOgvm3cEWf-VVMW9jukMkrlUtyVaoxD3F8u3EnFhoSZVba2uVz-CyWNJde2F2IwMfxYA7pLIjzTSXkImHUk9diQYDRYHI5Jx62iOvp3be_lslFPnz1lGzCxYTXmA/w378-h640/9.png" width="378" /></a></div><br /><div><br /></div><div>Interface Builder can show you the intrinsic size and how it affects its placement in a UIStackView that is proportionally distributed by setting Intrinsic Size to "PlaceHolder" and enter the exact same value you used for the UIViewExtended "Intrinsic Size".</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKYKdoPWXPDi4HW-1ORPvNqfdT8Hosa7sT3qEWi3xpTPA4knwzj09vFc-A4UyeEemdTSX1bfj86EQosf95ef91jiE2DfHOhm4t-EoSmx_EA8dbfP6ioEEP6FnVger9zfNJRn1IWSXGEcr9IsAMghuDJJaIbfqwJAzw4yRfy6WLdKmjB_7Kzg/s1022/10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1022" data-original-width="307" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKYKdoPWXPDi4HW-1ORPvNqfdT8Hosa7sT3qEWi3xpTPA4knwzj09vFc-A4UyeEemdTSX1bfj86EQosf95ef91jiE2DfHOhm4t-EoSmx_EA8dbfP6ioEEP6FnVger9zfNJRn1IWSXGEcr9IsAMghuDJJaIbfqwJAzw4yRfy6WLdKmjB_7Kzg/w192-h640/10.png" width="192" /></a></div><br /><div><br /></div><div>The place holder is a hint for Interface Builder to render the view using an intrinsic size inside of Interface Builder, it does not set the value for runtime. The runtime value is set because of UIViewExtended.</div><div><br /></div><div>Now setup the right UIViewExtended.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiXk9hjMcBGHZ4a_kuAx-kbWt2-nrraWMEoI_pwQ2d-SsO-Y1x36sozAQmsXnoJhgDjygNI3CAmN1G-3BkUOpU057gg6ojNY9MDrIgROL17T8Xc-P5LTiZoUs75ajeHZ7_6YQ_SdpMvS2-Wcveg9Scjb6x7cmsZP0jcD-JRSsietzDNqMXyg/s1169/11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="908" data-original-width="1169" height="498" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiXk9hjMcBGHZ4a_kuAx-kbWt2-nrraWMEoI_pwQ2d-SsO-Y1x36sozAQmsXnoJhgDjygNI3CAmN1G-3BkUOpU057gg6ojNY9MDrIgROL17T8Xc-P5LTiZoUs75ajeHZ7_6YQ_SdpMvS2-Wcveg9Scjb6x7cmsZP0jcD-JRSsietzDNqMXyg/w640-h498/11.png" width="640" /></a></div><br /><div><br /></div><div>Set the UIViewExtended intrinsic value as shown above (2, 0). Also setup the constraints and the "PlaceHolder" values as shown below:</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJctMl2YQvNm8Niq4l1FaGuV8HMkbumAMX4KqR-28yiGbDbLcy6BVOwINY-RkXetBH7Qm1u5QO0a-e6fmL05I8-1hydnQD59Ib0V6th4ed9P2gMCM18ERNir7gkiSVm62LvsiLOdNsejeXvgG8dxfXa750YR6l7xBUZAI0vN8-yMcp1e2xPw/s1169/12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="992" data-original-width="1169" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJctMl2YQvNm8Niq4l1FaGuV8HMkbumAMX4KqR-28yiGbDbLcy6BVOwINY-RkXetBH7Qm1u5QO0a-e6fmL05I8-1hydnQD59Ib0V6th4ed9P2gMCM18ERNir7gkiSVm62LvsiLOdNsejeXvgG8dxfXa750YR6l7xBUZAI0vN8-yMcp1e2xPw/w640-h544/12.png" width="640" /></a></div><br /><div><br /></div><div>Notice that the label is right justified. In the second UIStackView the label will be left justified so that you can see how each works.</div><div><br /></div><div>Add a UILabel to the left UIViewExtended.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqttA3JpQGGXE77jVsVmcsvRIabUYCXpRagd4NyZYGw8wC-Urq-AlyeRJR8fVyBmjt9RFEajxQcneHCMoVDhAJaGkjwzdsVz4GRdvGTwtjXHskpMmb4ACs37bITJi6hBA-z8Wzn70_n5BxV9fS_JFjkXBnXGtnlHziQunJwW8ENJJvC0Cdsw/s1169/14.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="992" data-original-width="1169" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqttA3JpQGGXE77jVsVmcsvRIabUYCXpRagd4NyZYGw8wC-Urq-AlyeRJR8fVyBmjt9RFEajxQcneHCMoVDhAJaGkjwzdsVz4GRdvGTwtjXHskpMmb4ACs37bITJi6hBA-z8Wzn70_n5BxV9fS_JFjkXBnXGtnlHziQunJwW8ENJJvC0Cdsw/w640-h544/14.png" width="640" /></a></div><br /><div><br /></div><div><br /></div><div><br /></div><div>Set the constraints for the UILabel as follows:</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlgXnn0rA3-KuWZYE5wzwI-PL_1FxPLwiYgh9TX0pqPgzwAtoWjXWKKdPjSZtSD3Si86QoVkAkPWyYyvqmtxt5ZLN8ogGGvpDitNSRxA1lG5jF9N_73oPiHZ3ZXCmo9ptHcwyg6KpMCEDPfkCN_ZC-YRMEStm9l-2Lksi6MejWbqOlxB6aww/s1169/15.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="992" data-original-width="1169" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlgXnn0rA3-KuWZYE5wzwI-PL_1FxPLwiYgh9TX0pqPgzwAtoWjXWKKdPjSZtSD3Si86QoVkAkPWyYyvqmtxt5ZLN8ogGGvpDitNSRxA1lG5jF9N_73oPiHZ3ZXCmo9ptHcwyg6KpMCEDPfkCN_ZC-YRMEStm9l-2Lksi6MejWbqOlxB6aww/w640-h544/15.png" width="640" /></a></div><br /><div><br /></div><div>Add a UITextField to the UIViewExtended.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRQ4cwG2A-lXeOKmV8XjUvWeMAX9igSr2DcqJj08-Nox1rWoceta-ASFKroYd8WlP1zgwFyTv1Dt-0EBi0TQqciF2hHdW6gp-V9fwHeIuVzXx4rYQ2SNMCXdPH8gM33aKpU_HKJdfYsDHFtiHlzKV0yL-pC4l_UaoTH7UXcD8H-6sM8KK43Q/s1169/16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="992" data-original-width="1169" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRQ4cwG2A-lXeOKmV8XjUvWeMAX9igSr2DcqJj08-Nox1rWoceta-ASFKroYd8WlP1zgwFyTv1Dt-0EBi0TQqciF2hHdW6gp-V9fwHeIuVzXx4rYQ2SNMCXdPH8gM33aKpU_HKJdfYsDHFtiHlzKV0yL-pC4l_UaoTH7UXcD8H-6sM8KK43Q/w640-h544/16.png" width="640" /></a></div><br /><div><br /></div><div>Set the UITextField constraints as shown below.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2OLukGIrroA3TCy4W-g0wGnE1n6nNpqaLmvIYLlXkgC8az-qBsspwcFrTA9Pg8ZBfvSbYa_OPQ3xNmdPJ825-M896sDk7ZBFSwl-HMrN4P7fi05pP2adJvXVeur5FXn9iSeU9CkD0jNNYt4Eo3RatvaB-qbuWQ0oR3PrrStGMXqT7AUQU2w/s1169/17.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="894" data-original-width="1169" height="490" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2OLukGIrroA3TCy4W-g0wGnE1n6nNpqaLmvIYLlXkgC8az-qBsspwcFrTA9Pg8ZBfvSbYa_OPQ3xNmdPJ825-M896sDk7ZBFSwl-HMrN4P7fi05pP2adJvXVeur5FXn9iSeU9CkD0jNNYt4Eo3RatvaB-qbuWQ0oR3PrrStGMXqT7AUQU2w/w640-h490/17.png" width="640" /></a></div><br /><div><br /></div><div><br /></div><div><br /></div><div><br /></div><h2 style="text-align: left;">V</h2><div>Add two UIViews to the second horizontal UIStackView. Change their type to UIViewExtended. UIViewExtended will allow you to set the proportions for the view so that it fills the UIStackView in a definable manner.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh24dT1Lx1yScEeVxRnCOG_bJ6qxACi0j76FfOEvQ1I3Q2qleXITIuBw3MvBkfplJ2ftvY3lrjhFBnRPsiYG9n-qS-8NQldubyE3GwZiiOmvWFF_66FwR0wZaMKmdSnwrsed1zsgyTCO8EKa715owl92cMm76RmXrD-xXthSciaSFlYBEDQAQ/s1169/13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="992" data-original-width="1169" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh24dT1Lx1yScEeVxRnCOG_bJ6qxACi0j76FfOEvQ1I3Q2qleXITIuBw3MvBkfplJ2ftvY3lrjhFBnRPsiYG9n-qS-8NQldubyE3GwZiiOmvWFF_66FwR0wZaMKmdSnwrsed1zsgyTCO8EKa715owl92cMm76RmXrD-xXthSciaSFlYBEDQAQ/w640-h544/13.png" width="640" /></a></div><br /><div><br /></div><div>For the left UIViewExtended set the Intrinsic size as show above (2,0). Set the constraints for the left UIExtendedView as shown below.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWHZpemDP3sF-8658yH8furLbCojDPUJKGOGuLSNRbFZgYa6T5hpJWu2b5Tqw6sCBCiGLRFPH9IO7erav9XbHiyUDzFSKRsqch9j5sCzvfAIXI8n7C7p4db6l9RMDZcmxPRYuJfTwlmjRERck_KE4R7FILR6phAmLiCV5XxnPnNB-Z_0Tltg/s1191/18.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1191" data-original-width="1169" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWHZpemDP3sF-8658yH8furLbCojDPUJKGOGuLSNRbFZgYa6T5hpJWu2b5Tqw6sCBCiGLRFPH9IO7erav9XbHiyUDzFSKRsqch9j5sCzvfAIXI8n7C7p4db6l9RMDZcmxPRYuJfTwlmjRERck_KE4R7FILR6phAmLiCV5XxnPnNB-Z_0Tltg/w628-h640/18.png" width="628" /></a></div><br /><div><br /></div><div>Remember to set the Intrinsic Size "PlaceHolder" as shown above so the InterfaceBuilder will render the view correctly.</div><div><br /></div><div>Set up the right UIViewExtended as follows.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZP_bnPjCOOSdIvL_K0EOLsw7li03M6Eg8ZO6twx1KiHpm4awxXtl-gJeWUMbNDBBgxSgNjYWPJpRfeQBuY7vz9AQkkr5TBhqaXuEzAdHiPDGue94UUHlVYIQ2ESRka9snO0RNQ-kGlPQDOrQDN1RtY56BJD8YMcYlnrtjibxz5qnKhRs8NQ/s1169/19.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="901" data-original-width="1169" height="494" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZP_bnPjCOOSdIvL_K0EOLsw7li03M6Eg8ZO6twx1KiHpm4awxXtl-gJeWUMbNDBBgxSgNjYWPJpRfeQBuY7vz9AQkkr5TBhqaXuEzAdHiPDGue94UUHlVYIQ2ESRka9snO0RNQ-kGlPQDOrQDN1RtY56BJD8YMcYlnrtjibxz5qnKhRs8NQ/w640-h494/19.png" width="640" /></a></div><br /><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk05sBQ7_HQ348os8LtkhKAFc1ETALsb9JzwiFOvDJseM3id5OMJIYtNMBRpyN0zhzIUQlNSmRl4k4PJcXj8-8GxkD2FwwizUq7d6WfCfPWVax9LSPdgmIVuwr4WZ9H3Jhc1R6ecscnfnQavygGSBIjXC7jCyPxYQLwNGAuM68CLPPgpJF2w/s1169/20.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1149" data-original-width="1169" height="630" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk05sBQ7_HQ348os8LtkhKAFc1ETALsb9JzwiFOvDJseM3id5OMJIYtNMBRpyN0zhzIUQlNSmRl4k4PJcXj8-8GxkD2FwwizUq7d6WfCfPWVax9LSPdgmIVuwr4WZ9H3Jhc1R6ecscnfnQavygGSBIjXC7jCyPxYQLwNGAuM68CLPPgpJF2w/w640-h630/20.png" width="640" /></a></div><br /><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7tWSIA1JNj6wZnXFF5-kqMz__fit3qdFZEQXKof3Pz0cQzwqV-jAVZplgkddvflqNlNm8l_zG71HdPyGvFJZSUIGoEHzL8v_79wjHys8w_ySjpBShKfX9bQMCAFCoE_UYzkCxt8sALGPRTtyYzg0kLz-GkqS9pe4yasS2G7p2lKOe7UN8UQ/s1169/20.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1149" data-original-width="1169" height="630" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7tWSIA1JNj6wZnXFF5-kqMz__fit3qdFZEQXKof3Pz0cQzwqV-jAVZplgkddvflqNlNm8l_zG71HdPyGvFJZSUIGoEHzL8v_79wjHys8w_ySjpBShKfX9bQMCAFCoE_UYzkCxt8sALGPRTtyYzg0kLz-GkqS9pe4yasS2G7p2lKOe7UN8UQ/w640-h630/20.png" width="640" /></a></div><div><br /></div><div><br /></div><div>In the left UIViewExtended ad a UILabel and set it up as follows.</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijXv5CgRLLXfXY0ySk71u6kRoFz_CqTMcP685H5N-5QWGWGX4kRPGG0WM29z_tO1oqLbcehiZSrVnSsHS_RM8wIUfbe0lkOAcLY-of7F_59asJgI7wGoA7HbLpq70ZnTPvMdMFtgEhEV51hH3MXzcgyJz4BSKE_evo7ySTwfW2kf_ro-vYlw/s1169/21.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="965" data-original-width="1169" height="528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijXv5CgRLLXfXY0ySk71u6kRoFz_CqTMcP685H5N-5QWGWGX4kRPGG0WM29z_tO1oqLbcehiZSrVnSsHS_RM8wIUfbe0lkOAcLY-of7F_59asJgI7wGoA7HbLpq70ZnTPvMdMFtgEhEV51hH3MXzcgyJz4BSKE_evo7ySTwfW2kf_ro-vYlw/w640-h528/21.png" width="640" /></a></div><div><br /></div>In the right UIViewExtended add a UITextField and set it up as follows.<div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_D9h7nFZy_UsxYyoK7NLMkfVcRF3zsr5uD-jt8yDUHZx7vWrEbLnJlSje6Ce90dmYgO3kaMCJPNFkFRCvLO6pE1fBf_jZ8j50hZMEaU_kBjZMhBnUk77QfmAgTSxmmwRFA6V2KyoUnIIqyLq8g0RqAdfNZlCj-7EBo_4ntS1q_b3r-mp8wQ/s1169/22.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="903" data-original-width="1169" height="494" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_D9h7nFZy_UsxYyoK7NLMkfVcRF3zsr5uD-jt8yDUHZx7vWrEbLnJlSje6Ce90dmYgO3kaMCJPNFkFRCvLO6pE1fBf_jZ8j50hZMEaU_kBjZMhBnUk77QfmAgTSxmmwRFA6V2KyoUnIIqyLq8g0RqAdfNZlCj-7EBo_4ntS1q_b3r-mp8wQ/w640-h494/22.png" width="640" /></a></div><br /><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWyO051GfBLArTESBvGRkdsHCFRqe1z_Rdgt_ScoiRZWoLh37RQIgP6vbPSgXt8y3KzPyRmZZPWNgTy1ZpsWMHN_47LL-Dil5cZPxoBOAwuQiRVI8zEgTgZQ1DfZazBsT6vIMhAf7MgfOuOuiSLvP9gVj56SZSdmdxQIBWNuLOXRYByLFKCA/s1169/23.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="903" data-original-width="1169" height="494" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWyO051GfBLArTESBvGRkdsHCFRqe1z_Rdgt_ScoiRZWoLh37RQIgP6vbPSgXt8y3KzPyRmZZPWNgTy1ZpsWMHN_47LL-Dil5cZPxoBOAwuQiRVI8zEgTgZQ1DfZazBsT6vIMhAf7MgfOuOuiSLvP9gVj56SZSdmdxQIBWNuLOXRYByLFKCA/w640-h494/23.png" width="640" /></a></div><br /><div><br /></div><div><div><br /></div><div><br /></div><h2 style="text-align: left;">VI</h2><div><br /></div><div>Now run the "app". Select any iPhone to run, I have started with a smaller device.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQfE0v1rzZ-8I7jImlAxt-YJ74UPuvIEv65OnAfUx9TiXz13OtdqZItIffpL0-uemcOr2-5iUdKMX3KD7AXHbGChzc-9UJfQP9rvX3VvWpVBb20cWhIXGdgctVGiM7YcMUan4ucfFUSyDJZbr6Ju_CUKX38oyrVDnjxI3_cw0c1sUg0Z5XVg/s985/24.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="985" data-original-width="501" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQfE0v1rzZ-8I7jImlAxt-YJ74UPuvIEv65OnAfUx9TiXz13OtdqZItIffpL0-uemcOr2-5iUdKMX3KD7AXHbGChzc-9UJfQP9rvX3VvWpVBb20cWhIXGdgctVGiM7YcMUan4ucfFUSyDJZbr6Ju_CUKX38oyrVDnjxI3_cw0c1sUg0Z5XVg/w326-h640/24.png" width="326" /></a></div><br /><div><br /></div><div>Now rotate the device and notice the placements.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTJLd9P8Flq38KDVgp1E6UWSICAlK0kHB6fTet_ZyLrZcbVLuDLA-aOS8igWxpcwDtRjgC078bCGO2BJpWrKZnd8EGoKoUn0ASMuTPnmN8Y8nqbp9_FVL4hbbUiG1lveP0x1l9A2f_E6nHz0-h3-hesERy6PfjlLmyTM6tX34MV8clYBKFMg/s941/25.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="538" data-original-width="941" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTJLd9P8Flq38KDVgp1E6UWSICAlK0kHB6fTet_ZyLrZcbVLuDLA-aOS8igWxpcwDtRjgC078bCGO2BJpWrKZnd8EGoKoUn0ASMuTPnmN8Y8nqbp9_FVL4hbbUiG1lveP0x1l9A2f_E6nHz0-h3-hesERy6PfjlLmyTM6tX34MV8clYBKFMg/w640-h366/25.png" width="640" /></a></div><br /><div>Now choose a larger iOS device. I chose iPhone 14 Pro Max.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzOLbhYAYEDAPy2YIwgSLs9jhe20Lh1fF9i-dF9qxIC7UxTGSl06o05zak0U0FdeoWCLSo3QBaMD5C6d0Pm6XKCLD61klGtjLxCwAL727ganEm3WN6wXKLJDY26MZLY_QNNcWw5oisZCmj2FLLnpyL2OiBORr_Tb2qt70t93_MsGZ_1FcQBQ/s1074/26.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1074" data-original-width="544" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzOLbhYAYEDAPy2YIwgSLs9jhe20Lh1fF9i-dF9qxIC7UxTGSl06o05zak0U0FdeoWCLSo3QBaMD5C6d0Pm6XKCLD61klGtjLxCwAL727ganEm3WN6wXKLJDY26MZLY_QNNcWw5oisZCmj2FLLnpyL2OiBORr_Tb2qt70t93_MsGZ_1FcQBQ/w324-h640/26.png" width="324" /></a></div><br /><div><br /></div><div>Now rotate the device.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhag99qrbC3ZaXKo2WZivK-cezVsoAlcyEvuCVxARqVl4-g3UBpfEbP6UPPx_Nhy19R1pe17G5Y2N5vDDCF63zdm0l0llHQztIRUUqPxx8HDvz5Msc2CuGxhlZcvFHoUqb-9lX8MMLLYl5r7Kv62GhLG7C6fKzZ2bULyFJaP9c6Zb_YXSbpwQ/s1006/27.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="577" data-original-width="1006" height="368" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhag99qrbC3ZaXKo2WZivK-cezVsoAlcyEvuCVxARqVl4-g3UBpfEbP6UPPx_Nhy19R1pe17G5Y2N5vDDCF63zdm0l0llHQztIRUUqPxx8HDvz5Msc2CuGxhlZcvFHoUqb-9lX8MMLLYl5r7Kv62GhLG7C6fKzZ2bULyFJaP9c6Zb_YXSbpwQ/w640-h368/27.png" width="640" /></a></div><br /><div><br /></div><div><br /></div><div><br /></div><h1 style="text-align: left;">Conclusion</h1><div>By using the above approach you can use UIStackViews with proportional distribution and control the placement of a label in relation to a text field. Always there are many ways to solve problems, this is just one way.</div><div><br /></div><div>Tweak the values until you get a feel for how it all works together.</div><div><br /></div><div>I wrote this so that I can remember this pattern. My day job is so intense right now that I don't get to work on my iOS apps very often and I forget how I set things up. </div><div><br /></div><div>My day job is Java using Apache Solr and Spring Boot apps running in AWS land.</div><div><br /></div><div><br /></div><p><br /></p><p><br /></p></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-27829513834520496092022-10-21T16:15:00.008-07:002022-10-22T11:25:50.185-07:00Java enum generic serializer and deserializer<h1 style="text-align: left;">Java enum generic Serializer and Deserializer <br /></h1><h2 style="text-align: left;"> Introduction</h2><div style="text-align: left;">Serializing a Java enum is simple using Jackson. It is easy and well known. </div><div style="text-align: left;"> </div><div style="text-align: left;">If the enum has a single value then Jackson provides @JasonValue which serializes the enum as the value. However de-serializing becomes an issue. This leads you to start to use @JsonSerialize and @JsonDeserialize to control serialization. Soon you run into questions on how to get the Class of your enum passed into the deserializer and how to call the default deserializer hoping not to have to re-invent the wheel.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">After using @JsonCreator, and trying to get the default serializer out of the Bean, I decided must be a way to do this and the way shouldn't clutter the enum with too many tags, deserializer subclasses for every enum type, etc.<br /></div><p>https://github.com/sirgilligan/EnumerationSerialization/blob/main/README.md</p><h2 style="text-align: left;">Java implementation for a Generic enum Serializer and Deserializer</h2>
<p dir="auto">Just like the traditional approach the enum's deserializer can be specified as a subclass of a base
deserializer.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto"><pre class="notranslate"><code>@JsonSerialize(using = EnumerationSerializer.class)
@JsonDeserialize(using = <b>RGB.Deserializer.class</b>)
@EnumJson(serializeProjection = Projection.NAME)
enum RGB {
RED,
GREEN,
BLUE;
public static class <b>Deserializer extends EnumerationDeserializer<RGB></b> {
private static final long serialVersionUID = 1L;
<b>public Deserializer() {
super(RGB.class);
}</b>
}
}
</code></pre></div>
<p dir="auto">This approach allows you to pass the enum Class. That is not bad, but it is a bit cluttered.<br /></p><p dir="auto"><b>Instead the class of the enum can be specified via
annotation!</b></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto"><pre class="notranslate"><code>@JsonSerialize(using = EnumerationSerializer.class)
@JsonDeserialize(using = EnumerationDeserializer.class)
<b>@EnumJson(serializeProjection = Projection.NAME, deserializationClass = RGB.class)</b>
enum RGB {
RED,
GREEN,
BLUE
} </code></pre><pre class="notranslate"><code>
</code></pre></div><p dir="auto">This new annotation specifies the Class is RGB.class. It also specifies that the default representation on serializtion should be enum.name(). The default representation could be NAME, ORDINAL, VALUE, or ALIAS.<br /></p><p dir="auto">There are two special annotations to identify a value and an alias.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto"><pre class="notranslate"><code>@JsonSerialize(using = EnumerationSerializer.class)
@JsonDeserialize(using = SomeDays.Deserializer.class)
@EnumJson(serializeProjection = Projection.ORDINAL)
enum SomeDays {
MONDAY("Lunes", "Monday"),
TUESDAY("Martes", "Tuesday"),
WEDNESDAY("Miercoles", "Wednesday");
@EnumJson(serializeProjection = <b>Projection.VALUE</b>)
final String <b>value</b>;
@EnumJson(serializeProjection = <b>Projection.ALIAS</b>)
final String <b>alias</b>;
SomeDays(String v, String a) {
this.value = v;
this.alias = a;
}
public static class Deserializer extends EnumerationDeserializer<SomeDays> {
private static final long serialVersionUID = 1L;
public Deserializer() {
super(SomeDays.class);
}
}
}
</code></pre></div>
<p dir="auto">However EnumerationSerializer and EnumerationDeserialize uses reflection to find any member variable named "value" or "alias". This means you don't even have to use the annotation for VALUE or ALIAS if the naming convention is used. Therefore the above example can be de-cluttered and now look like this:</p><p dir="auto"></p><p dir="auto"></p><p dir="auto"></p><p dir="auto"></p><p dir="auto"></p><p dir="auto"><br /></p><pre class="notranslate"><code>@JsonSerialize(using = EnumerationSerializer.class)
@JsonDeserialize(using = SomeDays.Deserializer.class)
@EnumJson(serializeProjection = Projection.ORDINAL, </code><b><code>deserializationClass = </code><code>SomeDays</code><code>.class)</code></b><code><b>)</b>
enum SomeDays {
MONDAY("Lunes", "Monday"),
TUESDAY("Martes", "Tuesday"),
WEDNESDAY("Miercoles", "Wednesday");
final String <b>value</b>;
final String <b>alias</b>;
SomeDays(String v, String a) {
this.value = v;
this.alias = a;
}
}</code></pre><pre class="notranslate"><code> </code></pre><p dir="auto"></p><p dir="auto">I really like that! I like that alot. <br /></p><p dir="auto">The annotations can be applied to a class that has members of your enum.</p>
<pre class="notranslate"><code>static class SomeStuff {
//Serialize as the Ordinal
@EnumJson(serializeProjection = Projection.ORDINAL)
public SomeDays someDay = SomeDays.MONDAY;
//Serialize as the Identifier
@EnumJson(serializeProjection = Projection.NAME)
public SomeDays nextDay = SomeDays.values()[someDay.ordinal() + 1];
//Serialize as the Value
@EnumJson(serializeProjection = Projection.VALUE)
public SomeDays middleDay = SomeDays.WEDNESDAY;
//Serialize as the Alias
@EnumJson(serializeProjection = Projection.ALIAS)
public SomeDays tuesday = SomeDays.TUESDAY;
//Serialize as the Ordinal
@EnumJson(serializeProjection = Projection.ORDINAL)
public SomeNums aNum = SomeNums.ONE;
//Serialize as the Identifier
@EnumJson(serializeProjection = Projection.NAME)
public SomeNums anotherNum = SomeNums.TWO;
}</code></pre><pre class="notranslate"><code> </code></pre><h3 style="text-align: left;"><code>The Serializer</code></h3><div style="text-align: left;"><code>Use the link to the souce code to see the current implementation. </code></div><div style="text-align: left;"><code>The code is included here so that you can use it as a reference on how to acheive something using serialization, reflection, or annotations.<br /></code></div><h3><code></code></h3><pre class="notranslate"><code>https://github.com/sirgilligan/EnumerationSerialization/blob/main/src/main/java/org/example/EnumerationSerializer.java<br /><span style="font-family: courier;"><br /></span></code></pre><pre class="notranslate">/*
EnumerationSerializer serializes an Enum looking for EnumJson annotations.
If no EnumJson annotation is found the enum is serialized by name.
If the enum is a member variable of some class then the EnumJson annotation
at the member variable level is used and takes priority over any Enum class annotation.
If there are no member variable EnumJson annotation then if there is an Enum class
annotation it will be used.
*/
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.lang.reflect.Field;
import org.example.EnumJson.Projection;
public class EnumerationSerializer<T extends Enum<T>> extends StdSerializer<Enum<T>>
{
private static final long serialVersionUID = 1L;
public EnumerationSerializer()
{
this(null);
}
protected EnumerationSerializer(Class<Enum<T>> t)
{
super(t);
}
@SuppressWarnings("unchecked")
@Override
public void serialize(Enum<T> value, JsonGenerator gen, SerializerProvider provider) throws IOException
{
//Looking for data to write as json
String dataToWrite = null;
//Looking for a specific annotation
//Field annotation has priority over class annotation
EnumJson enumJsonAnnotation = null;
//If this value is a field/member variable contained by another object, get the field name.
String fieldName = gen.getOutputContext().getCurrentName();
if (null != fieldName) {
//Does the field have an annotation?
try {
enumJsonAnnotation = gen.getOutputContext().getCurrentValue().getClass().getField(fieldName).getAnnotation(EnumJson.class);
}
catch (NoSuchFieldException ignored) {
//ignored
}
}
if (null == enumJsonAnnotation) {
//There wasn't a field level annotation
//Is there an annotation on the enum class?
try {
enumJsonAnnotation = value.getClass().getAnnotation(EnumJson.class);
}
catch (Exception ignored) {
//ignored
}
}
ObjectMapper mapper = (ObjectMapper) gen.getCodec();
if (null != enumJsonAnnotation) {
switch (enumJsonAnnotation.serializeProjection()) {
case ORDINAL: {
dataToWrite = mapper.writeValueAsString(value.ordinal());
}
break;
case NAME: {
dataToWrite = mapper.writeValueAsString(value.name());
}
break;
case ALIAS: {
Field[] enumFields = value.getClass().getDeclaredFields();
Field field = findAnnotatedField(enumFields, Projection.ALIAS);
if (null == field) {
field = findFieldByName(Projection.ALIAS.name().toLowerCase(), (Class<T>) value.getClass());
}
dataToWrite = getData(field, value, mapper);
}
break;
case VALUE: {
Field[] enumFields = value.getClass().getDeclaredFields();
Field field = findAnnotatedField(enumFields, Projection.VALUE);
if (null == field) {
field = findFieldByName(Projection.VALUE.name().toLowerCase(), (Class<T>) value.getClass());
}
dataToWrite = getData(field, value, mapper);
}
break;
default:
break;
}
}
else {
//There was not any EnumJson annotation or known field such as value or alias.
// Write enum as name
dataToWrite = mapper.writeValueAsString(value.name());
}
if (null != dataToWrite) {
gen.writeRawValue(dataToWrite);
}
}
protected Field findAnnotatedField(Field[] enumFields, EnumJson.Projection projection)
{
Field result = null;
for (Field f : enumFields) {
EnumJson annie = f.getAnnotation(EnumJson.class);
if ((null != annie) && (annie.serializeProjection() == projection)) {
result = f;
break;
}
}
return result;
}
private Field findFieldByName(String fieldName, Class<T> enumClass)
{
Field result = null;
try {
result = enumClass.getDeclaredField(fieldName);
}
catch (NoSuchFieldException ignored) {
//Ignored
}
return result;
}
@java.lang.SuppressWarnings("java:S3011")
protected String getData(Field field, Enum<T> value, ObjectMapper mapper)
{
String dataToWrite = null;
Object foundValue = null;
if (null != field) {
try {
field.setAccessible(true);
foundValue = field.get(value);
}
catch (IllegalAccessException ignored) {
//ignored
}
}
if (null != foundValue) {
try {
dataToWrite = mapper.writeValueAsString(foundValue);
}
catch (JsonProcessingException ignored) {
//ignored
}
}
return dataToWrite;
}
}
</pre><h3 class="notranslate" style="text-align: left;">The Deserializer</h3><br /><pre>import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.lang.reflect.Field;
import org.example.EnumJson.Projection;
public class EnumerationDeserializer<T extends Enum<T>> extends StdDeserializer<Enum<T>> implements ContextualDeserializer
{
private static final long serialVersionUID = 1L;
private transient Class<T> enumClass;
private transient EnumJson classAnnotation = null;
private transient EnumJson fieldAnnotation = null;
protected EnumerationDeserializer()
{
this(null);
}
protected EnumerationDeserializer(Class<T> vc)
{
super(vc);
this.enumClass = vc;
}
@SuppressWarnings("unchecked")
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException
{
//enumClass is not null if the constructor that takes the class as a param
//is used to create this object.
if (null != enumClass) {
classAnnotation = enumClass.getAnnotation(EnumJson.class);
}
if (null != property) {
fieldAnnotation = property.getAnnotation(EnumJson.class);
if ((null == classAnnotation) && (null == enumClass)) {
classAnnotation = property.getType().getRawClass().getAnnotation(EnumJson.class);
if ((null != classAnnotation) && (classAnnotation.deserializationClass().isEnum())) {
this.enumClass = (Class<T>) classAnnotation.deserializationClass();
}
}
}
return this;
}
/*-------------------------------------------------------------------------------------------
deserialize will check for four different matches on an enum.
1) If the json string matches the enum.name
2) If the enum nas an annotation for an EnumJson Projection = ALIAS
3) If the enum has an annotation for an EnumJson Projection = VALUE
4) If the json string matches the enum.ordinal
-------------------------------------------------------------------------------------------*/
@Override
public Enum<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
Enum<T> result = null;
final String jsonValue = p.getText();
boolean caseInsensitive = false;
if (fieldAnnotation != null) {
caseInsensitive = fieldAnnotation.deserializeCaseInsensitive();
}
else if (classAnnotation != null) {
caseInsensitive = classAnnotation.deserializeCaseInsensitive();
}
//-------------------------------------------------------------------------------------------
//Check if json matches the Name
for (final T enumValue : enumClass.getEnumConstants()) {
if (enumValue.name().equals(jsonValue) || ((caseInsensitive) && enumValue.name().equalsIgnoreCase(jsonValue))) {
result = enumValue;
}
}
//-------------------------------------------------------------------------------------------
//Check if the enum has an EnumJson Projection Annotation of ALIAS
if (null == result) {
Field[] enumFields = enumClass.getDeclaredFields();
result = enumByAnnotatedField(enumFields, Projection.ALIAS, jsonValue, caseInsensitive);
}
//-------------------------------------------------------------------------------------------
//Check if the enum has an EnumJson Projection Annotation of VALUE
if (null == result) {
Field[] enumFields = enumClass.getDeclaredFields();
result = enumByAnnotatedField(enumFields, Projection.VALUE, jsonValue, caseInsensitive);
}
//-------------------------------------------------------------------------------------------
//Check if json matches the Ordinal
if (null == result) {
for (final T enumValue : enumClass.getEnumConstants()) {
if (Integer.toString(enumValue.ordinal()).equals(jsonValue)) {
result = enumValue;
}
}
}
return result;
}
@java.lang.SuppressWarnings("java:S3011")
protected Enum<T> enumByAnnotatedField(Field[] enumFields, EnumJson.Projection projection, String jsonValue, boolean caseInsensitive)
{
Enum<T> result = null;
Field valueField = null;
for (Field f : enumFields) {
EnumJson annie = f.getAnnotation(EnumJson.class);
if ((null != annie) && (annie.serializeProjection() == projection)) {
valueField = f;
break;
}
}
if (null != valueField) {
//The enum has a EnumJson Projection that matches
valueField.setAccessible(true);
try {
for (final T enumValue : enumClass.getEnumConstants()) {
//Get the projected value from the enum.
Object projectedValue = valueField.get(enumValue);
if ((null != projectedValue) &&
((projectedValue.toString().equals(jsonValue)) ||
((caseInsensitive) && projectedValue.toString().equalsIgnoreCase(jsonValue)))) {
result = enumValue;
}
}
}
catch (IllegalAccessException ignored) {
//ignored
}
}
else {
//Look for a field by named value or alias.
if (projection == Projection.VALUE) {
result = getFromKnownField(Projection.VALUE.name().toLowerCase(), jsonValue, caseInsensitive);
}
else if (projection == Projection.ALIAS) {
result = getFromKnownField(Projection.ALIAS.name().toLowerCase(), jsonValue, caseInsensitive);
}
}
return result;
}
protected Enum<T> getFromKnownField(String fieldName, String jsonValue, boolean caseInsensitive)
{
Enum<T> result = null;
try {
Field knownField = enumClass.getDeclaredField(fieldName);
for (final T enumValue : enumClass.getEnumConstants()) {
Object value = knownField.get(enumValue);
if ((null != value) &&
((value.toString().equals(jsonValue)) || ((caseInsensitive) && value.toString().equalsIgnoreCase(jsonValue)))) {
result = enumValue;
break;
}
}
}
catch (NoSuchFieldException | IllegalAccessException ignored) {
//ignored
}
return result;
}
}
</pre><pre class="notranslate"><span style="font-family: courier;"> </span></pre><h3 class="notranslate" style="text-align: left;"><span style="font-family: courier;">The Annotations </span></h3><pre>import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@EnumAnnotation
public @interface EnumJson
{
enum Projection
{
ALIAS, //Enum has a property for an alias or alternate name. E.g. Monday
NAME, //Enum.name. E.g. MONDAY
ORDINAL, //Enum.ordinal. E.g. 0, 1, 3, 4, etc.
VALUE //Enum has property for some type of value. E.g. LUNES
}
Projection serializeProjection() default Projection.VALUE;
boolean deserializeCaseInsensitive() default false;
Class<?> deserializationClass() default Void.class;
}</pre><p class="notranslate" style="text-align: left;"><span style="font-family: courier;"> </span></p><p class="notranslate" style="text-align: left;"><span style="font-family: courier;"> </span></p>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-14727522836924518922022-08-11T10:47:00.006-07:002022-08-11T11:02:09.648-07:00Spring IOC - @Conditional<h2 style="text-align: left;"> Prerequisite</h2><p style="text-align: left;"><br />To create a new Spring Boot Application project in Intellij go to File -> New -> Project…<br /><br /><b id="docs-internal-guid-9f26a0f0-7fff-5e82-1f94-2530eb425a29" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><span style="border: none; display: inline-block; height: 517px; overflow: hidden; width: 624px;"><img height="517" src="https://lh6.googleusercontent.com/eK90J2QSygI53aPKY7gtQH6yu1jgWPNRc77EaBkQcdseYH4u1yVnLqC2iL-zlGYcwW4hTjr7LilBTZIDMcfAmxi3pgbQ5fca2zX-TGbHGHI-yHuJQHg67CQYNXAC-11BuzYnNcRMJstofbNi4E7uD_w" style="margin-left: 0px; margin-top: 0px;" width="624" /></span></span></b><br /><br />Select “Spring Initializer” and give your project a name. <br /><br />I prefer “Gradle”, so I selected Gradle instead of Maven. Select your JDK, etc.<br /><br />Go to the next page and under “Web” select Spring Web.<br /></p><p style="text-align: left;"><b id="docs-internal-guid-54d87bf5-7fff-8c97-3337-efb16b571131" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><span style="border: none; display: inline-block; height: 517px; overflow: hidden; width: 624px;"><img height="517" src="https://lh3.googleusercontent.com/we5l5Id_LKNsNd5q3qIZI9TcdpncICNpXSG6v4MiDWaIup4VMq7ppaR29SO7oFNisN5e_-LgqeSCaJsJhyfP64-gGVQB-l2iO9ld-yYw53rvlLe1Y7a6sGPc_38cvq1JuuMAUJlyU-b7mQmPSfuOWfw" style="margin-left: 0px; margin-top: 0px;" width="624" /></span></span></b></p><p style="text-align: left;"><br />For the example that follows I named it “Springy” and set the group to “com.slinky.springy”.<br /><br /></p><h2 style="text-align: left;">Introduction</h2><p style="text-align: left;"><br />This “example” will show how to use @Conditional in an @Configuration.<br /><br />You should be familiar with the basic terminology of Spring Boot dependency injection. I recommend reading “Baeldung : Spring Dependency Injection”.<br /><br />This example will use dependency injection to choose a specific implementation based on some logical condition. The condition I have chosen is simple: the value of an environment variable.<br /><br />I use Intelli, so edit the configuration by adding “Environment variables:”. If you don’t see “Environment variables:” choose the “Modify options ⌄” to add the field to the dialog.<br /><br /><br /><b id="docs-internal-guid-e8f75a0f-7fff-e7fa-832a-2be55f1e831b" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><span style="border: none; display: inline-block; height: 536px; overflow: hidden; width: 624px;"><img height="536" src="https://lh4.googleusercontent.com/nn1FUpbT6JBvJsihUDzlhSrHP_ymeSvPTSHPmuLGBBBndUq35bTHI3Qoa-YKVnwgqONLOzNYzGacBf44gCCfYbF-n2AwCvXzsALgZ49-5UQlJmFcy5125FRJp_tcLePHF26tBRKZgOHTKuLEivondfs" style="margin-left: 0px; margin-top: 0px;" width="624" /></span></span></b><br /><br /></p><h2 style="text-align: left;">Create the Following Java Classes</h2><p style="text-align: left;"></p><p style="text-align: left;"><br /></p><h3 style="text-align: left;">StringStuff.java</h3><p style="text-align: left;">package com.slinky.springy;<br /><br />public interface StringStuff<br />{<br /> String getString();<br />}<br /><br /><br /></p><h3 style="text-align: left;">DevStringStuff.java</h3><p style="text-align: left;">package com.slinky.springy;<br /><br />import org.springframework.context.annotation.Conditional;<br /><br />@Conditional(DevCondition.class)<br />public class DevStringStuff implements StringStuff<br />{<br /> @Override<br /> public String getString()<br /> {<br /> return "dev";<br /> }<br />}<br /><br /></p><h3 style="text-align: left;">StageStringStuff.java</h3><p style="text-align: left;"><br />package com.slinky.springy;<br /><br />import org.springframework.context.annotation.Conditional;<br /><br />@Conditional(StageCondition.class)<br />public class StageStringStuff implements StringStuff<br />{<br /> @Override<br /> public String getString()<br /> {<br /> return "stage";<br /> }<br />}<br /><br /><br /></p><h3 style="text-align: left;">DevCondtion.java</h3><p style="text-align: left;"><br />package com.slinky.springy;<br /><br />import org.springframework.context.annotation.Condition;<br />import org.springframework.context.annotation.ConditionContext;<br />import org.springframework.core.type.AnnotatedTypeMetadata;<br /><br />public class DevCondition implements Condition<br />{<br /> @Override<br /> public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)<br /> {<br /> String environment = context.getEnvironment().getProperty("env");<br /> return environment != null && environment.contains("dev");<br /> }<br />}<br /><br /><br /></p><h3 style="text-align: left;">StageCondition.java</h3><p style="text-align: left;"><br />package com.slinky.springy;<br /><br />import org.springframework.context.annotation.Condition;<br />import org.springframework.context.annotation.ConditionContext;<br />import org.springframework.core.type.AnnotatedTypeMetadata;<br /><br />public class StageCondition implements Condition<br />{<br /> @Override<br /> public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)<br /> {<br /> String environment = context.getEnvironment().getProperty("env");<br /> return environment != null && environment.contains("stage");<br /> }<br />}</p><p><br /></p><h3 style="text-align: left;">Configurator.java</h3><p><br />package com.slinky.springy;<br /><br />import org.springframework.context.annotation.Bean;<br />import org.springframework.context.annotation.ComponentScan;<br />import org.springframework.context.annotation.Conditional;<br />import org.springframework.context.annotation.Configuration;<br /><br />@Configuration<br />@ComponentScan("com.slinky.springy")<br />public class Configurator<br />{<br /> @Bean<br /> @Conditional(DevCondition.class)<br /> public StringStuff getDevStringStuff() {<br /> return new DevStringStuff();<br /> }<br /><br /> @Bean<br /> @Conditional(StageCondition.class)<br /> public StringStuff getStageStringStuff() {<br /> return new StageStringStuff();<br /> }<br /><br />}<br /><br /><br /></p><h3 style="text-align: left;">SpringyApplication.java</h3><p style="text-align: left;"><br />package com.slinky.springy;<br /><br />import org.springframework.beans.factory.annotation.Autowired;<br />import org.springframework.boot.SpringApplication;<br />import org.springframework.boot.autoconfigure.SpringBootApplication;<br />import org.springframework.web.bind.annotation.GetMapping;<br />import org.springframework.web.bind.annotation.RestController;<br /><br />@SpringBootApplication(scanBasePackages = {"com.slinky.springy"})<br />@RestController<br />public class SpringyApplication<br />{<br /><br /> @Autowired(required = false)<br /> private StringStuff stuffService;<br /><br /> public static void main(String[] args)<br /> {<br /> SpringApplication.run(SpringyApplication.class, args);<br /> }<br /><br /> @GetMapping("/env")<br /> public String env() {<br /> if (null != stuffService) {<br /> return stuffService.getString();<br /> }<br /> return "env error";<br /> }<br /><br />}<br /><br /><br /></p><h2 style="text-align: left;">Conclusion</h2><p style="text-align: left;"></p><p><br />The preceding example is so that you can create a working solution that uses @Condition. I am not going to explain why it works or comment on Spring IOC. This is to help you see a working version instead of trying to decipher the documentation and tutorials you may find on the Web.<br /><br />Run the Java project and open a browser window to this location:<br /><br />http://localhost:8080/env<br /><br />The use of an environment variable is just a simple way to create a condition. This may not be the best way to inject behavior based on a runtime environment variable.<br /><br /><br /></p>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-48285593976056688582022-06-11T20:50:00.000-07:002022-06-11T20:50:25.613-07:00Scroll View - Interface Builder<p> Here are the steps to make a Scroll View that has an embedded UIView that specifies the height of the contents of the scrollable area.</p><p>Create a new app with a View Controller.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhswmcY_zDelvi7M10mm8sSEz_cQuMHzBCG2woBvlr_ftc4BIPtcwB8F7a6bKH8treTk3TpbWEiOApzJ4wcgorCOhP6wH_wzgRAsxFeWFlL_4OPRAEZ-oA-My0AhB2X0p7dmRNBDy_tE5J2kZWQa5M_oHuh8hGcRnTWzAqswJ12jObh_wrhAQ/s1796/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1037" data-original-width="1796" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhswmcY_zDelvi7M10mm8sSEz_cQuMHzBCG2woBvlr_ftc4BIPtcwB8F7a6bKH8treTk3TpbWEiOApzJ4wcgorCOhP6wH_wzgRAsxFeWFlL_4OPRAEZ-oA-My0AhB2X0p7dmRNBDy_tE5J2kZWQa5M_oHuh8hGcRnTWzAqswJ12jObh_wrhAQ/w640-h370/1.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;">Place a Scroll View inside the View Controller.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3GzQ6A6GWGmuLQ3uR7f6ndl9wpIJXDVexLWPcWfSpIPYEBpKGY6fF5oaHmpT-vXesnWEOd2pIdKOxDWaDsW-7cX-qrfOAKApGs_SVsL_S_7IfVdXrkhDAgGJ0-x-orfbo4OWS4AWREC2K-ud7kG6iPJNqHuI2qfyKMUPqzOghsS5dhW-ugA/s1190/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="782" data-original-width="1190" height="420" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3GzQ6A6GWGmuLQ3uR7f6ndl9wpIJXDVexLWPcWfSpIPYEBpKGY6fF5oaHmpT-vXesnWEOd2pIdKOxDWaDsW-7cX-qrfOAKApGs_SVsL_S_7IfVdXrkhDAgGJ0-x-orfbo4OWS4AWREC2K-ud7kG6iPJNqHuI2qfyKMUPqzOghsS5dhW-ugA/w640-h420/2.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Td4OZuTpZNNRFL-IbdDMFHfHGoRQU_js4QcM8-Etx5ULB1uxlDxSS0Es8h6Bpdoevb6ckw0ow0Ius5Kh1CwNiajHknaeWN-xeMwEMisD3zFyWrJiQb9-CmOutvtk2cHqw1QFz11POeqnltkT9nP8NdHvDQwyky05C5RglhDhkQyV2Bc6Ag/s1008/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1008" data-original-width="936" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Td4OZuTpZNNRFL-IbdDMFHfHGoRQU_js4QcM8-Etx5ULB1uxlDxSS0Es8h6Bpdoevb6ckw0ow0Ius5Kh1CwNiajHknaeWN-xeMwEMisD3zFyWrJiQb9-CmOutvtk2cHqw1QFz11POeqnltkT9nP8NdHvDQwyky05C5RglhDhkQyV2Bc6Ag/w594-h640/3.png" width="594" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Constrain the position of the Scroll View. This example will position the Scroll View to use most of the available area. Just use the sizing handles and make the Scroll View fill the parent view. You can choose any size you want. Constrain the scroll view to the Safe Area.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3dVcckF1l_0PFYbaGg9OovYfYBXzqVTZ8KMGraselJAeTdRQj8xC4WgTA1MNHr2kVbrCHRNeZEH82eVZJeE95S8r9Qf6eBw5FzUbOSwUWzTj0mPTIxJZ9Q5bIsF2k9A6ioHYB21_DlaJCcXN6I1gDL51vrleIh2jH9aUBpRA9344Mj0nkvQ/s1008/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1008" data-original-width="936" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3dVcckF1l_0PFYbaGg9OovYfYBXzqVTZ8KMGraselJAeTdRQj8xC4WgTA1MNHr2kVbrCHRNeZEH82eVZJeE95S8r9Qf6eBw5FzUbOSwUWzTj0mPTIxJZ9Q5bIsF2k9A6ioHYB21_DlaJCcXN6I1gDL51vrleIh2jH9aUBpRA9344Mj0nkvQ/w594-h640/4.png" width="594" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><p>Next place a UIView inside the Scroll View. This example will use a "Container View".</p><div><br /></div></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXxT8gR4AkwwVSbGsftzzWIbYauqv0ebSTf-HYkfq25mzcKEh7dOyVWIivR6DQg67vyc98uqSUTU6Aq7jyrPfNV8S5NdjKorcFAOF81s3KrWs5J33JFGCAtC5J3P3eJMWJ0DuvvhJzWgtrBWhoIdW5HpMLeWSkPsRMEl-gROk9ly0GKx79cA/s1140/5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="808" data-original-width="1140" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXxT8gR4AkwwVSbGsftzzWIbYauqv0ebSTf-HYkfq25mzcKEh7dOyVWIivR6DQg67vyc98uqSUTU6Aq7jyrPfNV8S5NdjKorcFAOF81s3KrWs5J33JFGCAtC5J3P3eJMWJ0DuvvhJzWgtrBWhoIdW5HpMLeWSkPsRMEl-gROk9ly0GKx79cA/w640-h454/5.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5GCxOhmMXdYtPkDqovRiOgimh8OtH8KdKcC4htT-wxQjNdCA_Y7XOP6PhvTqPR56FdpxmAErH5Vq-KNjpGEb_w2cV6ihAKNlqTCU6C6P9lWr2bh0IwIlsXo07hwmf3MWx4kp-e082BsTVN9hsIadj204hJDlV8tXD8E-IQ1l56P7NyoykEA/s1140/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="808" data-original-width="1140" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5GCxOhmMXdYtPkDqovRiOgimh8OtH8KdKcC4htT-wxQjNdCA_Y7XOP6PhvTqPR56FdpxmAErH5Vq-KNjpGEb_w2cV6ihAKNlqTCU6C6P9lWr2bh0IwIlsXo07hwmf3MWx4kp-e082BsTVN9hsIadj204hJDlV8tXD8E-IQ1l56P7NyoykEA/w640-h454/6.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div><br /></div><p>Use the sizing handles to make the Container View the same size as the Scroll View.</p><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmIBapCfpV1hIWxfIhAZzFCu_RrWeK7JelbS8rbCz4xHuOJIZ6WtDahUKXLi9L87S-haZA2lBETj-nGSJQqGyold-tvmmsg77dxyBgHBuQiFOf5ExYJigdCgaFwTW86rjT3HRzdnRIB2NZHXFQBsuJdP4vv9sPpHR4YVRDjrP0h56PsNM7oQ/s1149/7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="862" data-original-width="1149" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmIBapCfpV1hIWxfIhAZzFCu_RrWeK7JelbS8rbCz4xHuOJIZ6WtDahUKXLi9L87S-haZA2lBETj-nGSJQqGyold-tvmmsg77dxyBgHBuQiFOf5ExYJigdCgaFwTW86rjT3HRzdnRIB2NZHXFQBsuJdP4vv9sPpHR4YVRDjrP0h56PsNM7oQ/w640-h480/7.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHE70TxuhebNC8TKTyq3VD1HQ1IzCQOWEWG5zwagGKU2j2hrQsqr_lYcVoIugYGYcatPloP3v__cLncgJtzfxIgNE4Ju8WQeYvl8d-6It2VyIk4TskR29bVxXGtqHpP_4Pe_Qdj-kwTY4RPXa5P5sVRRPs5q8vQi89TCOVhMv8i3zMM8XkjA/s1149/8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="862" data-original-width="1149" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHE70TxuhebNC8TKTyq3VD1HQ1IzCQOWEWG5zwagGKU2j2hrQsqr_lYcVoIugYGYcatPloP3v__cLncgJtzfxIgNE4Ju8WQeYvl8d-6It2VyIk4TskR29bVxXGtqHpP_4Pe_Qdj-kwTY4RPXa5P5sVRRPs5q8vQi89TCOVhMv8i3zMM8XkjA/w640-h480/8.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div><br /></div>Constrain the Container View to the Scroll View's "Content Layout Guide". Constrain leading, top, trailing, and bottom and set all of their values to"0".<div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1HlVZZjGTUNLMYG1EyHkZN8kPjl02jQYVCPKjzQBTHMmOrGsFqEcMINnszqrbd93ghGLJUQMVbaWk2H0jx_oa3GBnoOUf8Bx_OxBIJlRQ5K52xpT8sdEMlol0wyYfMdYDxMCgozvWhw8xEjvRnLK8IXEJXsMlMqa9Gf-Nfxtf4Rz9Nx0dcA/s1149/9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="862" data-original-width="1149" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1HlVZZjGTUNLMYG1EyHkZN8kPjl02jQYVCPKjzQBTHMmOrGsFqEcMINnszqrbd93ghGLJUQMVbaWk2H0jx_oa3GBnoOUf8Bx_OxBIJlRQ5K52xpT8sdEMlol0wyYfMdYDxMCgozvWhw8xEjvRnLK8IXEJXsMlMqa9Gf-Nfxtf4Rz9Nx0dcA/w640-h480/9.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzW0pHGYWJ0wbvwZ9y0vC26E7aIUb0maktzrUwA4vkKksonn7MRZVa2ZF6I4wsURbgivLIZPZhd8ev9URM2uWLSqlhqhLydzYpgHngwt_gGNalihBJpFV_pSP5pewFkot787uANiH7JyvP81P07VW3USX0QkO2Toca4pUOnqVeTsAhElSuxg/s566/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="566" data-original-width="462" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzW0pHGYWJ0wbvwZ9y0vC26E7aIUb0maktzrUwA4vkKksonn7MRZVa2ZF6I4wsURbgivLIZPZhd8ev9URM2uWLSqlhqhLydzYpgHngwt_gGNalihBJpFV_pSP5pewFkot787uANiH7JyvP81P07VW3USX0QkO2Toca4pUOnqVeTsAhElSuxg/w326-h400/17.png" width="326" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO3S4Ukg5xYegB4YzILK-9PHxXjgtEDSCGJ0lH6A8fEBQAz6m4JFYFQQ0rPe8ScjTgvMVmictFnGNy7D4PR3igN4NmUjSQgizhflTzS98af8NRbFSGuBciuj2Np4-njHTCvY5_QJYMlY9XnmZEKDnVoXdaIOCB2GMCKWCI8EzMq8JIWhvKCA/s632/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="204" data-original-width="632" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO3S4Ukg5xYegB4YzILK-9PHxXjgtEDSCGJ0lH6A8fEBQAz6m4JFYFQQ0rPe8ScjTgvMVmictFnGNy7D4PR3igN4NmUjSQgizhflTzS98af8NRbFSGuBciuj2Np4-njHTCvY5_QJYMlY9XnmZEKDnVoXdaIOCB2GMCKWCI8EzMq8JIWhvKCA/w640-h206/10.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div><br /></div>Now constrain the Container View to the Scroll View's "Frame Layout Guide". Constrain to "Equal Widths" and set the multiplier value of the constraint to "1".</div><div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLx_j4tAwnp_eyIetf6AhI-w2qnTmoYZwHTco0dm-a85_YfsqBfEAx4934MlbnvRJLimstTeOOu0bKDJ6LrD4NXZa1INKwxz-wnkgyHE71R8GxwAhNagmLO48ebCCdmtlh4V10sK5AoC3Guy5H0lemC8gKzaY3TTcz9VOy3kDF8ymi6wiR8Q/s1149/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="862" data-original-width="1149" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLx_j4tAwnp_eyIetf6AhI-w2qnTmoYZwHTco0dm-a85_YfsqBfEAx4934MlbnvRJLimstTeOOu0bKDJ6LrD4NXZa1INKwxz-wnkgyHE71R8GxwAhNagmLO48ebCCdmtlh4V10sK5AoC3Guy5H0lemC8gKzaY3TTcz9VOy3kDF8ymi6wiR8Q/w640-h480/11.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmrFMjXm-YQftuQQ3PJyfY3gFvUVgN85XQ_icGg05xMXpr9kfFgZjmvdAJ4hOCMrAqHY6uiHzG3mrloMBijEWGgm-zHVUygn9Hahu2v7P7Z8vhAPE5iqQRYfztKNoNOS50pVDdqifIYLcExKxv7ZawruKhmSDr5KyeknqqohBd6tdbRILxwQ/s936/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="338" data-original-width="936" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmrFMjXm-YQftuQQ3PJyfY3gFvUVgN85XQ_icGg05xMXpr9kfFgZjmvdAJ4hOCMrAqHY6uiHzG3mrloMBijEWGgm-zHVUygn9Hahu2v7P7Z8vhAPE5iqQRYfztKNoNOS50pVDdqifIYLcExKxv7ZawruKhmSDr5KyeknqqohBd6tdbRILxwQ/w640-h232/12.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">This example will show vertical scrolling. Therefore set the height of the Container View to something larger than the Scroll View.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg99-4F9o89i0nX2ZLDXF-X0usg1IWzeE41mQ77IDw1BpFKDIgCiuKoZubFnZCN0cvEb6Oob63yfuapyMUxYg-p1mciSmVKrPRrJaOLEK8v7yfG9S4K4aZsTLBwEDW3jwVhqSNfaA1QTYp25W5yyJyMJ16KFiufaZiSwSQUtDkCC-g-sJ5ZCA/s1068/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1068" data-original-width="936" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg99-4F9o89i0nX2ZLDXF-X0usg1IWzeE41mQ77IDw1BpFKDIgCiuKoZubFnZCN0cvEb6Oob63yfuapyMUxYg-p1mciSmVKrPRrJaOLEK8v7yfG9S4K4aZsTLBwEDW3jwVhqSNfaA1QTYp25W5yyJyMJ16KFiufaZiSwSQUtDkCC-g-sJ5ZCA/w560-h640/13.png" width="560" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">This example sets the height to "1200".</div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSygxtCZhQVESDGB9mvhDZrRpHy3C8Gi-fzKaM7qcLoSQdySBuPymsLM-02ESOkbqWvDW9FMW0bINfyntW06IT0lxdz-F9ugxsXUXl8y_cx-0VNtT_g4A2gG_b521XsBtyXIl92cGUvm8tIGbIukZS0XRjC8s8dtmV3pVVs0GNh-aHEQRmqg/s1212/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1048" data-original-width="1212" height="554" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSygxtCZhQVESDGB9mvhDZrRpHy3C8Gi-fzKaM7qcLoSQdySBuPymsLM-02ESOkbqWvDW9FMW0bINfyntW06IT0lxdz-F9ugxsXUXl8y_cx-0VNtT_g4A2gG_b521XsBtyXIl92cGUvm8tIGbIukZS0XRjC8s8dtmV3pVVs0GNh-aHEQRmqg/w640-h554/14.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Before testing this, place a label somewhere near the bottom of the Container View.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1tDIRMzYCtlppCqxneB6xT06g3BuDNWlflRbGlnv90Ovpx0o1rvBLePncdroGcftCZ5VAxlxxRhy5kxgAe6iewghHmNgV1qRg3j-uAbSrb6KRwTLk1BIx80U5PXIwLEwdWQI8nhfGPHRB-Lo27dXEOHOxmCjmzqu476S-TkGQJqEKPI3dvw/s1212/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1048" data-original-width="1212" height="554" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1tDIRMzYCtlppCqxneB6xT06g3BuDNWlflRbGlnv90Ovpx0o1rvBLePncdroGcftCZ5VAxlxxRhy5kxgAe6iewghHmNgV1qRg3j-uAbSrb6KRwTLk1BIx80U5PXIwLEwdWQI8nhfGPHRB-Lo27dXEOHOxmCjmzqu476S-TkGQJqEKPI3dvw/w640-h554/15.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><p>Now run it in the iPhone Simulator. This example uses an iPhone 8.</p><p>Drag in the simulator to see the label.</p></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBlVmQPoP1KPcox0-lPc7igNXdUjmFUhsbZEiAUOLnWCLuTq3RSb9r_QVB_73oL_jsbXrMCU0pn-pJ-5_rct47lWlFo7hcvu71ZNGK4RCr-B3-oIzjhIg4rA-HrfiZ9smS_BqM1ZeW1jIaIyvQTywWWGPkcAadu3UshAut2dcvjzC04qehFQ/s1296/16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1296" data-original-width="646" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBlVmQPoP1KPcox0-lPc7igNXdUjmFUhsbZEiAUOLnWCLuTq3RSb9r_QVB_73oL_jsbXrMCU0pn-pJ-5_rct47lWlFo7hcvu71ZNGK4RCr-B3-oIzjhIg4rA-HrfiZ9smS_BqM1ZeW1jIaIyvQTywWWGPkcAadu3UshAut2dcvjzC04qehFQ/w320-h640/16.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><p><br /></p><p>And that's it!</p></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-84223194573452147302022-05-30T10:51:00.002-07:002022-05-30T10:51:36.179-07:00StackView - Constraining Contained Views<p> These are the steps to layout a StackView's contained views by constraining the height of the contained views.</p><p><br /></p><p>Step 1: Add Vertical Stack View</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1k0lcTr05l4IFvQVwbUoUG2BYmS0vyVYWTbP5fkU7DUo4hMyc1lNR24avo86o_KnaKnPqeUX9tFjoCoEQ7hUVwryRB03MQStaRrQvwUSSjvIuCzr_cecFy9U5fc2xT4yH2N-IBlToAT-tezjDNwM8v3TloiLJOId2j6RYPyQ2bJ9qY0-jZg/s1263/step1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1k0lcTr05l4IFvQVwbUoUG2BYmS0vyVYWTbP5fkU7DUo4hMyc1lNR24avo86o_KnaKnPqeUX9tFjoCoEQ7hUVwryRB03MQStaRrQvwUSSjvIuCzr_cecFy9U5fc2xT4yH2N-IBlToAT-tezjDNwM8v3TloiLJOId2j6RYPyQ2bJ9qY0-jZg/w640-h476/step1.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 2: Constrain the Stack View</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgalCxoQIy-2OEtY56jEICP4J0ydn6wjciJBfY3Y-NbSLZO3f4SyAHyrL7Epxo4ODAxH7qwvQl-x9uT_sW1IlZtiUWORFUhsV9eYdw-cGaLI5ChxBPUIXMdkNR0Lt5UKnB83cFJfej2syc09VSmhjes7lFNHZnnB2lB4fX_EWRjfZ07U3qY4A/s365/step2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="365" data-original-width="302" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgalCxoQIy-2OEtY56jEICP4J0ydn6wjciJBfY3Y-NbSLZO3f4SyAHyrL7Epxo4ODAxH7qwvQl-x9uT_sW1IlZtiUWORFUhsV9eYdw-cGaLI5ChxBPUIXMdkNR0Lt5UKnB83cFJfej2syc09VSmhjes7lFNHZnnB2lB4fX_EWRjfZ07U3qY4A/w331-h400/step2.png" width="331" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 3: Add UIView to the Stack View</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAiLjUSeKau3MtCENrP6nwu1y97Lq5HTYyhNkcb_RWEHzoSAty16ZGBvAXjfYx94m0PjJK_XKf6wYg1ouojU9IqpZkcGJf1wCnP4NfYmlVDmB64h8AtbINrSNqAeuek6jZM4wdoGc6tW4ufDSR-CxxPrCZ9S43nPq9xc4EuND_Q0G2ubZEBQ/s1263/step3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAiLjUSeKau3MtCENrP6nwu1y97Lq5HTYyhNkcb_RWEHzoSAty16ZGBvAXjfYx94m0PjJK_XKf6wYg1ouojU9IqpZkcGJf1wCnP4NfYmlVDmB64h8AtbINrSNqAeuek6jZM4wdoGc6tW4ufDSR-CxxPrCZ9S43nPq9xc4EuND_Q0G2ubZEBQ/w640-h476/step3.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 4: Duplicate the UIView so that there are three UIViews</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkwugW9CkzNzlGIKDplEL_T6OohgFLFivL81EXdHYVZJIjg00xAMBLbbpR79liyC06N_hzKklqYTO3JJlJcCd7lM1ggV-L5QvCAtJgT2owfbWJT9T3Y8ZSm1VnyvhbtybUqlD_QD_m8d3ZcucUj3lW6yWTHumjOdCoJzDPUCbQAbZdhSw5Hg/s1263/step4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkwugW9CkzNzlGIKDplEL_T6OohgFLFivL81EXdHYVZJIjg00xAMBLbbpR79liyC06N_hzKklqYTO3JJlJcCd7lM1ggV-L5QvCAtJgT2owfbWJT9T3Y8ZSm1VnyvhbtybUqlD_QD_m8d3ZcucUj3lW6yWTHumjOdCoJzDPUCbQAbZdhSw5Hg/w640-h476/step4.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 5: Set the background color of each UIView to a unique color.</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2533iMVjdB5yaYIwV17UE9Nk-a7lIez5tPTMlN8bpLwba_VeLNBn89Nqf3q46QeF5kjVt4dijZjWVbklynXdW-6VodkWJWsnRNB_QDQVEFZ2RVMntY2F98ImVNqmUdWukBxexzOzJIDvKzETT-yCCD_wuZnxm4zbvp74WP14JuO8z8fgYuw/s1263/step5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2533iMVjdB5yaYIwV17UE9Nk-a7lIez5tPTMlN8bpLwba_VeLNBn89Nqf3q46QeF5kjVt4dijZjWVbklynXdW-6VodkWJWsnRNB_QDQVEFZ2RVMntY2F98ImVNqmUdWukBxexzOzJIDvKzETT-yCCD_wuZnxm4zbvp74WP14JuO8z8fgYuw/w640-h476/step5.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 6: Constrain the top UIView to the bottom UIView in the stack. Set to "Equal Heights"</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtPAprcRPXcDhQWY_mEXyVtY1WBxBNmeiw-3IRXMc94mD3gtyITPw3d1hB1Z-omsm53AxFjVPykyz8_H0N4AM2ud30yXX73AIuLhOOVfM6AmPCVc9_mmqA4z1dseCq4MYnWm9W9jWosJJE37f2W6EQzOBzvfQhikkHQbuUz1Ah-3YpbiYBrQ/s1270/step6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="950" data-original-width="1270" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtPAprcRPXcDhQWY_mEXyVtY1WBxBNmeiw-3IRXMc94mD3gtyITPw3d1hB1Z-omsm53AxFjVPykyz8_H0N4AM2ud30yXX73AIuLhOOVfM6AmPCVc9_mmqA4z1dseCq4MYnWm9W9jWosJJE37f2W6EQzOBzvfQhikkHQbuUz1Ah-3YpbiYBrQ/w640-h478/step6.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 7: Constrain the middle UIView to the bottom UIView in the stack. Set to "Equal Heights"</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL7WwgcxnUoT9Lr0m7Yp49JP2hvPJ0oE6OuGoG_f4nyLvZZ2oPZVikccys1ZijX5lkBbCpvW1a0EZyBM0dY0vF3o4aFwO5m8EdUn61mmkl1z8yrEnC4ufauYKip2OW2ZN4B6TqFw40b0OxUtNcJX5lEyDLrLguFnG-p72UMxHieMxW7jYi5Q/s1263/step7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL7WwgcxnUoT9Lr0m7Yp49JP2hvPJ0oE6OuGoG_f4nyLvZZ2oPZVikccys1ZijX5lkBbCpvW1a0EZyBM0dY0vF3o4aFwO5m8EdUn61mmkl1z8yrEnC4ufauYKip2OW2ZN4B6TqFw40b0OxUtNcJX5lEyDLrLguFnG-p72UMxHieMxW7jYi5Q/w640-h476/step7.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Step 8: Change the middle UIView's constraint multiplier to 1.0</div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWQCLGGcsIP-dYke7XuGijHIHWZ0l9r95b7lggYSMoRd4OC0XZvOCbpsG1XRBiZXGhtj96BcFa24RkJFt87-lQ7a0d3a_fBfc_a6S6uoErL7X_bePP1NJAxrnwd1iVHsJrD9QHJBJ26oxP3AizU7PrT-Es6FQmOHGP2IZ9bfu0X4MEiFEO9g/s1263/step8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWQCLGGcsIP-dYke7XuGijHIHWZ0l9r95b7lggYSMoRd4OC0XZvOCbpsG1XRBiZXGhtj96BcFa24RkJFt87-lQ7a0d3a_fBfc_a6S6uoErL7X_bePP1NJAxrnwd1iVHsJrD9QHJBJ26oxP3AizU7PrT-Es6FQmOHGP2IZ9bfu0X4MEiFEO9g/w640-h476/step8.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1A-j1okwhnwB7V61rj60U918KH-usWbjVd0U8uNn2uHdFRQ5d6Hx6u2b9fu5dNryv2nz6M8unCRJX6hAxHvUS4J1WiF2u4VVm5Au8MQ72RETIrVGoPLnisKvO-pBeaDphLZEauXyKJyCJZE2y72SMvbIDR3s7XOkbtHWBsHuOShDBe1jvug/s1263/step9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1A-j1okwhnwB7V61rj60U918KH-usWbjVd0U8uNn2uHdFRQ5d6Hx6u2b9fu5dNryv2nz6M8unCRJX6hAxHvUS4J1WiF2u4VVm5Au8MQ72RETIrVGoPLnisKvO-pBeaDphLZEauXyKJyCJZE2y72SMvbIDR3s7XOkbtHWBsHuOShDBe1jvug/w640-h476/step9.png" width="640" /></a></div><div><br /></div>Step 9: Change the top UIView's constraint multiplier to 0.5<div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe5Cjr68gBRcx6H_HPGb4cbP9Rh7Lm2EWg9he1BwvggiYrzUQoqFxvDecDEaWBJfaVKtb6YT32DSZ2ZUFZ0ApTuFjxrC0vBt14BauXt6gj0Nmr5d9JhaZWEJiKpUKl-_m0Opc6-V5c3_JZAjfUh8cNvICJ5TouflX3cq5Whd5hFQy6OSqZJg/s1263/step10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe5Cjr68gBRcx6H_HPGb4cbP9Rh7Lm2EWg9he1BwvggiYrzUQoqFxvDecDEaWBJfaVKtb6YT32DSZ2ZUFZ0ApTuFjxrC0vBt14BauXt6gj0Nmr5d9JhaZWEJiKpUKl-_m0Opc6-V5c3_JZAjfUh8cNvICJ5TouflX3cq5Whd5hFQy6OSqZJg/w640-h476/step10.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg73FTprGGvH58FUu-x78y4DPqqUtPWidDkzNEMZ9roNHMbia7DrcOMdby12wGvnxDhDGjTMqsn7x0lROSxcI-0Z56wUVG8xvwEZNVAyciYPTvBMWE64_3_6g3bbYMf3gvhBXPxS5Y6YxuGGOgdnM9xWVe2sV8AnfZIoofR8NjCgvDeSpcWnA/s1263/step11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="941" data-original-width="1263" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg73FTprGGvH58FUu-x78y4DPqqUtPWidDkzNEMZ9roNHMbia7DrcOMdby12wGvnxDhDGjTMqsn7x0lROSxcI-0Z56wUVG8xvwEZNVAyciYPTvBMWE64_3_6g3bbYMf3gvhBXPxS5Y6YxuGGOgdnM9xWVe2sV8AnfZIoofR8NjCgvDeSpcWnA/w640-h476/step11.png" width="640" /></a></div><br /><p><br /></p><p>See also:</p><h3 class="post-title entry-title" itemprop="name" style="color: #cc6600; font-family: Georgia, serif; font-size: 18.200000762939453px; font-weight: normal; line-height: 1.4em; margin: 0.25em 0px 0px; padding: 0px 0px 4px;"><a href="https://digerati-illuminatus.blogspot.com/2022/05/uiviewextended-stackview-and.html">UIViewExtended - StackView and FillProportionally</a></h3></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-49521826863863327492022-05-29T18:30:00.004-07:002022-05-30T10:52:30.863-07:00UIViewExtended - StackView and FillProportionally<p> Hav you have ever put a UIView in a StackView and wondered why "Fill Proportionally" wasn't working when you set the UIView's "Intrinsic Size"?</p><p>It's because the UIView doesn't let the intrinsic value be set, and therefore it can't be read.</p><p>So, I am thinking, there must be a way to add a property to the UIView via a subclass that will get the job done.</p><p>The approach is to use @IBInspectable.</p><p>Here is the source:</p><p><br /></p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">//</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">// UIViewExtended.swift</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">//</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">// Created by Geoffrey Slinker on 5/28/22.</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">// Copyright © 2022 Geoffrey Slinker. All rights reserved.</p><p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">//</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>import</b></span> Foundation</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>import</b></span> UIKit</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p><p style="background-color: white; color: #0b4f79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>class</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>UIViewExtended<span color="rgba(0, 0, 0, 0.85)"> : </span><span style="color: #3900a0;">UIView</span><span color="rgba(0, 0, 0, 0.85)"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>enum</b></span> <span style="color: #0b4f79;">Keys</span>: <span style="color: #3900a0;">String</span> {</p><p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>case</b></span><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">proportionalSize</span><span color="rgba(0, 0, 0, 0.85)"> = </span>"ProportionalSize"</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>var</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize<span color="rgba(0, 0, 0, 0.85)"> : </span><span style="color: #3900a0;">CGSize</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><b>override</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>init</b><span color="rgba(0, 0, 0, 0.85)">(</span><span style="color: #0f68a0;">frame</span><span color="rgba(0, 0, 0, 0.85)">: </span><span style="color: #3900a0;">CGRect</span><span color="rgba(0, 0, 0, 0.85)">) {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = <span style="color: #3900a0;">CGSize</span>(<span style="color: #6c36a9;">width</span>:<span style="color: #1c00cf;">1.0</span>, <span style="color: #6c36a9;">height</span>:<span style="color: #1c00cf;">1.0</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>super</b></span>.<span style="color: #6c36a9;">init</span>(<span style="color: #6c36a9;">frame</span>:frame)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>required</b></span> <span style="color: #9b2393;"><b>init</b></span>?(<span style="color: #0f68a0;">coder</span> aDecoder: <span style="color: #3900a0;">NSCoder</span>) {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> tempSize : <span style="color: #3900a0;">CGSize</span>? = aDecoder.<span style="color: #6c36a9;">decodeCGSize</span>(<span style="color: #6c36a9;">forKey</span>: <span style="color: #1c464a;">Keys</span>.<span style="color: #326d74;">proportionalSize</span>.<span style="color: #326d74;">rawValue</span>) <span style="color: #9b2393;"><b>as</b></span>? <span style="color: #3900a0;">CGSize</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>if</b></span> tempSize != <span style="color: #9b2393;"><b>nil</b></span> {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = tempSize!</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>else</b></span> {</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #326d74;">proportionalSize</span> = <span style="color: #3900a0;">CGSize</span>(<span style="color: #6c36a9;">width</span>:<span style="color: #1c00cf;">1.0</span>, <span style="color: #6c36a9;">height</span>:<span style="color: #1c00cf;">1.0</span>)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>super</b></span>.<span style="color: #6c36a9;">init</span>(<span style="color: #6c36a9;">coder</span>: aDecoder)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>override</b></span> <span style="color: #9b2393;"><b>func</b></span> <span style="color: #0f68a0;">encode</span>(<span style="color: #0f68a0;">with</span> coder: <span style="color: #3900a0;">NSCoder</span>) {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> coder.</span><span style="color: #6c36a9;">encode</span><span color="rgba(0, 0, 0, 0.85)">(</span><span style="color: #9b2393;"><b>self</b></span><span color="rgba(0, 0, 0, 0.85)">.</span>proportionalSize<span color="rgba(0, 0, 0, 0.85)">, </span><span style="color: #6c36a9;">forKey</span><span color="rgba(0, 0, 0, 0.85)">: </span><span style="color: #1c464a;">Keys</span><span color="rgba(0, 0, 0, 0.85)">.</span>proportionalSize<span color="rgba(0, 0, 0, 0.85)">.</span>rawValue<span color="rgba(0, 0, 0, 0.85)">)</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>super</b></span>.<span style="color: #6c36a9;">encode</span>(<span style="color: #6c36a9;">with</span>: coder)</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><b>@IBInspectable</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>var</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">intrinsicSize</span><span color="rgba(0, 0, 0, 0.85)">: </span><span style="color: #3900a0;">CGSize</span><span color="rgba(0, 0, 0, 0.85)"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>get</b></span> {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>return</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>set</b></span> {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize<span color="rgba(0, 0, 0, 0.85)"> = </span><span style="color: #6c36a9;">newValue</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>override</b></span><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>open</b></span><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>var</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>intrinsicContentSize<span color="rgba(0, 0, 0, 0.85)"> : </span><span style="color: #3900a0;">CGSize</span><span color="rgba(0, 0, 0, 0.85)"> {</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>get</b></span> {</p><p style="background-color: white; color: #326d74; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>return</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>proportionalSize</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: inherit;">Just set the intrinsic size in IB (Interface Builder). If you want to have the simulated view in IB look the same, keep the custom intrinsic size the same as the intrinsic size placeholder values. Yes, you have to manually keep the values the same, but at least you can do it all in IB.</span></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEiBr4gp9Y4IKd-_-hUWH4kh4YF6z62R5PzM8eUQm2Tgm1U5o5od6X08tv9gSl75p4muSLTikRawMYoxwuWl3zZ1QK1pcqzIxvJM3Br7LOqsoLX3CGEhQqJbj6rHGY9ADZsNcw1JBxBvFJUnMWa56IF3aYMY8J8KHGjQtkufzGCP1hRP7zjw/s760/tmp4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="645" data-original-width="760" height="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEiBr4gp9Y4IKd-_-hUWH4kh4YF6z62R5PzM8eUQm2Tgm1U5o5od6X08tv9gSl75p4muSLTikRawMYoxwuWl3zZ1QK1pcqzIxvJM3Br7LOqsoLX3CGEhQqJbj6rHGY9ADZsNcw1JBxBvFJUnMWa56IF3aYMY8J8KHGjQtkufzGCP1hRP7zjw/w640-h544/tmp4.png" width="640" /></a></div><br /><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">Set the values here:</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi07AoOwsiBmr7hec2ya-ZpWn1gHtjW0bx2CzJzoRMWfQmMXHqQimTssH_MNpTSCHsbTm9NuQ_xHLYybAqKpfU6vhcEic0VFTwzi6AZOe2EJZSZ0THYwLlrymMVJq1CsZ5JzCojbcHOMeO4paYa4cylnPvd-7REpDEa1eZ6Jjo8bB1MvEFhrw/s471/tmp2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="467" data-original-width="471" height="634" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi07AoOwsiBmr7hec2ya-ZpWn1gHtjW0bx2CzJzoRMWfQmMXHqQimTssH_MNpTSCHsbTm9NuQ_xHLYybAqKpfU6vhcEic0VFTwzi6AZOe2EJZSZ0THYwLlrymMVJq1CsZ5JzCojbcHOMeO4paYa4cylnPvd-7REpDEa1eZ6Jjo8bB1MvEFhrw/w640-h634/tmp2.png" width="640" /></a></div><br /><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxchaEJaAm9vA3rITMgTdIPbAumqrRosuqOn-YbyHfUFWQpr1rVOYWAHG_iyF_Yhio2AHal5IrDo6zCro_SuWg-GphM7UF7upgNVhjXHwMx0IvzqWVmOzsMqLoCc-z7hm4yc3G3APIvkpY8t3T4rDs4FzhKuQesYid5ROwow6QO3ASIYNACg/s1339/tmp.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="611" data-original-width="1339" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxchaEJaAm9vA3rITMgTdIPbAumqrRosuqOn-YbyHfUFWQpr1rVOYWAHG_iyF_Yhio2AHal5IrDo6zCro_SuWg-GphM7UF7upgNVhjXHwMx0IvzqWVmOzsMqLoCc-z7hm4yc3G3APIvkpY8t3T4rDs4FzhKuQesYid5ROwow6QO3ASIYNACg/w640-h292/tmp.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">If you want to UI to simulate the proportions then keep the custom value the same as the Intrinsic Size Placeholder value.</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2bsdB-1cxJe82D0T9sQSt8y2qFTsvUGdFNjrw5EpeltV5HfyI1UvCf-dNaXMvsad8ilKbEpl62jQE8MRiplJJ08TsJJcmUctmxCnVzVBckDv5EJvulgjeeylCSB2XP-N_Nwc_wzKUITQG093l1dzs_M6bBuQri0ciWVUhIHqqMKMdp8crEQ/s749/tmp3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="749" data-original-width="474" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2bsdB-1cxJe82D0T9sQSt8y2qFTsvUGdFNjrw5EpeltV5HfyI1UvCf-dNaXMvsad8ilKbEpl62jQE8MRiplJJ08TsJJcmUctmxCnVzVBckDv5EJvulgjeeylCSB2XP-N_Nwc_wzKUITQG093l1dzs_M6bBuQri0ciWVUhIHqqMKMdp8crEQ/w406-h640/tmp3.png" width="406" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div><br /></div><div>Here is the unit test. The unit test also gets the XML so that it can be examined in the debugger.</div><div><br /></div><div><br /></div><div><p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #9b2393;"><b>func</b></span><span color="rgba(0, 0, 0, 0.85)"> </span>testUIViewExtended<span color="rgba(0, 0, 0, 0.85)">() </span><span style="color: #9b2393;"><b>throws</b></span><span color="rgba(0, 0, 0, 0.85)"> {</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> view : <span style="color: #1c464a;">UIViewExtended</span> = <span style="color: #1c464a;">UIViewExtended</span>.<span style="color: #326d74;">init</span>(<span style="color: #326d74;">frame</span>: <span style="color: #3900a0;">CGRect</span>(<span style="color: #6c36a9;">x</span>: <span style="color: #1c00cf;">0</span>,<span style="color: #6c36a9;">y</span>: <span style="color: #1c00cf;">0</span>, <span style="color: #6c36a9;">width</span>: <span style="color: #1c00cf;">100</span>, <span style="color: #6c36a9;">height</span>: <span style="color: #1c00cf;">50</span>))</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> view.<span style="color: #326d74;">intrinsicSize</span> = <span style="color: #3900a0;">CGSize</span>(<span style="color: #6c36a9;">width</span>: <span style="color: #1c00cf;">5</span>,<span style="color: #6c36a9;">height</span>: <span style="color: #1c00cf;">5</span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: #5d6c79; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span>//Look at the xml in the debugger</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> archiver = <span style="color: #3900a0;">NSKeyedArchiver</span>(<span style="color: #6c36a9;">requiringSecureCoding</span>: <span style="color: #9b2393;"><b>false</b></span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> archiver.<span style="color: #6c36a9;">outputFormat</span> = .<span style="color: #6c36a9;">xml</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> archiver.<span style="color: #6c36a9;">encodeRootObject</span>(view)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> someData = archiver.<span style="color: #6c36a9;">encodedData</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> stringData = <span style="color: #3900a0;">String</span>(<span style="color: #3900a0;">decoding</span>: someData, <span style="color: #3900a0;">as</span>: <span style="color: #3900a0;">UTF8</span>.<span style="color: #9b2393;"><b>self</b></span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> codedData = <span style="color: #9b2393;"><b>try</b></span>! <span style="color: #3900a0;">NSKeyedArchiver</span>.<span style="color: #6c36a9;">archivedData</span>(<span style="color: #6c36a9;">withRootObject</span>: view,</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #6c36a9;">requiringSecureCoding</span>: <span style="color: #9b2393;"><b>false</b></span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>let</b></span> result = <span style="color: #9b2393;"><b>try</b></span>! <span style="color: #3900a0;">NSKeyedUnarchiver</span>.<span style="color: #6c36a9;">unarchiveTopLevelObjectWithData</span>(codedData) <span style="color: #9b2393;"><b>as</b></span>?</p>
<p style="background-color: white; color: #1c464a; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span>UIViewExtended</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"> </p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #6c36a9;">XCTAssert</span>(result?.<span style="color: #6c36a9;">frame</span>.<span style="color: #6c36a9;">width</span> == <span style="color: #1c00cf;">100</span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #6c36a9;">XCTAssert</span>(result?.<span style="color: #6c36a9;">frame</span>.<span style="color: #6c36a9;">height</span> == <span style="color: #1c00cf;">50</span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #6c36a9;">XCTAssert</span>(result?.<span style="color: #326d74;">intrinsicSize</span>.<span style="color: #6c36a9;">width</span> == <span style="color: #1c00cf;">5</span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #6c36a9;">XCTAssert</span>(result?.<span style="color: #326d74;">intrinsicSize</span>.<span style="color: #6c36a9;">height</span> == <span style="color: #1c00cf;">5</span>)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">See also:</p><p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><h3 class="post-title entry-title" itemprop="name" style="color: #cc6600; font-family: Georgia, serif; font-size: 18.200000762939453px; font-weight: normal; line-height: 1.4em; margin: 0.25em 0px 0px; padding: 0px 0px 4px;"><a href="https://digerati-illuminatus.blogspot.com/2022/05/stackview-constraining-contained-views.html">StackView - Constraining Contained Views</a></h3></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-75494883613722216692022-01-26T19:43:00.005-08:002022-01-28T07:49:45.747-08:00AntPathMatcher replace with PathPatternParser<p>AntPathMatcher setCaseSensitive not working?</p><p>Did you update the version of Spring Boot? Did your URI case insensitivity stop working?</p><p>Did you have something like this:</p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">@Configuration</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">public class WebConfig implements WebMvcConfigurer</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">{</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> @Override</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> public void configurePathMatch(PathMatchConfigurer configurer)</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> {</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> AntPathMatcher matcher = new AntPathMatcher();</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> matcher.setCaseSensitive(false);</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> configurer.setPathMatcher(matcher);</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> }</span></p><p style="font-family: Helvetica; font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><p style="font-family: Helvetica; font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;">Change it to something like this:</p><p style="font-family: Helvetica; font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><br /></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">@Configuration</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">public class WebConfig implements WebMvcConfigurer</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">{</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> @Override</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> public void configurePathMatch(PathMatchConfigurer configurer)</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> {</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> PathPatternParser patternParser = new PathPatternParser();</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> patternParser.setCaseSensitive(false);</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> configurer.setPatternParser(patternParser);</span></p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;"> }</span></p><p>If you want to continue to use AntPathMatcher, add this to your application.properties file:</p><p style="font-size: 14px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="font-family: courier;">spring.mvc.pathmatch.matching-strategy=ant-path-matcher</span></p><div><br /></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-51232291206695743712022-01-05T10:31:00.004-08:002022-01-12T07:37:35.629-08:00Boxing an Array in Swift<p><a href="https://developer.apple.com/documentation/swift/array">Swift Arrays</a> </p><p>If you are reading this you probably have the need to work with an array returned from a function or a copy of an array.
I have been porting a complex data transfer object (DTO) from Java to Swift. The Java implementation of this DTO has many violations the Law of Demeter.</p><p>The Swift implementation needs to resemble the Java implementation so that changes to one code base will be easier to make in the other code base. This requirement lead me to creating a Boxed Array which I named "List". Before critiquing the name of the class or the method names, this is to make the port from Java as simple as possible FOR ME. You can make List implement the methods of a Swift Array if you want, or make Protocols for your own "collection classes". <br /></p><p>This example of Boxing / Wrapping a Swift Array is as simple as possible. This includes the ability to serialize the List class to be the same as an Array when serialized to JSON.</p><hr /><br /><div style="text-align: left;"><span style="font-size: x-small;"><span style="font-family: courier;">//Geoffrey Slinker - Just keep my name here please. <br /></span></span></div><div style="text-align: left;"><span style="font-size: x-small;"><span style="font-family: courier;">import Foundation</span></span></div><div style="text-align: left;"><span style="font-size: x-small;"><span style="font-family: courier;"><br /><br />public class List<T : Equatable & Codable> : Sequence, Codable<br />{<br /> var container : [T] = []<br /> <br /> public init() {<br /> <br /> }<br /> <br /> //------------------------------------------------------------------------<br /> //JSON Serialization <br /> required public init(from decoder:Decoder) throws {<br /> try container = [T](from: decoder)<br /> }<br /> <br /> public func encode(to encoder: Encoder) throws {<br /> try container.encode(to: encoder)<br /> }<br /> //------------------------------------------------------------------------<br /> <br /> public func makeIterator() -> ListIterator<T> {<br /> return ListIterator(self)<br /> }<br /> <br /> public func append(_ newElement:T) {<br /> container.append(newElement)<br /> }<br /> <br /> public func get(_ at : Int) -> T? {<br /> return container[at]<br /> }<br /> <br /> public func remove(at : Int) {<br /> container.remove(at: at)<br /> }<br /> <br /> public func remove(_ element:T) {<br /> if let index = container.firstIndex(where: {$0 == element}) {<br /> container.remove(at: index)<br /> }<br /> }<br /> <br /> public func clear() {<br /> container.removeAll()<br /> }<br /> <br /> public var count : Int {<br /> get {<br /> return container.count<br /> }<br /> }<br />}<br /><br />public struct ListIterator<T : Equatable & Codable> : IteratorProtocol<br />{<br /> let list : List<T><br /> var currentPosition = 0<br /> <br /> init(_ list: List<T>) {<br /> self.list = list<br /> }<br /> <br /> public mutating func next() -> T? {<br /> if(currentPosition < list.count) {<br /> let result = list.get(currentPosition)<br /> currentPosition += 1<br /> return result<br /> }<br /> return nil<br /> }<br /> <br />}</span></span></div><hr /><p>Test Code</p><div style="text-align: left;"><span style="font-size: x-small;"><span style="font-family: courier;">import XCTest<br /><br />class ListTests: XCTestCase {<br /><br /> override func setUpWithError() throws {<br /> // Put setup code here. This method is called before the invocation of each test method in the class.<br /> }<br /><br /> override func tearDownWithError() throws {<br /> // Put teardown code here. This method is called after the invocation of each test method in the class.<br /> }<br /><br /><br /> func testJson() throws {<br /> let myArray = [0, 1, 2, 3]<br /> <br /> let arrayData = try! JSONSerialization.data(withJSONObject: myArray, options: [])<br /> let arrayJson = String(data: arrayData, encoding: String.Encoding.utf8)<br /> <br /> <br /> let myList : List<Int> = List<Int>()<br /> myList.append(0)<br /> myList.append(1)<br /> myList.append(2)<br /> myList.append(3)<br /> <br /><br /> let listData = try! JSONEncoder().encode(myList)<br /> let listJson = String(data: listData, encoding: String.Encoding.utf8)<br /> <br /> XCTAssertEqual(arrayJson, listJson)<br /> <br /><br /> let anotherList : List<Int>? = try JSONDecoder().decode(List<Int>.self, from: listData)<br /> XCTAssert(anotherList!.count == 4)<br /> XCTAssertEqual(anotherList?.get(0), 0)<br /> XCTAssertEqual(anotherList?.get(1), 1)<br /> XCTAssertEqual(anotherList?.get(2), 2)<br /> XCTAssertEqual(anotherList?.get(3), 3)<br /> <br /> let yetAnotherList : List<Int>? = try JSONDecoder().decode(List<Int>.self, from: arrayData)<br /> XCTAssert(yetAnotherList!.count == 4)<br /> XCTAssertEqual(yetAnotherList?.get(0), 0)<br /> XCTAssertEqual(yetAnotherList?.get(1), 1)<br /> XCTAssertEqual(yetAnotherList?.get(2), 2)<br /> XCTAssertEqual(yetAnotherList?.get(3), 3)<br /> }<br /><br />}</span></span><br /></div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-78919077495459608282020-04-06T12:34:00.000-07:002020-04-06T12:34:16.627-07:00Mac OS FileMerge as git difftool<br />From a console run:<br />git config --global --edit<br /><br /><br />Add the following to the file.<br /><br />[diff]<br /><br /> tool = opendiff<br /><br />[merge]<br /><br /> tool = opendiff<br /><br />[difftool]<br /><br /> prompt = false<br /><br />[mergetool]<br /><br /> prompt = falseGeoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-67580369828274390072020-02-10T10:43:00.000-08:002020-02-10T10:43:11.431-08:00Binding: Compile-time vs Runtime, Overload vs Override, Swift and JavaObject Oriented Languages, such as Swift and Java, have two commonly used features for methods/functions, Overloading and Overriding.<br />
<br />
There are many descriptions of overloading and overriding, so I will not go into details about that. The purpose of this post is to point out when the method to call is selected. Overloaded methods are selected at compile time. Overridden methods are selected at runtime.<br />
<br />
Consider this example in Swift.<br />
<br />
main.swift<br />
<br />
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">import</span> Foundation</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">let</span><span class="s2" style="color: white;"> </span><span class="s3" style="color: #41a1c0;">classC</span><span class="s2" style="color: white;"> : </span>ClassC<span class="s2" style="color: white;"> = </span>ClassC<span class="s2" style="color: white;">()</span></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">let</span><span class="s2" style="color: white;"> </span><span class="s3" style="color: #41a1c0;">classB</span><span class="s2" style="color: white;"> : </span>ClassB<span class="s2" style="color: white;"> = </span>classC</div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">let</span><span class="s2" style="color: white;"> </span><span class="s3" style="color: #41a1c0;">classA</span><span class="s2" style="color: white;"> : </span>ClassA<span class="s2" style="color: white;"> = </span>classC</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p4" style="background-color: black; color: #41cc45; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
//Runtime binding for overrides</div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
classC<span class="s2" style="color: white;">.</span>message<span class="s2" style="color: white;">()</span></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
classB<span class="s2" style="color: white;">.</span>message<span class="s2" style="color: white;">()</span></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
classA<span class="s2" style="color: white;">.</span>message<span class="s2" style="color: white;">()</span></div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p5" style="background-color: black; color: #ff2c38; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s4" style="color: #00a0ff;">print</span><span class="s2" style="color: white;">(</span>"------------------"<span class="s2" style="color: white;">)</span></div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p4" style="background-color: black; color: #41cc45; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
//Compile-time binding for overloads</div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">let</span><span class="s2" style="color: white;"> </span><span class="s3" style="color: #41a1c0;">messageUtil</span><span class="s2" style="color: white;"> : </span>ClassMessageUtil<span class="s2" style="color: white;"> = </span>ClassMessageUtil<span class="s2" style="color: white;">()</span></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
messageUtil<span class="s2" style="color: white;">.</span>message<span class="s2" style="color: white;">(</span>classC<span class="s2" style="color: white;">)</span></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
messageUtil<span class="s2" style="color: white;">.</span>message<span class="s2" style="color: white;">(</span>classB<span class="s2" style="color: white;">)</span></div>
<div class="p3" style="background-color: black; color: #23ff83; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
messageUtil<span class="s2" style="color: white;">.</span>message<span class="s2" style="color: white;">(</span>classA<span class="s2" style="color: white;">)</span></div>
<br />
Output:<br />
<br />
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>ClassC:message: BindingExperiment.ClassC</b></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>ClassC:message: BindingExperiment.ClassC</b></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>ClassC:message: BindingExperiment.ClassC</b></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>------------------</b></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>ClassC:message BindingExperiment.ClassC</b></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>ClassB:message BindingExperiment.ClassC</b></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<b>ClassA:message BindingExperiment.ClassC</b></div>
<br />
ClassA<br />
<br />
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">import</span> Foundation</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p3" style="background-color: black; color: #5dd8ff; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">class</span><span class="s2" style="color: white;"> </span>ClassA<span class="s2" style="color: white;"> {</span></div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">func</span> <span class="s3" style="color: #41a1c0;">message</span>() {</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">let</span> messageString : <span class="s4" style="color: #00a0ff;">String</span> = <span class="s5" style="color: #ff2c38;">"ClassA:message: "</span> <span class="s4" style="color: #00a0ff;">+</span> <span class="s4" style="color: #00a0ff;">String</span>(describing: <span class="s1" style="color: #d31895;">self</span>)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s4" style="color: #00a0ff;">print</span>(messageString)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span>}</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
}</div>
<br />
ClassB<br />
<br />
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">import</span> Foundation</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">class</span> <span class="s2" style="color: #5dd8ff;">ClassB</span> : <span class="s3" style="color: #23ff83;">ClassA</span> {</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p3" style="background-color: black; color: #d31895; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s4" style="color: white;"> </span>override<span class="s4" style="color: white;"> </span>func<span class="s4" style="color: white;"> </span><span class="s5" style="color: #41a1c0;">message</span><span class="s4" style="color: white;">() {</span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">let</span> messageString : <span class="s6" style="color: #00a0ff;">String</span> = <span class="s7" style="color: #ff2c38;">"ClassB:message: "</span> <span class="s6" style="color: #00a0ff;">+</span> <span class="s6" style="color: #00a0ff;">String</span>(describing: <span class="s1" style="color: #d31895;">self</span>)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s6" style="color: #00a0ff;">print</span>(messageString)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span>}</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
}</div>
<br />
ClassC<br />
<br />
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">import</span> Foundation</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">class</span> <span class="s2" style="color: #5dd8ff;">ClassC</span> : <span class="s3" style="color: #23ff83;">ClassB</span> {</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p3" style="background-color: black; color: #d31895; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s4" style="color: white;"> </span>override<span class="s4" style="color: white;"> </span>func<span class="s4" style="color: white;"> </span><span class="s5" style="color: #41a1c0;">message</span><span class="s4" style="color: white;">() {</span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">let</span> messageString : <span class="s6" style="color: #00a0ff;">String</span> = <span class="s7" style="color: #ff2c38;">"ClassC:message: "</span> <span class="s6" style="color: #00a0ff;">+</span> <span class="s6" style="color: #00a0ff;">String</span>(describing: <span class="s1" style="color: #d31895;">self</span>)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s6" style="color: #00a0ff;">print</span>(messageString)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span>}</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
}</div>
<br />
ClassMessageUtil<br />
<br />
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">import</span> Foundation</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<br /></div>
<div class="p3" style="background-color: black; color: #5dd8ff; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="s1" style="color: #d31895;">class</span><span class="s2" style="color: white;"> </span>ClassMessageUtil<span class="s2" style="color: white;"> {</span></div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">func</span> <span class="s3" style="color: #41a1c0;">message</span>(<span class="s1" style="color: #d31895;">_</span> classA : <span class="s4" style="color: #23ff83;">ClassA</span>) {</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">let</span> messageString : <span class="s5" style="color: #00a0ff;">String</span> = <span class="s6" style="color: #ff2c38;">"ClassA:message "</span> <span class="s5" style="color: #00a0ff;">+</span> <span class="s5" style="color: #00a0ff;">String</span>(describing: classA)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s5" style="color: #00a0ff;">print</span>(messageString)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span>}</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">func</span> <span class="s3" style="color: #41a1c0;">message</span>(<span class="s1" style="color: #d31895;">_</span> classB : <span class="s4" style="color: #23ff83;">ClassB</span>) {</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">let</span> messageString : <span class="s5" style="color: #00a0ff;">String</span> = <span class="s6" style="color: #ff2c38;">"ClassB:message "</span> <span class="s5" style="color: #00a0ff;">+</span> <span class="s5" style="color: #00a0ff;">String</span>(describing: classB)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s5" style="color: #00a0ff;">print</span>(messageString)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span>}</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">func</span> <span class="s3" style="color: #41a1c0;">message</span>(<span class="s1" style="color: #d31895;">_</span> classC : <span class="s4" style="color: #23ff83;">ClassC</span>) {</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s1" style="color: #d31895;">let</span> messageString : <span class="s5" style="color: #00a0ff;">String</span> = <span class="s6" style="color: #ff2c38;">"ClassC:message "</span> <span class="s5" style="color: #00a0ff;">+</span> <span class="s5" style="color: #00a0ff;">String</span>(describing: classC)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span><span class="s5" style="color: #00a0ff;">print</span>(messageString)</div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
<span class="Apple-converted-space"> </span>}</div>
<div class="p2" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; min-height: 16px;">
<span class="Apple-converted-space"> </span></div>
<div class="p1" style="background-color: black; color: white; font-family: Menlo; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
}</div>
<br />
<br />
Above is all of the code and the output, now let's review "main" and the output.<br />
<br />
The inheritance of the classes are:<br />ClassC "isa" ClassB<br />
ClassB "isa" ClassA<br />
<br />
ClassA is the "most" base class in this example. These classes implement "message", so each subclass overrides the implementation. This will show runtime binding of method selection.<br />
<br />
ClassMessageUtil was created to show method overloading. There are three implementations of "message", each one taking a different input variable type, one for ClassA, one for ClassB, and one for ClassC. This is used to show that the binding for method selection happens at compile time.<br />
<br />
<i>let classC : ClassC = ClassC()</i><br />
<i>let classB : ClassB = classC</i><br />
<i>let classA : ClassA = classC</i><br />
<br />
We instantiate one instance of ClassC and assign that instance to variables that have the type ClassB and ClassA. This can be done because of inheritance.<br />
<br />
<i>classC.message()</i> outputs ClassC:message: BindingExperiment.ClassC<br />
<i>classB.message()</i> outputs ClassC:message: BindingExperiment.ClassC<br />
<i>classA.message()</i> outputs ClassC:message: BindingExperiment.ClassC<br />
<br />
At runtime the system recognizes that the instance is a "ClassC", and therefore calls ClassC message.<br />
<br />
What follows shows compile-time binding. This happens for overloaded methods. At compile time the best "type" fit is selected.<br />
<br />
<br />
<i>let messageUtil : ClassMessageUtil = ClassMessageUtil()</i><br />
<i>messageUtil.message(classC)</i> outputs ClassC:message BindingExperiment.ClassC<br />
<i>messageUtil.message(classB)</i> outputs <b>ClassB:message BindingExperiment.ClassC</b><br />
<i>messageUtil.message(classA)</i> outputs ClassA:message BindingExperiment.ClassC<br />
<br />
Because classB has a declared type of ClassB, even though it references an instance of ClassC, the compiler selects the overloaded method that matches the best which is:<br />
<br />
<i> func message(_ classB : ClassB) {</i><br />
<i> let messageString : String = "<b>ClassB:message " + String(describing: classB)</b></i><br />
<i> print(messageString)</i><br />
<i> }</i><br />
<br />
It did not use the method that has a parameter of type ClassC. The selection was made at compile time.<br /><br />This may not be what you expected.<br /><br />It is not uncommon to create methods that take parameters of some base class and then use overrides to get the runtime behavior you desire. This practice can surprise you when compile-time binding comes into play for overloaded methods. If you have this problem and you find yourself trying to fix it by using a "switch" statement and cast the parameter to its subclass, this is usually wrong and the code needs to be redesigned.<br />
<br />
One approach is to use "protocols" in Swift or "interfaces" in Java as parameter types instead of some base class.<br />
<br />
Here is the same example in Java.<br />
<br />
public class Main {<br />
<br />
public static void main(String[] args) {<br />
<br />
ClassC cClass = new ClassC();<br />
ClassB bClass = cClass;<br />
ClassA aClass = cClass;<br />
<br />
//Runtime binding for overrides<br />
cClass.message();<br />
bClass.message();<br />
aClass.message();<br />
<br />
System.out.println("------------------------");<br />
<br />
//Compile-time binding for overloads<br />
ClassMessageUtil messageUtil = new ClassMessageUtil();<br />
messageUtil.message(<b>cClass</b>);<br />
messageUtil.message(<b>bClass</b>);<br />
messageUtil.message(<b>aClass</b>);<br />
<br />
}<br />
}<br />
<br />
<br />
Output:<br /><br />
<b>ClassC</b>:message com.XXX.ClassC<br />
<b>ClassC</b>:message com. XXX.ClassC<br />
<b>ClassC</b>:message com. XXX.ClassC<br />
------------------------<br />
<b>ClassC</b>:message com. XXX.ClassC<br />
<b>ClassB</b>:message com. XXX.ClassC<br />
<b>ClassA</b>:message com. XXX.ClassC<br />
<br />
public class ClassA<br />
{<br />
public void message()<br />
{<br />
String messageString = "ClassA:message " + this.getClass().getName();<br />
System.out.println(messageString);<br />
}<br />
}<br />
<br />
public class ClassB extends ClassA<br />
{<br />
public void message()<br />
{<br />
String messageString = "ClassB:message " + this.getClass().getName();<br />
System.out.println(messageString);<br />
}<br />
}<br />
<br />
public class ClassC extends ClassB<br />
{<br />
public void message()<br />
{<br />
String messageString = "ClassC:message " + this.getClass().getName();<br />
System.out.println(messageString);<br />
}<br />
}<br />
<br />
public class ClassMessageUtil<br />
{<br />
public void message(ClassA classA)<br />
{<br />
String messageString = "ClassA:message " + classA.getClass().getName();<br />
System.out.println(messageString);<br />
}<br />
<br />
public void message(ClassB classB)<br />
{<br />
String messageString = "ClassB:message " + classB.getClass().getName();<br />
System.out.println(messageString); }<br />
<br />
public void message(ClassC classC)<br />
{<br />
String messageString = "ClassC:message " + classC.getClass().getName();<br />
System.out.println(messageString); }<br />
}<br />
<br />
<br />
As you can see in this example, Swift and Java behave the same.<br />
<br />Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-49317362529213718972018-04-03T17:04:00.000-07:002018-04-03T17:16:18.725-07:00Solr 7 TieredMergePolicyFactoryIf you get this error when using Solr 7 in cloud mode when you try to create the collection about the TieredMergePolicyFactory:<br />
<br />
"Caused by: solr.TieredMergePolicyFactory"<br />
<br />
The reason maybe it failed to load the class and this is because the example solr config file has an error in it:<br />
<br />
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code> <mergePolicyFactory class="solr.TieredMergePolicyFactory">
<int name="maxMergeAtOnce">10</int>
<int name="segmentsPerTier">10</int>
</mergePolicyFactory>
</code></pre>
<br />
<div>
This is what worked for me:<br />
<br />
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code> <mergePolicyFactory class="org.apache.solr.index.TieredMergePolicyFactory">
<int name="maxMergeAtOnce">10</int>
<int name="segmentsPerTier">10</int>
</mergePolicyFactory>
</code></pre>
</div>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-28971295781180519482017-07-26T16:24:00.002-07:002017-07-27T09:22:38.325-07:00Lucy Queries and Plastic - A type of Lucene Query for ElasticSearch<h2>
Introduction</h2>
A Lucy Query is a query that is very similar to a Lucene query and a Solr query, however, not as robust at this time, nor do I feel it needs to be for my uses.<br />
<br />
Plastic takes a Lucy Query and converts it at run-time into a boolean query for ElasticSearch.<br />
<br />
Generating Lucene or Solr queries programatically is relatively straightforward, however generating ElasticSearch queries programatically is difficult due to ElasticSearch's use of a fluent (dot type) syntax where you generate objects and nest other objects inside of those, etc. It is much easier to generate a text string that specifies a query.<br />
<br />
A text string query specification also allows for the creation of a query template and facilitates Query by Example (QBE) queries.<br />
<br />
<h2>
Lucy Query</h2>
Lucy queries are similar to Solr queries and to Lucene queries. Lucy queries do not support the syntactical sugar for AND and OR found in Solr. Lucy queries only use the operators for required (+), not required, and not (!).<br />
<br />
For example:<br />
+name:"john" phone:"555-2121"<br />
<br />
The name is required and the phone is not. Run the above Lucy query through Plastic and the following ElasticSearch query is generated:<br />
<br />
{<br />
"bool" : {<br />
"must" : [<br />
{<br />
"match" : {<br />
"name" : {<br />
"query" : "john",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"should" : [<br />
{<br />
"match" : {<br />
"phone" : {<br />
"query" : "555-2121",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
<br />
Lucy queries support grouping of query terms. If the above query is modified to use groups like this:<br />
+(name:"john") (phone:"555-2121")<br />
<br />
Then the results after running the Lucy query through Plastic is very different but results in a query that is equivalent to the original query. Notice how the grouping creates a new boolean query in ElasticSearch for each group, it nests the query terms exactly like the Lucy query specifies.<br />
<br />
{<br />
"bool" : {<br />
"must" : [<br />
{<br />
"bool" : {<br />
"should" : [<br />
{<br />
"match" : {<br />
"name" : {<br />
"query" : "john",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
],<br />
"should" : [<br />
{<br />
"bool" : {<br />
"should" : [<br />
{<br />
"match" : {<br />
"phone" : {<br />
"query" : "555-2121",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
<br />
Lucy supports nested queries of ElasticSearch (something that is not found in a Solr or Lucene Query). Nesting is specified by using the dot "." in the field name.<br />
<br />
name.given:"john" name.surname:"smith"<br />
<br />
In the above Lucy query the field values to query are nested. The ElasticSearch mappings (schema) to create the field is thus:<br />
<br />
<br />
"names": {<br />
"type": "nested",<br />
"properties": {<br />
"given": {<br />
"type": "text",<br />
"norms": false,<br />
"similarity": "boolean",<br />
"analyzer": "whitespace"<br />
},<br />
"surname": {<br />
"type": "text",<br />
"norms": false,<br />
"similarity": "boolean",<br />
"analyzer": "whitespace"<br />
}<br />
}<br />
}<br />
<br />
After running the above Lucy query through Plastic this is the ElasticSearch query:<br />
<br />
{<br />
"bool" : {<br />
"should" : [<br />
{<br />
"nested" : {<br />
"query" : {<br />
"match" : {<br />
"name.given" : {<br />
"query" : "john",<br />
"boost" : 1.0<br />
}<br />
}<br />
},<br />
"path" : "name",<br />
"score_mode" : "avg",<br />
"boost" : 1.0<br />
}<br />
},<br />
{<br />
"nested" : {<br />
"query" : {<br />
"match" : {<br />
"name.surname" : {<br />
"query" : "smith",<br />
"boost" : 1.0<br />
}<br />
}<br />
},<br />
"path" : "name",<br />
"score_mode" : "avg",<br />
"boost" : 1.0<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
<br />
<br />
<br />
A simple Lucy query is composed of:<br />
<ul>
<li>field name followed by a colon</li>
<li>a field value, which may or may not be in quotes</li>
</ul>
<br />
For instance the following is a valid Lucy query:<br />
<ul>
<li>names.given:"john mark"</li>
</ul>
<br />
A Lucy query can have modifiers for boost, fuzzy / slop, and constant score.<br />
<ul>
<li>names.given:"john mark"~3, this sets the slop for a phrase query to be 3.</li>
<li>names.given:"john mark"^3, this sets the boost to be 3.</li>
<li>names.given:"john mark"^=3, this sets the constant score to be 3.</li>
</ul>
<br />
A Lucy query can have modifiers for the operations of must, must not, and should.<br />
<ul>
<li>names.given:"john mark", should match</li>
<li>+names.given:"john mark", must match</li>
<li>!names.given:"john mark", must not match</li>
</ul>
<br />
A Lucy query can have query terms grouped by parenthesis and those parenthesis can have modifiers.<br />
<ul>
<li>(names.given:"john mark" names.surname:"smith"), should match on the results of what is inside the parenthesis.</li>
<li>+(names.given:"john mark" names.surname:"smith"), must match on the results of what is inside the parenthesis.</li>
<li>!(names.given:"john mark" names.surname:"smith"), match not on the results of what is inside the parenthesis.</li>
</ul>
<br />
Grouped terms in a Lucy query can have modifiers as well.<br />
<ul>
<li>(names.given:"john mark" names.surname:"smith")^3</li>
</ul>
<h2>
</h2>
<h2>
Plastic</h2>
<div>
Plastic currently has two features.</div>
<div>
<ol>
<li>Convert Lucy Queries into ElasticSearch Queries</li>
<li>Expand Lucy Query Templates into Lucy Queries</li>
</ol>
<div>
<br /></div>
</div>
<div>
Converting a Lucy Query into an ElasticSearch query is done in a Java module I call Plastic. It is mentioned above, but to keep documentation simple here is an example.</div>
<div>
<br /></div>
<div>
For example take the following Lucy Query:<br />
+name:"john" phone:"555-2121"<br />
<br />
The name is required and the phone is not. Run the above Lucy query through Plastic and the following ElasticSearch query is generated:<br />
<br />
{<br />
"bool" : {<br />
"must" : [<br />
{<br />
"match" : {<br />
"name" : {<br />
"query" : "john",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"should" : [<br />
{<br />
"match" : {<br />
"phone" : {<br />
"query" : "555-2121",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
<br />
One advantage of having a query in text like a Lucy Query is that Query Templates can be made and used with a term expander to facilitate "Query By Example" (QBE).<br />
<br />
A Lucy Query Template is:<br />
FieldName:{EXPANSION_OPERATOR}<br />
<br />
The EXPANSION OPERATORS ARE:<br />
<ul>
<li>FIRST</li>
<li>AND</li>
<li>OR</li>
<li>AND#N (where N is an integer)</li>
<li>OR#N (where N is an integer)</li>
</ul>
<h3>
Single Value Expansion Operators</h3>
FIRST is replaced by the first value found<br />
<br />
<h3>
Multi-Value Expansion Operators</h3>
</div>
<div>
AND is replaced by a required term for each value.<br />
names.given{AND} for "John Willam"<br />
+names.given:"John" +names.given:"William"<br />
<br />
OR is replaced by a term for each value.<br />
names.given{OR} for "John Willam"<br />
names.given:"John" names.given:"William"<br />
<br />
AND#N OR#N: These are used to limit multivalued terms.<br />
AND#2 means and the first two values.<br />
AND#3 means and the first three values.</div>
<div>
<br /></div>
<div>
It takes a Lucy Query Template and a HashMap (Dictionary) of term values for Plastic to expand a Lucy Query Template into a Lucy Query which in turn can be transformed into an ElasticSearch query.</div>
<div>
<br /></div>
<div>
For example, given the following Lucy Query Template:</div>
<div>
givenName{AND} surname:{OR}</div>
<div>
<br /></div>
<div>
And the following HashMap<string ist="" tring="">>:</string></div>
<div>
{surname=[Smith, Schmidt], givenName=[john, mark]}</div>
<div>
<br /></div>
<div>
Plastic will expand the Lucy Query Template with the data found in the HashMap to be the following Lucy Query:</div>
<div>
<div>
( +givenName:"john" +givenName:"mark" ) ( surname:"Smith" surname:"Schmidt" ) </div>
</div>
<div>
<br /></div>
Then Plastic will convert the above Lucy Query into an ElasticSearch query:<br />
<br />
{<br />
"bool" : {<br />
"should" : [<br />
{<br />
"bool" : {<br />
"must" : [<br />
{<br />
"match" : {<br />
"givenName" : {<br />
"query" : "john",<br />
"boost" : 1.0<br />
}<br />
}<br />
},<br />
{<br />
"match" : {<br />
"givenName" : {<br />
"query" : "mark",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
},<br />
{<br />
"bool" : {<br />
"should" : [<br />
{<br />
"match" : {<br />
"surname" : {<br />
"query" : "Smith",<br />
"boost" : 1.0<br />
}<br />
}<br />
},<br />
{<br />
"match" : {<br />
"surname" : {<br />
"query" : "Schmidt",<br />
"boost" : 1.0<br />
}<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
],<br />
"boost" : 1.0<br />
}<br />
}<br />
<br />
<h2>
Conclusion</h2>
Lucy Queries allow for straightforward query generation at run-time. These Lucene-like queries are then converted to ElasticSearch queries by the Plastic module.<br />
<br />
Once you have a text based query language that can be converted into ElasticSearch queries then you can create Query Templates and perform Query By Example (QBE) queries in a straight forward manner.<br />
<br />
This makes ElasticSearch more usable for those that have systems where the user can specify arbitrary queries via some mechanism such as a UI.<br />
<br />
Lucy Query and Plastic are terms invented for the use in the space of querying ElasticSearch relative to Lucene and Solr as well. June 2017.Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-8582042528412318612016-07-15T14:00:00.003-07:002016-07-15T14:10:42.886-07:00Scouting and Reconnaissance in Software DevelopmentCheck out my other blog:<br />
<a href="http://mavericksoftwaredevelopment.blogspot.com/2012/05/maverick-software-development-model.html">Maverick Software Development</a><br />
<h1>
Scouting and Reconnaissance in Software Development</h1>
by Geoffrey Slinker<br />
v1.0 October 2004<br />
v1.1 January 2005<br />
v1.2, v1.3, v1.4 July 2005<br />
v1.5 March 24, 2006<br />
<br />
<table id="Table1" style="width: 100%px;"><tbody>
<tr align="left"><td></td></tr>
<tr><td>Maverick Development</td></tr>
</tbody></table>
<h2>
Abstract</h2>
Scouting and reconnaissance are two well known methods of discovery. By these means information and experience are gained when faced with the unknown. Experience is critical to writing good software. Experience allows you to correctly identify problems and address them. Scouting and recon for software development is a great way to gain experience and avoid the pitfalls of the unknown.<br />
<h2>
Introduction</h2>
In the well known book ‘The Mythical Man-Month’ Frederick P Brooks states:<br />
<blockquote dir="ltr" style="margin-right: 0px;">
<em>Where a new system concept or new technology is used, one has to build a system to throw away, for even the best planning is not so omniscient as to get it right the first time. Hence plan to throw one away; you will, anyhow.</em></blockquote>
As the years passed and systems grew in size and complexity it became apparent that building a "throw away" as not the most efficient approach. In the 20th anniversary edition of his same book, <em>Brooks states that developing a throwaway version is not as efficient as iterative approaches to software development</em>.<br />
In Extreme Programming Explained Second Edition, Kent Beck states:<br />
<blockquote dir="ltr" style="margin-right: 0px;">
<em>"Defect Cost Increase is the second principle applied to XP to increase the cost-effectiveness of testing. DCI is one of the few empirically verified truths about software development: the sooner you find a defect, the cheaper it is to fix it."</em></blockquote>
Scouting and recon techniques are used to discover defects through experiments and to completely avoid the presence of the defect in the "real" software. These techniques work within phased or phasic development methodologies as well as within iterative methodologies and give knowledge and experience through their use.<br />
<h2>
Gaining Experience</h2>
There are many software development activities concerned with gaining experience. Some of these activities include creating proofs of concept, prototyping, and experimenting. I will refer to all of these activities as experiments.<br />
How much effort should be placed in an experiment? Enough to gain the experience needed to get you to the next step.<br />
<h2>
Software Scouting</h2>
“Scouting” will be the metaphor. During the exploration of the American frontier, scouts were sent out ahead of the company to determine the safest path through unknown and hostile territory. Through software “scouting missions” one can save time and money, and reduce the risks to the company.<br />
<br />
Brooks’ first statement concerning building a "throw away" is akin to exploring the entire route first and then moving the company. His revised statement concerning iterative development is akin to scouting out a few hours (or days) ahead and returning to guide the company. This pattern of short scouting trips would continually repeat, making the technique both iterative and incremental. Through the scouting metaphor you can gain a certain feel for why building a "throw away" version is more costly than iterative development.<br />
<h2>
Scouting Tools</h2>
There are many ways to explore the unknown. These activities have many similarities. One of the key differentiators is the stage of software development in which the activity occurs. Following various "tools" for scouting are defined and the stage in which they are typically used is specified.<br />
A <strong>"Proof of Concept"</strong> occurs after a solution has been conceptualized. Investigation is needed to gain confidence and verify the viability of the solution.<br />
<br />
A<strong> "Prototype"</strong> is made after a design has been made. Investigation is needed to validate that the result of the design solves the problem. In software prototyping development activities are scaled back. In engineering prototypes may be scaled functioning models. In software there is no physical dimension so development activities are scaled back which include minimal effort for robustness and usually only implementing the “happy path” of the functionality. Also techniques to reduce coupling are skipped and cohesion is ignored as much as possible (Even though these activities are skipped the experience of prototyping bring to light how the software components should be coupled and an overall domain definition emerges that allows for better cohesion).<br />
Ed Mauldin explains prototyping as thus:<br />
<blockquote dir="ltr" style="margin-right: 0px;">
<em>“Prototyping is probably the oldest method of design. It is typically defined as the use of a physical model of a design, as differentiated from an analytical or graphic model. It is used to test physically the essential aspects of a design before closing the design process (e.g., completion and release of drawings, beginning reliability testing, etc.). Prototypes may vary from static "mockups" of tape, cardboard, and styrofoam, which optimize physical interfaces with operators or other systems, to actual functioning machines or electronic devices. They may be full or sub-scale, depending on the particular element being evaluated. In all cases, prototypes are characterized by low investment in tooling and ease of change.”</em></blockquote>
<br />
An <strong>"Experiment"</strong> occurs after software modules have been developed. Investigation into their behavior under varied conditions is needed. An experiment is conducted to observe the behavior.<br />
A "<strong>Mock Object</strong>" is created during software implementation. Components have been developed and investigation into their behavior needs to be done. To isolate these components from the effects of other components the other components are replaced with "mocks" that have simple and specific behavior.<br />
A "<strong>Driver</strong>" is created during software implementation. Components have been developed and investigation into their interfaces and usability need to occur. A driver is developed to interface with and drive the component. The interfaces or entry points of the components are confirmed correct and the pre-conditions of the components are exercised. The driver can validate the post-conditions of the component as well.<br />
A <strong>"Stub"</strong> is created during software implementation. Functionality has been developed and investigation of the code paths needs to occur. Called interfaces are developed with the simplest means in order to return specific results and exercise the code paths of the caller. These simple interface implementations are stubs.<br />
A <strong>"Simulation"</strong> is typically created after the system is implemented. A deliverable needs to be tested in various environments and conditions. A simulation of an environment is developed and it is used for testing. Common examples are simulated users, simulated load, simulated outages, and such.<br />
<h2>
When to Scout</h2>
Remember, scouting activities address the issue of gaining experience in unknown territory. These activities are not necessary when experience is present. Simply said, “If you know how to do the job, then do it!”<br />
<br />
When one is in unknown territory scout ahead for information, then come back and apply the knowledge gained. Have enough discipline not to get distracted by the sights along the way. Stay focused, travel light, and get back to camp as quickly as possible.<br />
<br />
Can you afford not to scout ahead? The answer to this question only comes at the end of the journey. Did you make it to your destination or not?<br />
<h2>
Scouting for Phasic Methodologies</h2>
One reason that experiments work is because they address issues and concerns in context and as they occur. It is a "learn as you" go approach. Below are some scenarios in which scouting can be used in a traditional phased or phasic methodologies.<br />
<blockquote dir="ltr" style="margin-right: 0px;">
<h3>
Phase 1: Analysis and Requirements.</h3>
• Paper prototypes of the user interface.<br />
• Proof-of-concept of a requirement (i.e. the database must support 500 simultaneous connections).<br />
<h3>
Phase 2: Design.</h3>
• Refined paper prototypes of the user interface. Paper models of the architecture and model (i.e. UML).<br />
<h3>
Phase 3: Implementation.</h3>
• Develop an experiment for the “happy path” to discover boundaries and interfaces.<br />
• Create prototypes ahead of implementing frameworks so that the framework's approach can be reviewed.<br />
<h3>
Phase 4: Testing.</h3>
• Create experiments to test scenarios.<br />
• Create testing harnesses that allow for proxy users (a proxy user can be a user simulated by a computer program).<br />
• Simulate extreme conditions such as system load.<br />
(Testing is scouting ahead of the user to make sure the user’s experience will be a good one.)</blockquote>
<h2>
Scouting for Iterative Methodologies</h2>
<blockquote dir="ltr" style="margin-right: 0px;">
<h3>
User Stories</h3>
<ul>
<li>Create a proof of concept to verify the User has conveyed their desires.</li>
</ul>
<h3>
Project Planning</h3>
<ul>
<li>If the user story involves a User Interface, create paper prototypes of the interface to stimulate user input and direction.</li>
</ul>
<h3>
Release Planning</h3>
<ul>
<li>Create a prototype to identify dependencies to facilitate iteration planning.</li>
</ul>
<h3>
Iteration Planning</h3>
<ul>
<li>Create design prototypes using a modeling language such as UML.</li>
</ul>
<h3>
Iteration</h3>
<ul>
<li>Create stubs, drivers, and mock objects to increase confidence in the behavior of isolated units.</li>
<li>Create an experiment to observe object behavior.</li>
<li>Create a simulation to test things like performance under a heavy load.</li>
</ul>
</blockquote>
<div dir="ltr">
This list is supposed to be thought provoking, not complete. The idea behind scouting is to perform some scouting activity when faced with the unknown. When doing experiments in conjunction with an iterative development methodology the experiments are "lighter" than they would be in a phasic development methodology if the customer/user is taking an active role. With the customer present one can prototype a user interface with a white board and some drawings. If the customer is not present then a prototype for a user interface is usually mocked up with some kind of computer aided drawing package or even a "quick and dirty" user interface is developed with a GUI building tool or scripting language.</div>
<h2>
Benefits of Scouting</h2>
<ol>
<li>Scouting brings light to a situation. Through scouting activities estimations become more accurate. The accuracy comes from the application of the experience, not from an improved ability to predict the future.</li>
<li>Scouting reduces coupling and improves cohesion. When writing software in the light of experience, the coupling between objects is reduced and the experience unifies the system's terms and metaphors which increase cohesion.</li>
<li>Scouting builds trust and confidence by eliminating incorrect notions and avoiding drastic changes in design and implementation.</li>
</ol>
<h2>
Risks of Software Scouting</h2>
<ol>
<li>Is management mature enough to allow the proper use of an experiment and not try to “ship” the prototype and undermine the effort?</li>
<li>Is development mature enough to refrain from features creeping into the product because the experiment revealed something interesting?</li>
</ol>
<h2>
Project Management Ensures Adequate Software Recon</h2>
Project Management should scout and see if their development environment can support activities that rapidly gain experience. Probing questions include:<br />
<ul>
<li>Are the software developers aware of all of the activities that can lead to experience?</li>
<li>Are the stakeholders aware of the benefits of prototypes and experiments?</li>
<li>Is everyone aware of the risks of not doing recon and the risks of doing recon? Remember, one of the risks of a prototype is that sometimes people try to ship it!</li>
</ul>
An interesting exercise would be to listen for concerns expressed by developers and ask them what activity would address their concern. Some concerns expressed by developers that can be addressed through recon are:<br />
<ul>
<li>“If I just had time to write this right”</li>
<li>“I don’t think we know how difficult this is going to be”</li>
<li>“I really don’t have any idea how long this is going to take”</li>
</ul>
When a concern is expressed ask the developer what they would do to address it. Listen for solutions that bring experience and shed light.<br />
<h2>
Conclusion</h2>
Experience is key to writing good software. The sooner you discover a problem and correctly fix the problem the cheaper it is. Scouting ahead in software by using prototypes and experiments is a great way to discover the right path without risking the entire company to the unknown.Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-33064658732851108472016-07-15T13:59:00.001-07:002016-07-15T14:10:20.138-07:00Design By UseCheck out my other blog:<br />
<a href="http://mavericksoftwaredevelopment.blogspot.com/2012/05/maverick-software-development-model.html">Maverick Software Development</a><br />
<h1>
<br /></h1>
<h1>
"Design By Use" Development</h1>
by Geoffrey Slinker<br />
version 1.6<br />
March 25, 2006<br />
April 22, 2005<br />
July 1, 2005<br />
July 25, 2005<br />
August 23, 2005<br />
<table id="Table1" style="width: 100%px;"><tbody>
<tr align="left"><td><br /></td></tr>
<tr><td>Maverick Development</td></tr>
</tbody></table>
<h2>
Abstract</h2>
"Design by Use" development (DBU) improves team resource utilization, software design, software quality, and software maintenance through a set of proven industry methods that have been shown to work together synergistically.<br />
<br />
<h2>
Introduction</h2>
Are you concerned with keeping your development staffed adequately tasked? Would you like to improve design quality by reducing coupling, improving cohesion, and communicating the domain model? Is the quality of your software important? Do you maximize the R.O.I. of your software by using the software for as many years as possible? If you answered no to any of these questions are you from another planet?<br />
<br />
As part of my career I have specialized in the rendering of concise solutions to problems. Whether the problem was to be solved with code or with a methodology I have always strived to take the problem that was presented, boil it down to the essence, and provide a solution. I have studied software engineering processes now for over 20 years. I have distilled the essence of what I feel are the most useful methods to use as a foundation to build a process that is efficient and improving.<br />
<br />
I have recently thrown all of the traditional methodologies along with agile methodologies that I know into my soup pan and turned up the heat! Then I took the results and have been experimenting with them. It is like a soup that has been cooked in a big pot. You will taste all of the different ingredients if you try or you can ignore the ingredients and just enjoy the combined flavor.<br />
<br />
This paper presents a methodology for development that can work as a subcomponent of any encompassing methodology and deliver results in the areas mentioned in the abstract.<br />
<h2>
Executive Summary</h2>
Design by Use (DBU) follows the basic steps:<br />
1) Create High Level Design<br />
2) Identify systems and subsystems<br />
3) Identify messages or calls between systems and subsystems<br />
4) Use theses identified messages or calls to specify to each team what they should code and how the message will be made (the message/method signature).<br />
<br />
For example: There are two subsystems identified, S1, and S2. There are two teams, T1 and T2. T1 is to write S1 and T2 is to write S2.<br />
S1 calls into S2, let's suppose the message is GetStuffFromS2.<br />
Team 1 writes an Usage Example:<br />
<pre style="background-color: #fbedbb; font-family: "Courier New", Courier, mono; font-size: 9pt; font-stretch: normal; padding: 7pt; width: 1518px;">void Main()
{
MyData data = GetStuffFromS2(1);
assert(data.value == 3);
}
</pre>
<br />
Team 1 gives this Usage Example to Team 2. T2 uses this to direct what they will develop and the order of development will natually flow from this point. So T2 implements GetStuffFromS2 in their subsystem S2 and they notify T1 when it is available (or if they are using unit tests they will know GetSTuffFromS2 is available when the build light goes green for that test).<br />
S1 is immediately integrated with S2 and even better, it is integrated in a great way, the way the user wants to use the system.<br />
DBU is beyond Test Driven Development (TDD) and Design by Contract (DbC). DBU is concerned with large software systems, multiple teams, coordination, and integration. TDD is a code design activity. DbC is a contract driven process based around invariants, pre-conditions, and post-conditions.<br />
<br />
<h2>
The Approach</h2>
The "Why":<br />
The problem is keeping all software development teams working and not waiting.<br />
The "When":<br />
When a large software system is being developed with many systems and subsystems and each of these is developed by different teams.<br />
The "How":<br />
The high level design of the system is done with any method that the company agrees upon. A custom diagramming language such as a simplified UML works fine. Subsystems are identified and teams are assigned to each subsystem.<span style="text-decoration: underline;">The data flows, invocations, calls, dependencies, or whatever you want to call them are identified at the subsystem boundaries.</span> For example, "My subscription subsystem will need to ask the pricing subsystem for a price given a product Id."<br />
<br />
At this point the development pump must be primed. All of the teams have their requirements. It doesn't matter if you use Use Cases or User Stories or another way to specify requirements. In an agile methodology this would be one of the last activities of Release Planning. The teams meet together as one and the functionality that will be delivered during this release is decided upon. Each system and subsystem that are participating in this release are identified. If there are systems that are not part of this release the teams responsible for them will not be needed and can work on other systems. Each call into an external system or subsystem that had been identified are listed. <u>The "caller" starts out by writing a usage example.</u> <span style="text-decoration: underline;">The usage examples are created for the calls identified from the high level design (calls that cross system boundaries)</span> . The usage examples that call into subsystems other than your own are delivered to the proper team. In all software development there are the upstream/downstream situations. (I do not go into the perils of being downstream in this paper.) <span style="text-decoration: underline;">All of the usage examples will be used to drive the design and development of what's inside a subsystem. This is the low-level design (code) and includes the details not covered in the high-level design (possibly UML).</span><br />
<br />
<span style="text-decoration: underline;">When all of the usage examples for the subsystem boundaries are identified that can be the teams can coordinate and prioritize the remaining development tasks.</span> This gives a clear picture of who is doing what and how they should do it. There is no waiting because the usage example has with it sample data to drive the call. <span style="text-decoration: underline;">Therefore no one is waiting for someone upstream to finally call their code.</span><br />
<br />
<span style="text-decoration: underline;">The usage examples test post conditions after the call into the subsystem. The implementation in the subsystem checks preconditions, invariants, and post conditions.</span> If you taste the flavor of design by contract in this soup you are correct.<br />
<br style="text-decoration: underline;" />
<span style="text-decoration: underline;">From what has been stated so far in the DBU approach the design has presented the overall domain, has identified sub-domains, has exposed the boundaries and entry points, and has allowed for efficient use of resources and scheduling.</span><br />
<br />
Quality is improved through the approach as thus far stated. <span style="text-decoration: underline;">By having usage examples that drive development integration has already been addressed.</span> Instead of "integrate often" this approach is "integrate immediately". As soon as a component is finished and satisfies the usage example it can be used by consumers. <span style="text-decoration: underline;">Through this approach the design is very cohesive because sufficient consideration was given to the domain model and the boundary points.</span> The idea that cohesive designs and correct models just emerge from some primordial ooze is a misunderstanding. Instead it comes from the application of knowledge, consideration, experimentation, and application. This approach uses these four factors (knowledge, consideration, experimentation, and application) continuously.<br />
<br />
<span style="text-decoration: underline;">With the usage examples defined and expectations set there is no need for teams to reinvent the wheel.</span> To often teams will not use others code because the quality is suspect or the delivery date is unknown or the solution is a near fit but not a good fit. Eliminating these concerns is just as much a social problem as well as a procedural one. The approach specified here addresses the procedure.<br />
<br />
So far improvements in resource utilization, design, and quality have been described. <span style="text-decoration: underline;">Finally this approach improves the R.O.I. through facilitating software maintenance.</span> By running the usage examples a developer can isolate a piece of code and step through it to understand a legacy system. Often documentation is lost or out of synchronization with the software and a developer just wants to know what the system currently does. When modifying an existing system it is essential to know that changes have not affected the system in undesired ways. <span style="text-decoration: underline;">By running the usage examples in the role of a regression test the changes can be verified that the effects of the change are isolated to the desired areas.</span> Since each system call into another system is specified the designer's and programmer's intent is specified. This specification can be used to replace entire systems and subsystems. Suppose we want to replace the pricing subsystem our subscription subsystem uses. The usage examples shows exactly where to make the incision.<br />
<h2>
Summary</h2>
<br />
<div style="margin-left: 40px;">
1) <span style="font-weight: bold;">Improves team resource utilization</span><br />
<div style="margin-left: 40px;">
a. Through specifying interfaces through usage example one team can clearly specify to another team the functionality that is desired. This is immediate integration. Through this there is less rework during integration that traditionally would come at the end of the development phase.</div>
2) <span style="font-weight: bold;">Improves quality</span><br />
<div style="margin-left: 40px;">
a. Eliminates issues with late integration<br />
b. Builds confidence in subsystems and reduces "silo-ing" and duplicated code.</div>
3) <span style="font-weight: bold;">Improves design</span><br />
<div style="margin-left: 40px;">
a. Rapidly defines interfaces and exposed entry points.<br />
b. Reduces coupling.<br />
c. Increases cohesion.</div>
<div style="margin-left: 80px;">
i. through communication<br />
ii. through the dissemination of domain concepts<br />
iii. through the unification of domain models</div>
4) <span style="font-weight: bold;">Improves software maintenance</span><br />
<div style="margin-left: 40px;">
a. By running the usage examples as a regression test one can step through code that is not documented or that is not behaving according to documentation.<br />
b. Usage examples are ran after every modification (small sets of changes) to verify that the changes have not caused problems because of unknown side effects and couplings.</div>
</div>
<h2>
Conclusion</h2>
"Design by Use" development (DBU) improves team resource utilization, software design, software quality, and software maintenance through a set of proven industry methods that have been shown to work together synergistically.<br />
<br />
Complex software with many systems and subsystems which are developed by several teams of developers is difficult to schedule the order each part will be developed. Integration is often done late. Immediate integration is the key activity.<br />
To flesh out more of the entire process please read "Reporting for Accountability".Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-44889814326258953002016-04-15T10:01:00.001-07:002016-04-15T10:02:33.498-07:00Java 8 java.time LENIENT date parsingI was porting some Java code that uses Joda Time to the new Java 8 Time package. I needed a way to parse a date of the format "YYYY-MM-DD" and be lenient, specifically on leap year date mistakes.<br />
<br />
I also need this to be a hash of the day of the year, so that March 1, 2000 (a leap year) and March 1, 2001 (not a leap year) hash to the same value.<br />
<br />
They key piece of code is this:<br />
<pre style="background-color: white; color: black; font-family: 'Consolas'; font-size: 10.5pt;">DateTimeFormatter formatter = DateTimeFormatter.<span style="color: #660e7a; font-style: italic; font-weight: bold;">ISO_LOCAL_DATE</span>.withResolverStyle(ResolverStyle.<span style="color: #660e7a; font-style: italic; font-weight: bold;">LENIENT</span>);</pre>
<pre style="background-color: white; color: black; font-family: 'Consolas'; font-size: 10.5pt;"> </pre>
<pre style="background-color: white; color: black; font-family: 'Consolas'; font-size: 10.5pt;">Notice this: ResolverStyle.<span style="color: #660e7a; font-style: italic; font-weight: bold;">LENIENT</span></pre>
<pre style="background-color: white; color: black; font-family: 'Consolas'; font-size: 10.5pt;"> </pre>
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public class DateUtils
{
//This is a hash of the day of the year.
public static int hashDayOfYear(String stringDate)
{
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE.withResolverStyle(ResolverStyle.LENIENT);
LocalDate date = LocalDate.parse(stringDate, formatter);
int dayOfYear = date.getDayOfYear();
//Leap year stuff
boolean isLeap = Year.isLeap(date.getYear());
//February 28th is the 59th day of the year.
if( isLeap )
{
if(dayOfYear == 60)
{
//This allows for exact matching of dates but interfears with range matching
dayOfYear = 366;
}
else if (dayOfYear > 59)
{
dayOfYear--;
}
}
return dayOfYear;
}
}
public class DateUtilsTest
{
@Test
public void testOne()
{
//Feb 28 of a leap year
String date = "2000-02-28"
int dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 59;
//Feb 29 of leap year maps to 366
date = "2000-02-29"
dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 366;
//Feb 29, but not leap year, needs to be lenient and map to March 1
date = "2001-02-29"
dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 60;
//Feb 30 of a leap year, needs to be lenient and map to March 1
date = "2000-2-30";
dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 60;
}
}
</code></pre>
Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-8479734929207919172016-02-11T10:49:00.000-08:002017-01-24T09:01:30.918-08:00Personalized Bash Shell, VIM, and other settings...I want to capture my very simple, yet I think clean, settings I like to use.<br />
<br />
Here is my .bashrc<br />
<br />
---------------------------------------------------------<br />
<span style="font-family: "courier new" , "courier" , monospace;"># .bashrc<br /><br /># Source global definitions<br />if [ -f /etc/bashrc ]; then<br /> . /etc/bashrc<br />fi<br /><br /># User specific aliases and functions<br />LS_COLORS='di=1;33' ; export LS_COLORS<br /><br />PROMPT_DIRTRIM=3<br />export PROMPT_DIRTRIM<br /><br />PS1="[\u \w]\$"</span><br />
---------------------------------------------------------<br />
<br />
This sets some colors and makes the prompt show the directories in a way that I find useful because I am always deep into the directory structure.<br />
<br />
[user1 ~/.../opt/solr-5.4.1/example]$<br />
<br />
Here is my .vimrc<br />
<br />
---------------------------------------------------------<br />
<span style="font-family: "courier new" , "courier" , monospace;">colorscheme desert</span><br />
---------------------------------------------------------<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-19787899392548706802016-02-11T10:40:00.002-08:002016-02-11T10:40:45.159-08:00BASH Script to remove trailing back slashI was working with a script that was called in an RPM build (in the SPEC file). I passed a directory as a the first variable to the script. The directory ended with a back slash. I needed to remove that backslash since all of my variables started with a backslash.<br />
<br />
RPM_BUILD_DIR=""<br />if [ -n "$1" ]<br />then<br /> RPM_BUILD_DIR=${1%/} #REMOVE TRAILING /<br />fi<br />
<br />
So, the bash script checks to see if we have a parameter in the first position and if so remove the trailing backslash.<br />
<br />
If the directory string was "/usr/local/bin/" the results are:<br />
"/usr/local/bin"<br />
<br />
I searched for examples to do this and they all seemed overly complex. Maybe this one is too simple for some situations, but it works for my needs.Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-70285737861292334262016-02-04T16:12:00.002-08:002016-02-05T08:23:58.463-08:00BASH Script to Manipulate IP Addresses and Port NumbersThis post is just a place to store some bash script for reference. I don't work in bash often enough to remember how things work so I need to make little snippets and such for reference. I do the same thing for regex and sql.<br />
<br />
Here are some of the things I do to manipulate ip addresses in bash scripts. Since I work a lot with Solr, specifying zookeeper machines and lists of servers for SolrCloud I am always manipulating IP addresses.<br />
<br />
<span style="font-size: small;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="font-family: "courier new" , "courier" , monospace;">#!/bin/bash<br />#set -x<br />echo -----------------BEGIN------------------------<br />servers="10.1.1.1:8080,10.1.1.2:8080,10.1.1.3:8080"<br />declare -a serversArray=("10.1.1.1:8080" "10.1.1.2:8080" "10.1.1.3:8080")<br /><br />echo servers:" "${servers}<br />echo serversArray:" "${serversArray[@]}<br /><br />echo ----------------------------------------------<br /><br />#use for loop to convert the serversArray to a comma seperated string<br />#Since arrays can be sparse, that is their indices do not have to be sequential<br />#get the indices as an array and iterate over the indices.<br />result1=<br />arrayIndices=(${!serversArray[*]})<br />for index in ${arrayIndices[*]}<br />{<br /> result1=${result1}${serversArray[$index]}<br /> if [ $index != ${arrayIndices[*]: -1} ] #This gets the last element of an array<br /> then<br /> result1=$result1, #only append comma if this isn't the last entry<br /> fi<br />}<br />echo Array to comma seperated string using for loop:" "${result1}<br /><br />#convert array to comma delimited string using character substitution<br />cds=${serversArray[@]};<br />cds=${cds// /,}<br />echo Array to comma seperated string using character substitution:" "${cds}<br /><br />#convert the comma delimited string into an array<br />atemp=($(IFS=','; x=($servers); echo ${x[@]}))<br />echo Comma delimited string to array:" "${atemp[@]}<br />for a in "${atemp[@]}"<br />{<br /> echo []"${a}"<br />}<br />echo ----------------------------------------------<br /><br />#remove the port from the servers, only works for port numbers of 4 digits<br />echo Remove Port Numbers from IP Addresses<br />servers2=${servers//:????/}<br />echo ${servers2}<br /><br />#now use sed to remove port numbers from servers<br />echo ${servers} | sed -e "s/:[0-9]*//g"<br /><br />echo ----------------------------------------------<br />#create an ip address with incrementing port numbers<br />echo Creat ip addresses with incrementing port numbers<br />echo 10.1.1.0:{10001,10002,10003,10004}<br />echo 10.2.2.2:{10001..10004}<br />echo 10.1.1.0:{10001,10002,10003,10004},<br />#capture echo into var and strip the trailing comma<br />ips=$(echo 10.1.1.0:{10001,10002,10003,10004},)<br />ips=${ips/%,/}<br />echo ${ips}<br /><br /></span></span></span><br />
<br />
<br />
<br />
<br />
<br />
Here is the output:<br />
-----------------BEGIN------------------------<br />servers: 10.1.1.1:8080,10.1.1.2:8080,10.1.1.3:8080<br />serversArray: 10.1.1.1:8080 10.1.1.2:8080 10.1.1.3:8080<br />----------------------------------------------<br />Array to comma seperated string using for loop: 10.1.1.1:8080,10.1.1.2:8080,10.1.1.3:8080<br />Array to comma seperated string using character substitution: 10.1.1.1:8080,10.1.1.2:8080,10.1.1.3:8080<br />Comma delimited string to array: 10.1.1.1:8080 10.1.1.2:8080 10.1.1.3:8080<br />[]10.1.1.1:8080<br />[]10.1.1.2:8080<br />[]10.1.1.3:8080<br />----------------------------------------------<br />Remove Port Numbers from IP Addresses<br />10.1.1.1,10.1.1.2,10.1.1.3<br />10.1.1.1,10.1.1.2,10.1.1.3<br />----------------------------------------------<br />Creat ip addresses with incrementing port numbers<br />10.1.1.0:10001 10.1.1.0:10002 10.1.1.0:10003 10.1.1.0:10004<br />10.2.2.2:10001 10.2.2.2:10002 10.2.2.2:10003 10.2.2.2:10004<br />10.1.1.0:10001, 10.1.1.0:10002, 10.1.1.0:10003, 10.1.1.0:10004,<br />10.1.1.0:10001, 10.1.1.0:10002, 10.1.1.0:10003, 10.1.1.0:10004<br />Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-81770650264392233942016-01-25T16:26:00.000-08:002016-01-28T12:43:36.671-08:00Introduction to Solr 5 SolrCloud<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;"></b><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 3pt; margin-top: 0pt;">
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 34.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Introduction to Solr 5 SolrCloud</span></b></div>
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;">
</b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Collection - a complete logical index.</span></b></div>
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;">
</b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Collections are made up of one or more shards and a replication factor.</span></b></div>
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;">
</b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Shards have one or more replicas as defined by the replication factor.</span></b></div>
<b id="docs-internal-guid-376f88a5-8945-1338-8f7e-47f84ce40a5f" style="font-weight: normal;">
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Each replica is a core.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://wiki.apache.org/solr/SolrTerminology" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://wiki.apache.org/solr/SolrTerminology</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://cwiki.apache.org/confluence/display/solr/How+SolrCloud+Works" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://cwiki.apache.org/confluence/display/solr/How+SolrCloud+Works</span></a></div>
<br /><br /><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 26.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Special Note</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The term “replica” in SolrCloud has caused me confusion. This paper attempts to clarify this issue.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Here are my words trying to clarify the above terms:</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Collection - a complete logical index.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Collections are made up of one or more shards and a replication factor.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">There is always at least one instance of a Shard (this is a replication factor of one). There can be more than one instance of a Shard for redundancy ( a replication factor greater than one).</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">An instance of a shard is called a core.</span></div>
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 26.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Collection</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A SolrCloud Collection is a complete logical index.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A Collection can be divided into shards. This allows the data to be distributed. </span></div>
<br /><br /><br /><img height="364" src="https://lh3.googleusercontent.com/fbI5fykKQJ7vzakGUogSqjFifL2jjhrAWeqhq81WpZdjMSXMlSB5XA55OK9b6oRs8yBGTPoupuDji5I64LZ6cCPb82jtBqLfr0coGGcJ49f2xg2-lZmKRDIy3TSY1LNWmgFXVs9W" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="364" /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The above picture represents a Collection with one shard and a replication factor of one. This results into a collection with one shard and </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">that one shard IS the one replica</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. Here in lies the confusion when trying to describe SolrCloud. When I read the word replica I immediately imagine an original and a copy, an original and a replica.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Since there is always at least one replica it can be confusing terminology. When I first started trying to build a mental picture of SolrCloud I erroneously started with the idea that there was a master with replicas and therefore a replication factor of one would be a master and a replica. But that is not the case. What I thought of as a master is in reality “replica one”. Therefore, if you want your original index with one backup / failover copy what you need to say is “I want a replication factor of two.”</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Therefore I feel the best way to describe it is like this:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The above picture represents a Collection with one shard and a replication factor of one. This results into a collection with one shard and </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">that one shard is the only copy / instance of the data. Each instance of a shard is called a Core.</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></div>
<br /><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 26.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Shard</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A Shard is a division of a Collection (complete logical index). Therefore a Shard is a portion or slice of a Collection (complete logical index).</span></div>
<br /><img height="387" src="https://lh4.googleusercontent.com/hDp-vxQwENn3TgQkeFv5Ek1OhGQFIypWDuy6DEmnwAqLpZS10x6OUW14ZsCooiRMVq8Tr-ON92_u9hlk8qQJ9TKpV2v3lsbR3ePscOWJCwLAIFWk4QN5np31f4pZiC8THHOl59KN" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="193" /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Above represents a Collection sliced or divided into eight Shards.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Why would you want more than one shard? One reason would be if the total size of the collection is too large to fit on one computer.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In a Collection with one Shard all of the data will be in that single shard. For example, if you are doing a dictionary then with one shard the words from A to Z all go into the single shard. If you have two shards then the data for shard one could be A to M and the data for shard two could be N to Z.</span></div>
<br /><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 26.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Replica</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Shards can be duplicated by using a replication factor. The replication factor specifies how many instances of each shard should exist. Each instance of a shard is called a Core. The confusion lies in that a Core is also called a Replica.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">From the Solr documentation:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break" /></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">“</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Collections can be divided into shards. Each </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">shard</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> can exist in multiple copies; these copies of the same shard are called replicas. One of the replicas within a shard is the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">leader</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, designated by a leader-election process. Each </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">replica</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> is a physical index, so one replica corresponds to one core.</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">”</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The replication factor multiplied by the number of shards results in the total number instances of shards or better said </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">the replication factor multiplied by the number of shards results in the total number of cores</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Shard instances show up in the Solr dashboard as “Cores”. In SolrCloud a Replica and a Core are the same thing.</span></div>
<br /><img height="377" src="https://lh3.googleusercontent.com/wuoxmLPsbAOdra-hqSYC_oDDs9Qi8qyLJBEb_DJboZrDpZbFjiwBXEeTD6bNdnq7mn-UxfIJo_C4xnLUtBZCB4QsSefCRqoAj2U-Ms31YWBHcikb18ifKiE-BC1soQBw7GBb2WXB" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="237" /><br /><img height="163" src="https://lh4.googleusercontent.com/jDB0OGM8jgOZ5t4PqFsp0BeAjFgzYv8Sor2-5iv4tAm6DLNUqBsZr8JDkEyDjD--IlXhJfUOYKSpzzoxRhyYXxlcF4tHfi1mJNqYOO0ev2W5yyYpSi3wr60duElq1cv7ZQ_bZi-u" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="478" /><br /><img height="424" src="https://lh5.googleusercontent.com/7WZGfX76NZUXS5Q1Ah0LQ1rcoYj-aoerEBfpyENKRrsYjW43i9Ev38xrq1ua2xrOb-0qn2aYAblHoEwJrKwR6hSg0p8qmcSeIY4oJzfgzpm2PTaHNGzWUJWc_4fV2jZBtx4zr_YI" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="256" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Above the picture shows the “gettingstarted” collection with two shards and a replication factor of one which results in two shards each with one core / replica. Since there are two shards, each with one core / replica, there are a total of two cores / replicas. That is why you see two “cores” in the Solr Dashboard.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">It is interesting to see the state.json for the “gettingstarted” collection.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"gettingstarted": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"maxShardsPerNode": "2",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"router": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"name": "compositeId"</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">},</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"replicationFactor": "1",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"autoAddReplicas": "false",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"shards": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"shard1"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">: {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"range": "80000000-ffffffff",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"state": "active",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">replicas</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">core_node2</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"state": "active",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">core</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">": "gettingstarted_shard1_replica1",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"node_name": "10.211.1.126:8983_solr",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"base_url": "http://10.211.1.126:8983/solr",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"leader": "true"</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">},</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"shard2"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">: {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"range": "0-7fffffff",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"state": "active",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">replicas</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">core_node1</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">": {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"state": "active",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">core</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">": "gettingstarted_shard2_replica1",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"node_name": "10.211.1.126:8983_solr",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"base_url": "http://10.211.1.126:8983/solr",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"leader": "true"</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<br /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Below is a collection that has eight shards with a replication factor of three. What is the total number of cores / replicas? There are 24 cores / replicas.</span></div>
<br /><br /><img height="345" src="https://lh6.googleusercontent.com/ZhP2wLwCdA0FeGthP7RX7iNaqySMJp0vWf_-O5LkDtLA7RyIcJ4lYSVSqokC6GTdIp8w1yTXT4RUN3b5wy_Ov3VOyya6R35SU0e2lX6VzQGx0NirOHiJLlmI0eknLbzjQ4xRydlF" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="345" /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Just remember if you prefer to use the term Replica instead of the term Core that “replica 1” is just the first instantiation of a shard and “replica 2” is the second instantiation of the shard.</span></div>
<br /><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 26.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Starting Solr </span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Please be familiar with “Getting Started with SolrCloud”.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://cwiki.apache.org/confluence/display/solr/Getting+Started+with+SolrCloud" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://cwiki.apache.org/confluence/display/solr/Getting+Started+with+SolrCloud</span></a></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">What I am about to describe are not steps to take Solr into production. I am not setting up linux users and permissions, this is just quick and dirty and I run as the root user doing it.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Download and untar/ unpackage Solr. Follow the steps found in the link above “Getting Started with SolrCloud” or just run this:</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">$ bin/solr -e cloud -noprompt</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Point a webrowser to:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="http://localhost:8983/solr" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">http://localhost:8983/solr</span></a></div>
<br /><br /><br /><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 18pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 21.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Zookeeper</span></h2>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">If everything is running correctly then we are going to check and see what is in zookeeper. If it isn’t running, delete everything and start over. If you used the -noprompt command to start solr, follow the steps on the webpage and include the -V option with the command.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The first way to examine part of what is in zookeeper is through the Solr Dashboard.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Click on the left panel as shown here:</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="621" src="https://lh6.googleusercontent.com/iajo_Y2860xxaGJo0xezk7X4XPZMMksk76yooSCHZIhNt04PmhS-VDnlgEeE-M9E_bcdphMH7iRNb0Sm3yZ1MKgjPWalFOM7o-cini_HuR_K5Vshy2oCXw5Iu_ubFj8vT-E5gEPj" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="438" /></span></div>
<br /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In Solr’s install directory, go to:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">$ cd server/scripts/cloud-scripts</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Run:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">$ ./zkcli.sh -zkhost localhost:9983 -cmd list | less</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You will see how the Solr Dashboard is showing what is in zookeeper.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now download zookeeper and install it.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Got to the zookeeper bin directory and run:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">$ ./zkCli.sh -server localHost:9983</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Just because Solr is running the embedded zookeeper doesn’t mean you can’t connect to it.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Note that zkCli.sh is completely different than the shell found in Solr with the name zkcli.sh. </span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">At the zk prompt to do following:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[zk: localHost:9983(CONNECTED) 1] ls /</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You will see the following:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[configs, security.json, zookeeper, clusterstate.json, aliases.json, live_nodes, overseer, overseer_elect, collections]</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You can examine the values, for example:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">ls /live_nodes</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[10.211.1.126:8983_solr, 10.211.1.126:7574_solr]</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Why did I talk about zookeeper now? Because it is essential to understand where things are being stored and who retrieves the data.</span></div>
<br /><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 18pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 21.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Add a Node to the Cluster</span></h2>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now, install Solr on another machine. Obviously it needs to be able to see the existing Solr machines on the network.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I decided to install Solr on a Windows machine since the currently running Solr is on a CentOS machine.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I started the Command Prompt by specifying “Run as Administrator”. At this time I am not looking for permission issues, I am avoiding them. I want to see Solr working.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">From the DOS Command Prompt while in the Solr bin directory run:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">solr.cmd start -c -z 10.211.1.126:9983</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Obviously you use the I.P. address of your machine, not mine.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The -c means start in SolrCloud mode.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The -z specifies the zookeeper. Notice it is the embedded zookeeper already running in Solr.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Back to zookeeper, from the zookeeper command prompt (the real zookeeper, the capital C zookeeper, the zkCli.sh):</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[zk: localHost:9983(CONNECTED) 3] ls /live_nodes</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[10.61.130.207:8983_solr, 10.211.1.126:8983_solr, 10.211.1.126:7574_solr]</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[zk: localHost:9983(CONNECTED) 4]</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Notice that now there is a new entry in the live nodes.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You can also see this in the Solr Dashboard of the original Solr instance.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="375" src="https://lh5.googleusercontent.com/XBGUTjoyeIX7c1dsgstqtF-8CClrxfhvSohM5LZDESwUhlkqE1PnR0qKIwnSRMOMLtsMpp12Xd2DRY_nkFFVRcFNRwTc8oVKsoAB9h7jfSyxBl8PSrMgWRjNdUC9hyLlGZ3X27A0" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<br /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now go to the Solr Dashboard of the original Solr instance, not the one you just started. Notice in the top right the link “Try New UI”.</span></div>
<br /><img height="123" src="https://lh5.googleusercontent.com/tRxT9scmxmcNVn41qy0JHLZABMFzxzB1vD6WHcR9Wy3-PqW3P_pAPA-lV2wH9Hh1v0NP0_RuLKkjIc4q_Y-rSX4lqSrvvExwSJIb1fOcDFeLQo9hG8qg5Nd9tQIMjpI3OGhhuiCd" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You will see this:</span></div>
<br /><img height="416" src="https://lh5.googleusercontent.com/Q0JDwtc_sbO4mM8JhjqoLjZLFkwdZttPPt_sSrDwWyxR-m4VgVuLdeRv3aI4TvdOxB881KHai_OmdoLicXdg6K2PJBwQqlZ7Jz_eSHNfOIYIaffwcxgQkspk2eYLLoeDkWG8PJtl" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Click on the “gettingst…” link in the middle pane.</span></div>
<br /><br /><img height="412" src="https://lh6.googleusercontent.com/wmSaYoYzLOEtNCV_1rxL-eV8cKNvf1cqmU_1RJQE-svxrDbS2WUYoCXZfVrPO9xz2pZK-V5rCbEyuemUMtGuiT-F5yLWEKuRNxye91RP_iC02-E8uMYoGptWREiGgVCvY2bksSun" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now click on the Shards on the right of the middle panel.</span></div>
<br /><br /><img height="304" src="https://lh6.googleusercontent.com/WadeKcbApvhoEBDQ_QG7lKN63HjhuhQGyvBY76jd1KxJz6IT0WeGQiC-U5_rEndBTDj3fjVqxXHTzGz6jq8ajkHiX8PU66H9x5oXhvm78CD3s9fLBo8vkuYx5en8JpA6fLxrk840" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now click “add replica” on the right for shard1.</span></div>
<br /><br /><img height="329" src="https://lh6.googleusercontent.com/c_yllLi24WIBM0U4ImhKwegLIiY1y5USn97fXmz-eRiJqu6mFfHBfi0BWifP2cmjULAamKeqfQLbctOJtLXEYLDOXST4kuecGgZYFG1i6VyUub7uR35mFLd2z1k4rBJaCS9Z3YkI" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Select the ip address of the “new” instance, the one I started on the Windows machine is the last entry, and click “Create Replica”.</span></div>
<br /><img height="324" src="https://lh4.googleusercontent.com/ZyPufoViK1MULb3tKAUO1WhBszJ2Rwp5BgJCJ4znrkEsauMSwvjiBFU-GU5C9DmCdluO-OV6SkyAMXrOj5MN9wotXY4C6sCO8Mr-7LKK6pHLNLz0SN5YbarJLBd2FQJg8AQInvwz" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now go to the Solr Dashboard of the new instance and go to the “Cloud” (click Cloud in the left panel).</span></div>
<br /><img height="380" src="https://lh4.googleusercontent.com/_cBg7GZ_nUu9e9Y-gFwKxuE5Qdq9lfcwn0B-uDzi15yPXvxWaUvgOJkxc1f3S53wfcnKPg0J-kTuPpl-hn4qobCI1lQw5_dItZEWzg1FGTbtQ1UwvezO4TBwbWLXQYM-xaMCIaQY" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Notice on the new instance that it is running and is hosting a Core / Replica of Shard 1.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">What did these actions create on the new instance?</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">D:\solr-5.2.1\server\solr\gettingstarted_shard1_replica3</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Inside of that new directory there is a core.properties file that contains this:</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">#Written by CorePropertiesLocator</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">#Wed Jan 27 17:40:26 UTC 2016</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">name=gettingstarted_shard1_replica3</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">shard=shard1</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">collection=gettingstarted</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">coreNodeName=core_node5</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">On the original instance of Solr add another replica / core for shard2 on the new Solr instance.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">When finished the SolrCloud for the gettingstarted collection should look like this:</span></div>
<br /><img height="384" src="https://lh6.googleusercontent.com/LW9XpCj6kP6x9z8PCPgcTIkUYB5hw4AMVZLu-dYhg0xKg4MuXuD84CLYjOsnKQYTnIGyf47JkFeMLdfdqVMmoTz6uNCi9GnCvDf0_8rEeMwLhpY-em8KSvxJJ2sJxAGeSwwjLk84" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 26.666666666666664px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Adding Data</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The Solr documentation instructs how to add data to the gettingstarted collection.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://cwiki.apache.org/confluence/display/solr/Post+Tool" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://cwiki.apache.org/confluence/display/solr/Post+Tool</span></a></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Before we add data we need to update the schema. The schema is stored in zookeeper and is called managed-schema. You can see it at this path in zkCli.sh (the real zookeeper shell):</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">[zk: localHost:9983(CONNECTED) 4] get /configs/gettingstarted/managed-schema</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In the Solr install directory go to example/films and read README.txt. You will see that you need to update the Solr schema. You can run the following command or go into Solr and add fields through the Solr Dashboard.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">curl http://localhost:8983/solr/films/schema -X POST -H 'Content-type:application/json' --data-binary '{</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "add-field" : {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "name":"name",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "type":"text_general",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "stored":true</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> },</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "add-field" : {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "name":"initial_release_date",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "type":"tdate",</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> "stored":true</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}'</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I updated the schema through the UI of the Solr Dashboard.</span></div>
<br /><img height="559" src="https://lh3.googleusercontent.com/qSIGV7umd-00IPknb0wrLOhyTtfCG2vyfIlSMxwYWS2y2Jd73F7AlOlpVFRK5Ixw63bU-joBwCGGtSVvYrhOLxITUHIWJ8B9Mcd8yonRf9FLj3_7fSoWt03Q4DDJjbeR6HXMAeTm" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><br /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">After updating the schema I reloaded the cores through the Solr Dashboard.</span></div>
<br /><br /><img height="295" src="https://lh6.googleusercontent.com/m6w98qApBXAovfuQ-EOFKF-8YHV5Gua9WArWN6GbYkJQkdjgK4IoUKrE0OP2__fOl5OPs2R09twpOxdNk8VFPzZ8t0ws5PrLBy5_h39TJQFdRp5dz6iOkuWY3RT6ZTPJ37IRFz7o" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">On the original (first) instance of Solr (in my case the instance running on CentOS) run the command:</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">bin/post -c gettingstarted example/films/films.json</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Next go to the Solr Dashboard of the original instance, select the gettingstartedcollection and execute the default query.</span></div>
<br /><br /><br /><img height="508" src="https://lh3.googleusercontent.com/FB-rAlhbdEo3tc9cyq0AfcDxXMu5E4nIgMp_pFQ8moI4PsePUGEpIAQ_1SVvZ-qSMkbJn2trcTSV9zvHx-1Uuq3rexVSiw5aDdIzD95MKOEJh1hC3TN7QRyylU6k7hpFLCa1oycG" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">It looks like the post put 1,100 records into the database.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">NOTE:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">If you don’t update the schema before running the post command you will call all kinds of exceptions and errors. I think this is because the post tries to auto-detect field types and update the schema at runtime and it erroneously picks the wrong field type.</span></div>
<br /><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 18pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 21.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Checking Replication</span></h2>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now I am wondering did the replication to the second instance of Solr (for me the second instance was started on Windows) actually has the data. To check this I am going to remove the cores/replicas from my first instance of Solr (running on CentOS) by removing the cores / replicas through the Solr Dashboard.</span></div>
<br /><br /><img height="384" src="https://lh4.googleusercontent.com/mmVFG-Zl_qb1T6wkQBsRqtCq-yXKW7yh2sASdhnFq2vHfst-aDqf_ZqYy0ZijuhemsE34eyWCT0NZvCExl57isCyti8-BO9_vIOLyeZvwAkbaE4eOHCayIR1_PvtFuKOA86AdW1R" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Just click the red X next to each core / replica running on the first box.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now go to the Cloud panel and see if the original box has been removed.</span></div>
<br /><br /><br /><img height="340" src="https://lh6.googleusercontent.com/slQ6U00piQlG9zvi-tPqv-KOvpmXFj5YT2IIdrKMHJpBM95vd31z1G_0YQQQ7_rDIBtjfspaNaZNNpY39ORIy2PAZOMLMeCbdIiNvgm-xNdLG4e1iJzkc27zrpO-fdyt2h75YKky" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Everything looks as expected.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now select the collection “gettingstarted” and execute the default query.</span></div>
<br /><br /><br /><img height="489" src="https://lh5.googleusercontent.com/Wx0SwirrnUzllbcfiewz6LSE2At8BCE1jJVOK16DDkjaZkM1MN8EfAF41AZORjpZ3N4ismqkSVMs12QKitTzgMjdQi6mrlrKzicTvZ-UI2oof9Wnp74LYdxLDKnGO5sqQuCAyJ2V" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /><br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">There are still 1,100 records. It looks like everything is working correctly.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Just to double check, go into the index directory and see if there are any files on the original instance.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">$cd example/cloud/node1/solr/gettingstarted_shard1_replica2/data/index</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">There are no index files, just a write.lock file left there.</span></div>
</b>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-4123960400952230312016-01-02T19:14:00.003-08:002016-01-02T19:15:36.210-08:00Objective C and JSON, Convert a subclass of NSObject with properties that are other NSObjects to JSONCheck out <a href="https://github.com/gslinker/GSObject">GSObject on GitHub</a>.<br />
<br />
I have been investigating the serialization of Objective-C classes to JSON and have found that it is not as easy as I had hoped.<br />
<br />
So, I wrote my own. Just like any good developer would do. ;-)<br />
<br />
My solution is very simple and I was surprised at how simple it could be done compared to all of the solutions that I found out there.<br />
<br />
The solution is based on these simple methods:<br />
<br />
<br />
<div class="p1">
<span class="s1">- (<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html#//apple_ref/doc/c_ref/NSDictionary"><span class="s2">NSDictionary</span></a><<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/doc/c_ref/NSString"><span class="s2">NSString</span></a> *,id> *)dictionaryWithValuesForKeys:(<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/index.html#//apple_ref/doc/c_ref/NSArray"><span class="s2">NSArray</span></a><<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/doc/c_ref/NSString"><span class="s2">NSString</span></a> *> *)keys</span></div>
<br />
<br />
<div class="p1">
<span class="s1">+ (id)JSONObjectWithData:(<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/doc/c_ref/NSData"><span class="s2">NSData</span></a> *)data options:(<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Foundation/Reference/NSJSONSerialization_Class/index.html#//apple_ref/doc/c_ref/NSJSONReadingOptions"><span class="s2">NSJSONReadingOptions</span></a>)opt error:(<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/index.html#//apple_ref/doc/c_ref/NSError"><span class="s2">NSError</span></a> * _Nullable *)error</span></div>
<br />
<br />
<div class="p1">
<span class="s1">- (id)valueForKey:(<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/doc/c_ref/NSString"><span class="s2">NSString</span></a> *)key</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">
</span></div>
<div class="p1">
<span class="s1">- (void)setValue:(id)value forKey:(<a href="file:///Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/doc/c_ref/NSString"><span class="s2">NSString</span></a> *)key</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
By overriding the valueForKey: and setValue:forKey in the new base class GSObject and then using some reflection/introspection and the dictionaryWithValuesForKeys: and JSONObjectWIthData:options:error I was able to write this simple and handy code.</div>
<div class="p1">
<br /></div>
<div class="p1">
Enjoy!</div>
<br />
<br />
# GSObject<br />
<br />
GSObject is a class that allows you to serialize to JSON or deserialize from JSON.<br />
<br />
GSObject is a subclass of NSObject.<br />
GSObject overrides valueForKey and setValue:forKey<br />
<br />
GSObject also looks for the following SELECTORs:<br />
- (NSString *) jsonValue<br />
+ (NSNumber *) initWithJsonValue : (NSString *) jsonValue<br />
<br />
These SELECTORS allow you to create subclasses or categories to control the JSON. Examples of usages would be with NSDate or NSNumber as currency.<br />
<br />
Following are some simple classes to use as an example:<br />
<br />
<br />
//<br />
// ThingOne.h<br />
// JasonStuff<br />
//<br />
// Created by Geoffrey Slinker on 12/28/15.<br />
// Copyright © 2015 Slinkworks LLC. All rights reserved.<br />
//<br />
<br />
#import <foundation oundation.h=""></foundation><br />
#import "GSObject.h"<br />
#import "ThingTwo.h"<br />
<br />
@interface ThingOne : GSObject<br />
<br />
@property (nonatomic, retain) NSString *name;<br />
@property (nonatomic, retain) ThingTwo *thingTwo;<br />
@property (nonatomic, retain) NSArray *values;<br />
@property (nonatomic, retain) NSDictionary *dict;<br />
@property int myInt;<br />
@property float myFloat;<br />
@property BOOL myBool;<br />
@property (nonatomic, retain) NSNumber* someMoney;<br />
<br />
<br />
@end<br />
<br />
-----------------------------------------------------------------------<br />
<br />
//<br />
// ThingOne.m<br />
// JasonStuff<br />
//<br />
// Created by Geoffrey Slinker on 12/28/15.<br />
// Copyright © 2015 Slinkworks LLC. All rights reserved.<br />
//<br />
<br />
#import "ThingOne.h"<br />
<br />
@implementation ThingOne<br />
<br />
@synthesize name;<br />
@synthesize thingTwo;<br />
@synthesize values;<br />
@synthesize dict;<br />
@synthesize myInt;<br />
@synthesize myFloat;<br />
@synthesize myBool;<br />
@synthesize someMoney;<br />
<br />
- (instancetype)init<br />
{<br />
self = [super init];<br />
<br />
thingTwo = [[ThingTwo alloc] init];<br />
<br />
thingTwo.stuff = @"Thing Two Stuff";<br />
thingTwo.someOtherStuff = @"Thing Two Other Stuff";<br />
NSDateFormatter *dateFormater = [[NSDateFormatter alloc]init];<br />
[dateFormater setDateFormat:@"yyyy-mm-dd"];<br />
thingTwo.someDate = [dateFormater dateFromString:@"1963-10-07"];<br />
<br />
values = [NSArray arrayWithObjects:@"Value1", @"Value2", @"Value3", nil];<br />
<br />
dict = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];<br />
<br />
myInt = 5431;<br />
myFloat = 123.456f;<br />
myBool = YES;<br />
<br />
someMoney = [NSNumber numberWithInt:503];<br />
<br />
return self;<br />
}<br />
<br />
@end<br />
<br />
-----------------------------------------------------------------------<br />
<br />
//<br />
// ThingTwo.h<br />
// JasonStuff<br />
//<br />
// Created by Geoffrey Slinker on 12/28/15.<br />
// Copyright © 2015 Slinkworks LLC. All rights reserved.<br />
//<br />
<br />
#import <foundation oundation.h=""></foundation><br />
#import "GSObject.h"<br />
<br />
@interface ThingTwo : GSObject<br />
<br />
@property (nonatomic, retain) NSString *stuff;<br />
@property (nonatomic, retain) NSString *someOtherStuff;<br />
@property (nonatomic, retain) NSDate *someDate;<br />
@property (nonatomic, retain) NSString *nullString;<br />
@property (nonatomic, retain) NSDate *nullDate;<br />
<br />
@end<br />
<br />
-----------------------------------------------------------------------<br />
<br />
//<br />
// ThingTwo.m<br />
// JasonStuff<br />
//<br />
// Created by Geoffrey Slinker on 12/28/15.<br />
// Copyright © 2015 Slinkworks LLC. All rights reserved.<br />
//<br />
<br />
#import "ThingTwo.h"<br />
<br />
@implementation ThingTwo<br />
<br />
@synthesize stuff;<br />
@synthesize someOtherStuff;<br />
@synthesize someDate;<br />
<br />
- (instancetype)init<br />
{<br />
self = [super init];<br />
<br />
someDate = [NSDate date];<br />
<br />
return self;<br />
}<br />
<br />
@end<br />
<br />
-----------------------------------------------------------------------<br />
<br />
Here is some example code on how to use it:<br />
<br />
ThingOne* object1 = [[ThingOne alloc] init];<br />
object1.name = @"John Jones";<br />
<br />
<br />
NSData* jsonData1 = [object1 toJsonDataWithOptions:NSJSONWritingPrettyPrinted];<br />
NSString *jsonString1 = [object1 toJsonStringWithOptions:NSJSONWritingPrettyPrinted];<br />
<br />
NSDictionary<nsstring id=""> *dict1 = [GSObject dictionaryWithValues:object1];</nsstring><br />
<br />
NSString *roundTripJson1 = [object1 toJsonStringWithOptions:NSJSONWritingPrettyPrinted];<br />
<br />
ThingOne *object2 = [GSObject create:[ThingOne class] fromJsonString:roundTripJson1];<br />
NSString *roundTripJson2 = [object2 toJsonStringWithOptions:NSJSONWritingPrettyPrinted];<br />
<br />
<br />
NSString *json3 = @"{\"myInt\" : 2039,\"thingTwo\" : {\"stuff\" : \"Thing Two Stuff2\",\"someOtherStuff\" : \"Thing Two Other Stuff2\"},\"name\" : \"William Smith\",\"dict\" : {\"key10\" : \"value10\",\"key20\" : \"value20\"},\"values\" : [\"ValueA\",\"ValueB\",\"ValueC\"]}";<br />
<br />
ThingOne *object3 = [GSObject create:[ThingOne class] fromJsonString:json3];<br />
NSDictionary<nsstring id=""> *dict3 = [GSObject dictionaryWithValues:object3];</nsstring><br />
NSString *roundTripJson3 = [object3 toJsonStringWithOptions:NSJSONWritingPrettyPrinted];<br />
<br />
-----------------------------------------------------------------------<br />
Here are the variables from the debugger:<br />
<br />
<br />
<br />
(lldb) po jsonString1<br />
{<br />
"values" : [<br />
"Value1",<br />
"Value2",<br />
"Value3"<br />
],<br />
"myInt" : 5431,<br />
"myFloat" : 123.456,<br />
"myBool" : true,<br />
"someMoney" : "$503.00",<br />
"thingTwo" : {<br />
"stuff" : "Thing Two Stuff",<br />
"nullDate" : null,<br />
"someDate" : "1963-01-07 07:10:00 +0000",<br />
"nullString" : null,<br />
"someOtherStuff" : "Thing Two Other Stuff"<br />
},<br />
"name" : "John Jones",<br />
"dict" : {<br />
"key1" : "value1",<br />
"key2" : "value2"<br />
}<br />
}<br />
<br />
(lldb) po roundTripJson1<br />
{<br />
"values" : [<br />
"Value1",<br />
"Value2",<br />
"Value3"<br />
],<br />
"myInt" : 5431,<br />
"myFloat" : 123.456,<br />
"myBool" : true,<br />
"someMoney" : "$503.00",<br />
"thingTwo" : {<br />
"stuff" : "Thing Two Stuff",<br />
"nullDate" : null,<br />
"someDate" : "1963-01-07 07:10:00 +0000",<br />
"nullString" : null,<br />
"someOtherStuff" : "Thing Two Other Stuff"<br />
},<br />
"name" : "John Jones",<br />
"dict" : {<br />
"key1" : "value1",<br />
"key2" : "value2"<br />
}<br />
}<br />
<br />
(lldb) po roundTripJson2<br />
{<br />
"values" : [<br />
"Value1",<br />
"Value2",<br />
"Value3"<br />
],<br />
"myInt" : 5431,<br />
"myFloat" : 123.456,<br />
"myBool" : true,<br />
"someMoney" : "$503.00",<br />
"thingTwo" : {<br />
"stuff" : "Thing Two Stuff",<br />
"nullDate" : null,<br />
"someDate" : "1963-01-07 07:10:00 +0000",<br />
"nullString" : null,<br />
"someOtherStuff" : "Thing Two Other Stuff"<br />
},<br />
"name" : "John Jones",<br />
"dict" : {<br />
"key1" : "value1",<br />
"key2" : "value2"<br />
}<br />
}<br />
<br />
(lldb) po roundTripJson3<br />
{<br />
"values" : [<br />
"ValueA",<br />
"ValueB",<br />
"ValueC"<br />
],<br />
"myInt" : 2039,<br />
"myFloat" : 123.456,<br />
"myBool" : true,<br />
"someMoney" : "$503.00",<br />
"thingTwo" : {<br />
"stuff" : "Thing Two Stuff2",<br />
"nullDate" : null,<br />
"someDate" : "1963-01-07 07:10:00 +0000",<br />
"nullString" : null,<br />
"someOtherStuff" : "Thing Two Other Stuff2"<br />
},<br />
"name" : "William Smith",<br />
"dict" : {<br />
"key10" : "value10",<br />
"key20" : "value20"<br />
}<br />
}<br />
<br />
(lldb)<br />
<br />
<br />Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com0tag:blogger.com,1999:blog-36645098.post-79195010137788507742014-01-14T16:22:00.000-08:002014-01-14T16:24:53.041-08:00Solr Cloud zkCli.sh set clusterstate.jsonWell, if you have ever spent two hours doing something completely wrong then you know where I have been today.<br />
<br />
I have a Solr Cloud configuration with three shards and no replicas at this time. I am inserting documents then pausing and doing some load tests, then inserting more, until I get to 5 billion.<br />
<br />
Well, the linux boxes running Solr and Zookeeper were restarted and Solr was restarted before Zookeeper. Then when Zookeeper was restarted somehow the clusterstate.json was updated so that I now had 1 shard with 2 replicas.<br />
<br />
So, all I need to do is fix the clusterstate.json. I stop the Solr instances and go to work. Fortunately I have a copy of the clusterstate.json and I highly recommend saving a copy of your clusterstate.json somewhere safe.<br />
<br />
Here is where the trouble starts.<br />
<br />
I had found online that you just have to set the clusterstate.json. I assume that you can do this from the zkCli command prompt.<br />
<br />
So, I run zkCli.sh and at the prompt I try this:<br />
set /clusterstate.json "`cat /local/path/to/clusterstate.json`"<br />
<br />
I get a java NumberFormat Exception.<br />
<br />
I tried escaping quotes in the json, removing line feeds, everything I could think of.<br />
<br />
Well, long story short, you don't do the command from the zkCli command prompt.<br />
<br />
You run the command in your shell/console.<br />
<br />
I now do this from the zookeeper bin directory:<br />
<br />
#sh zkCli.sh -server 127.0.0.1:2181 set /clusterstate.json "`cat /local/path/to/clusterstate.json`"<br />
<br />
Everything worked great.<br />
<br />
So, if you are trying to set the clusterstate.json while in ZkCli.sh you will get this error:<br />
<br />
<b>zkcli Command failed: java.lang.NumberFormatException: For input string:</b><br />
<br />
<b>Don't run it inside of ZkCli.sh, run the command from the shell.</b>Geoff Slinkerhttp://www.blogger.com/profile/12365501393247949005noreply@blogger.com3