├── .github ├── CONTRIBUTING.md ├── Hi.swift ├── PULL_REQUEST_TEMPLATE.md ├── deploy.sh ├── inspect.rb ├── osia_category_list.rb ├── osia_convert.rb ├── osia_get_history.rb ├── osia_get_lic.rb ├── osia_get_links.rb ├── osia_helper.rb ├── osia_history_missing.rb ├── osia_screenshots_missing.rb ├── osia_tweet_clean.rb ├── osia_update_history.rb ├── osia_update_lic.rb ├── osia_update_stars.rb ├── osia_validate_categories.rb └── schema.json ├── .travis.yml ├── ARCHIVE.md ├── Dangerfile ├── LICENSE ├── README.md ├── circle.yml └── contents.json /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | To contribute to`open-source-ios-apps`, update the **contents.json** file (this will generate the README). 2 | 3 | A new entry should update **contents.json** with this format: 4 | 5 | ```js 6 | { 7 | "title": "Name of the app", 8 | "category-ids": ["Category id"], 9 | "description": "What this app does", 10 | "source": "Link to source, usually GitHub", 11 | "screenshots": ["http://something.com/image.png"], 12 | "date_added": "Aug 6 2016", 13 | "suggested_by": "@github_username" 14 | } 15 | ``` 16 | 17 | :tada: 18 | 19 | For more information, please read https://github.com/dkhamsing/open-source-ios-apps/wiki 20 | -------------------------------------------------------------------------------- /.github/Hi.swift: -------------------------------------------------------------------------------- 1 | print("Hello world") 2 | print("Hello world") 3 | print("Hello world") 4 | print("Hello world") 5 | print("Hello world") 6 | print("Hello world") 7 | print("Hello world") 8 | print("Hello world") 9 | print("Hello world") 10 | print("Hello world") 11 | print("Hello world") 12 | print("Hello world") 13 | print("Hello world") 14 | print("Hello world") 15 | print("Hello world") 16 | print("Hello world") 17 | print("Hello world") 18 | print("Hello world") 19 | print("Hello world") 20 | print("Hello world") 21 | print("Hello world") 22 | print("Hello world") 23 | print("Hello world") 24 | print("Hello world") 25 | print("Hello world") 26 | print("Hello world") 27 | print("Hello world") 28 | print("Hello world") 29 | print("Hello world") 30 | print("Hello world") 31 | print("Hello world") 32 | print("Hello world") 33 | print("Hello world") 34 | print("Hello world") 35 | print("Hello world") 36 | print("Hello world") 37 | print("Hello world") 38 | print("Hello world") 39 | print("Hello world") 40 | print("Hello world") 41 | print("Hello world") 42 | print("Hello world") 43 | print("Hello world") 44 | print("Hello world") 45 | print("Hello world") 46 | print("Hello world") 47 | print("Hello world") 48 | print("Hello world") 49 | print("Hello world") 50 | print("Hello world") 51 | print("Hello world") 52 | print("Hello world") 53 | print("Hello world") 54 | print("Hello world") 55 | print("Hello world") 56 | print("Hello world") 57 | print("Hello world") 58 | print("Hello world") 59 | print("Hello world") 60 | print("Hello world") 61 | print("Hello world") 62 | print("Hello world") 63 | print("Hello world") 64 | print("Hello world") 65 | print("Hello world") 66 | print("Hello world") 67 | print("Hello world") 68 | print("Hello world") 69 | print("Hello world") 70 | print("Hello world") 71 | print("Hello world") 72 | print("Hello world") 73 | print("Hello world") 74 | print("Hello world") 75 | print("Hello world") 76 | print("Hello world") 77 | print("Hello world") 78 | print("Hello world") 79 | print("Hello world") 80 | print("Hello world") 81 | print("Hello world") 82 | print("Hello world") 83 | print("Hello world") 84 | print("Hello world") 85 | print("Hello world") 86 | print("Hello world") 87 | print("Hello world") 88 | print("Hello world") 89 | print("Hello world") 90 | print("Hello world") 91 | print("Hello world") 92 | print("Hello world") 93 | print("Hello world") 94 | print("Hello world") 95 | print("Hello world") 96 | print("Hello world") 97 | print("Hello world") 98 | print("Hello world") 99 | print("Hello world") 100 | print("Hello world") 101 | print("Hello world") 102 | print("Hello world") 103 | print("Hello world") 104 | print("Hello world") 105 | print("Hello world") 106 | print("Hello world") 107 | print("Hello world") 108 | print("Hello world") 109 | print("Hello world") 110 | print("Hello world") 111 | print("Hello world") 112 | print("Hello world") 113 | print("Hello world") 114 | print("Hello world") 115 | print("Hello world") 116 | print("Hello world") 117 | print("Hello world") 118 | print("Hello world") 119 | print("Hello world") 120 | print("Hello world") 121 | print("Hello world") 122 | print("Hello world") 123 | print("Hello world") 124 | print("Hello world") 125 | print("Hello world") 126 | print("Hello world") 127 | print("Hello world") 128 | print("Hello world") 129 | print("Hello world") 130 | print("Hello world") 131 | print("Hello world") 132 | print("Hello world") 133 | print("Hello world") 134 | print("Hello world") 135 | print("Hello world") 136 | print("Hello world") 137 | print("Hello world") 138 | print("Hello world") 139 | print("Hello world") 140 | print("Hello world") 141 | print("Hello world") 142 | print("Hello world") 143 | print("Hello world") 144 | print("Hello world") 145 | print("Hello world") 146 | print("Hello world") 147 | print("Hello world") 148 | print("Hello world") 149 | print("Hello world") 150 | print("Hello world") 151 | print("Hello world") 152 | print("Hello world") 153 | print("Hello world") 154 | print("Hello world") 155 | print("Hello world") 156 | print("Hello world") 157 | print("Hello world") 158 | print("Hello world") 159 | print("Hello world") 160 | print("Hello world") 161 | print("Hello world") 162 | print("Hello world") 163 | print("Hello world") 164 | print("Hello world") 165 | print("Hello world") 166 | print("Hello world") 167 | print("Hello world") 168 | print("Hello world") 169 | print("Hello world") 170 | print("Hello world") 171 | print("Hello world") 172 | print("Hello world") 173 | print("Hello world") 174 | print("Hello world") 175 | print("Hello world") 176 | print("Hello world") 177 | print("Hello world") 178 | print("Hello world") 179 | print("Hello world") 180 | print("Hello world") 181 | print("Hello world") 182 | print("Hello world") 183 | print("Hello world") 184 | print("Hello world") 185 | print("Hello world") 186 | print("Hello world") 187 | print("Hello world") 188 | print("Hello world") 189 | print("Hello world") 190 | print("Hello world") 191 | print("Hello world") 192 | print("Hello world") 193 | print("Hello world") 194 | print("Hello world") 195 | print("Hello world") 196 | print("Hello world") 197 | print("Hello world") 198 | print("Hello world") 199 | print("Hello world") 200 | print("Hello world") 201 | print("Hello world") 202 | print("Hello world") 203 | print("Hello world") 204 | print("Hello world") 205 | print("Hello world") 206 | print("Hello world") 207 | print("Hello world") 208 | print("Hello world") 209 | print("Hello world") 210 | print("Hello world") 211 | print("Hello world") 212 | print("Hello world") 213 | print("Hello world") 214 | print("Hello world") 215 | print("Hello world") 216 | print("Hello world") 217 | print("Hello world") 218 | print("Hello world") 219 | print("Hello world") 220 | print("Hello world") 221 | print("Hello world") 222 | print("Hello world") 223 | print("Hello world") 224 | print("Hello world") 225 | print("Hello world") 226 | print("Hello world") 227 | print("Hello world") 228 | print("Hello world") 229 | print("Hello world") 230 | print("Hello world") 231 | print("Hello world") 232 | print("Hello world") 233 | print("Hello world") 234 | print("Hello world") 235 | print("Hello world") 236 | print("Hello world") 237 | print("Hello world") 238 | print("Hello world") 239 | print("Hello world") 240 | print("Hello world") 241 | print("Hello world") 242 | print("Hello world") 243 | print("Hello world") 244 | print("Hello world") 245 | print("Hello world") 246 | print("Hello world") 247 | print("Hello world") 248 | print("Hello world") 249 | print("Hello world") 250 | print("Hello world") 251 | print("Hello world") 252 | print("Hello world") 253 | print("Hello world") 254 | print("Hello world") 255 | print("Hello world") 256 | print("Hello world") 257 | print("Hello world") 258 | print("Hello world") 259 | print("Hello world") 260 | print("Hello world") 261 | print("Hello world") 262 | print("Hello world") 263 | print("Hello world") 264 | print("Hello world") 265 | print("Hello world") 266 | print("Hello world") 267 | print("Hello world") 268 | print("Hello world") 269 | print("Hello world") 270 | print("Hello world") 271 | print("Hello world") 272 | print("Hello world") 273 | print("Hello world") 274 | print("Hello world") 275 | print("Hello world") 276 | print("Hello world") 277 | print("Hello world") 278 | print("Hello world") 279 | print("Hello world") 280 | print("Hello world") 281 | print("Hello world") 282 | print("Hello world") 283 | print("Hello world") 284 | print("Hello world") 285 | print("Hello world") 286 | print("Hello world") 287 | print("Hello world") 288 | print("Hello world") 289 | print("Hello world") 290 | print("Hello world") 291 | print("Hello world") 292 | print("Hello world") 293 | print("Hello world") 294 | print("Hello world") 295 | print("Hello world") 296 | print("Hello world") 297 | print("Hello world") 298 | print("Hello world") 299 | print("Hello world") 300 | print("Hello world") 301 | print("Hello world") 302 | print("Hello world") 303 | print("Hello world") 304 | print("Hello world") 305 | print("Hello world") 306 | print("Hello world") 307 | print("Hello world") 308 | print("Hello world") 309 | print("Hello world") 310 | print("Hello world") 311 | print("Hello world") 312 | print("Hello world") 313 | print("Hello world") 314 | print("Hello world") 315 | print("Hello world") 316 | print("Hello world") 317 | print("Hello world") 318 | print("Hello world") 319 | print("Hello world") 320 | print("Hello world") 321 | print("Hello world") 322 | print("Hello world") 323 | print("Hello world") 324 | print("Hello world") 325 | print("Hello world") 326 | print("Hello world") 327 | print("Hello world") 328 | print("Hello world") 329 | print("Hello world") 330 | print("Hello world") 331 | print("Hello world") 332 | print("Hello world") 333 | print("Hello world") 334 | print("Hello world") 335 | print("Hello world") 336 | print("Hello world") 337 | print("Hello world") 338 | print("Hello world") 339 | print("Hello world") 340 | print("Hello world") 341 | print("Hello world") 342 | print("Hello world") 343 | print("Hello world") 344 | print("Hello world") 345 | print("Hello world") 346 | print("Hello world") 347 | print("Hello world") 348 | print("Hello world") 349 | print("Hello world") 350 | print("Hello world") 351 | print("Hello world") 352 | print("Hello world") 353 | print("Hello world") 354 | print("Hello world") 355 | print("Hello world") 356 | print("Hello world") 357 | print("Hello world") 358 | print("Hello world") 359 | print("Hello world") 360 | print("Hello world") 361 | print("Hello world") 362 | print("Hello world") 363 | print("Hello world") 364 | print("Hello world") 365 | print("Hello world") 366 | print("Hello world") 367 | print("Hello world") 368 | print("Hello world") 369 | print("Hello world") 370 | print("Hello world") 371 | print("Hello world") 372 | print("Hello world") 373 | print("Hello world") 374 | print("Hello world") 375 | print("Hello world") 376 | print("Hello world") 377 | print("Hello world") 378 | print("Hello world") 379 | print("Hello world") 380 | print("Hello world") 381 | print("Hello world") 382 | print("Hello world") 383 | print("Hello world") 384 | print("Hello world") 385 | print("Hello world") 386 | print("Hello world") 387 | print("Hello world") 388 | print("Hello world") 389 | print("Hello world") 390 | print("Hello world") 391 | print("Hello world") 392 | print("Hello world") 393 | print("Hello world") 394 | print("Hello world") 395 | print("Hello world") 396 | print("Hello world") 397 | print("Hello world") 398 | print("Hello world") 399 | print("Hello world") 400 | print("Hello world") 401 | print("Hello world") 402 | print("Hello world") 403 | print("Hello world") 404 | print("Hello world") 405 | print("Hello world") 406 | print("Hello world") 407 | print("Hello world") 408 | print("Hello world") 409 | print("Hello world") 410 | print("Hello world") 411 | print("Hello world") 412 | print("Hello world") 413 | print("Hello world") 414 | print("Hello world") 415 | print("Hello world") 416 | print("Hello world") 417 | print("Hello world") 418 | print("Hello world") 419 | print("Hello world") 420 | print("Hello world") 421 | print("Hello world") 422 | print("Hello world") 423 | print("Hello world") 424 | print("Hello world") 425 | print("Hello world") 426 | print("Hello world") 427 | print("Hello world") 428 | print("Hello world") 429 | print("Hello world") 430 | print("Hello world") 431 | print("Hello world") 432 | print("Hello world") 433 | print("Hello world") 434 | print("Hello world") 435 | print("Hello world") 436 | print("Hello world") 437 | print("Hello world") 438 | print("Hello world") 439 | print("Hello world") 440 | print("Hello world") 441 | print("Hello world") 442 | print("Hello world") 443 | print("Hello world") 444 | print("Hello world") 445 | print("Hello world") 446 | print("Hello world") 447 | print("Hello world") 448 | print("Hello world") 449 | print("Hello world") 450 | print("Hello world") 451 | print("Hello world") 452 | print("Hello world") 453 | print("Hello world") 454 | print("Hello world") 455 | print("Hello world") 456 | print("Hello world") 457 | print("Hello world") 458 | print("Hello world") 459 | print("Hello world") 460 | print("Hello world") 461 | print("Hello world") 462 | print("Hello world") 463 | print("Hello world") 464 | print("Hello world") 465 | print("Hello world") 466 | print("Hello world") 467 | print("Hello world") 468 | print("Hello world") 469 | print("Hello world") 470 | print("Hello world") 471 | print("Hello world") 472 | print("Hello world") 473 | print("Hello world") 474 | print("Hello world") 475 | print("Hello world") 476 | print("Hello world") 477 | print("Hello world") 478 | print("Hello world") 479 | print("Hello world") 480 | print("Hello world") 481 | print("Hello world") 482 | print("Hello world") 483 | print("Hello world") 484 | print("Hello world") 485 | print("Hello world") 486 | print("Hello world") 487 | print("Hello world") 488 | print("Hello world") 489 | print("Hello world") 490 | print("Hello world") 491 | print("Hello world") 492 | print("Hello world") 493 | print("Hello world") 494 | print("Hello world") 495 | print("Hello world") 496 | print("Hello world") 497 | print("Hello world") 498 | print("Hello world") 499 | print("Hello world") 500 | print("Hello world") 501 | print("Hello world") 502 | print("Hello world") 503 | print("Hello world") 504 | print("Hello world") 505 | print("Hello world") 506 | print("Hello world") 507 | print("Hello world") 508 | print("Hello world") 509 | print("Hello world") 510 | print("Hello world") 511 | print("Hello world") 512 | print("Hello world") 513 | print("Hello world") 514 | print("Hello world") 515 | print("Hello world") 516 | print("Hello world") 517 | print("Hello world") 518 | print("Hello world") 519 | print("Hello world") 520 | print("Hello world") 521 | print("Hello world") 522 | print("Hello world") 523 | print("Hello world") 524 | print("Hello world") 525 | print("Hello world") 526 | print("Hello world") 527 | print("Hello world") 528 | print("Hello world") 529 | print("Hello world") 530 | print("Hello world") 531 | print("Hello world") 532 | print("Hello world") 533 | print("Hello world") 534 | print("Hello world") 535 | print("Hello world") 536 | print("Hello world") 537 | print("Hello world") 538 | print("Hello world") 539 | print("Hello world") 540 | print("Hello world") 541 | print("Hello world") 542 | print("Hello world") 543 | print("Hello world") 544 | print("Hello world") 545 | print("Hello world") 546 | print("Hello world") 547 | print("Hello world") 548 | print("Hello world") 549 | print("Hello world") 550 | print("Hello world") 551 | print("Hello world") 552 | print("Hello world") 553 | print("Hello world") 554 | print("Hello world") 555 | print("Hello world") 556 | print("Hello world") 557 | print("Hello world") 558 | print("Hello world") 559 | print("Hello world") 560 | print("Hello world") 561 | print("Hello world") 562 | print("Hello world") 563 | print("Hello world") 564 | print("Hello world") 565 | print("Hello world") 566 | print("Hello world") 567 | print("Hello world") 568 | print("Hello world") 569 | print("Hello world") 570 | print("Hello world") 571 | print("Hello world") 572 | print("Hello world") 573 | print("Hello world") 574 | print("Hello world") 575 | print("Hello world") 576 | print("Hello world") 577 | print("Hello world") 578 | print("Hello world") 579 | print("Hello world") 580 | print("Hello world") 581 | print("Hello world") 582 | print("Hello world") 583 | print("Hello world") 584 | print("Hello world") 585 | print("Hello world") 586 | print("Hello world") 587 | print("Hello world") 588 | print("Hello world") 589 | print("Hello world") 590 | print("Hello world") 591 | print("Hello world") 592 | print("Hello world") 593 | print("Hello world") 594 | print("Hello world") 595 | print("Hello world") 596 | print("Hello world") 597 | print("Hello world") 598 | print("Hello world") 599 | print("Hello world") 600 | print("Hello world") 601 | print("Hello world") 602 | print("Hello world") 603 | print("Hello world") 604 | print("Hello world") 605 | print("Hello world") 606 | print("Hello world") 607 | print("Hello world") 608 | print("Hello world") 609 | print("Hello world") 610 | print("Hello world") 611 | print("Hello world") 612 | print("Hello world") 613 | print("Hello world") 614 | print("Hello world") 615 | print("Hello world") 616 | print("Hello world") 617 | print("Hello world") 618 | print("Hello world") 619 | print("Hello world") 620 | print("Hello world") 621 | print("Hello world") 622 | print("Hello world") 623 | print("Hello world") 624 | print("Hello world") 625 | print("Hello world") 626 | print("Hello world") 627 | print("Hello world") 628 | print("Hello world") 629 | print("Hello world") 630 | print("Hello world") 631 | print("Hello world") 632 | print("Hello world") 633 | print("Hello world") 634 | print("Hello world") 635 | print("Hello world") 636 | print("Hello world") 637 | print("Hello world") 638 | print("Hello world") 639 | print("Hello world") 640 | print("Hello world") 641 | print("Hello world") 642 | print("Hello world") 643 | print("Hello world") 644 | print("Hello world") 645 | print("Hello world") 646 | print("Hello world") 647 | print("Hello world") 648 | print("Hello world") 649 | print("Hello world") 650 | print("Hello world") 651 | print("Hello world") 652 | print("Hello world") 653 | print("Hello world") 654 | print("Hello world") 655 | print("Hello world") 656 | print("Hello world") 657 | print("Hello world") 658 | print("Hello world") 659 | print("Hello world") 660 | print("Hello world") 661 | print("Hello world") 662 | print("Hello world") 663 | print("Hello world") 664 | print("Hello world") 665 | print("Hello world") 666 | print("Hello world") 667 | print("Hello world") 668 | print("Hello world") 669 | print("Hello world") 670 | print("Hello world") 671 | print("Hello world") 672 | print("Hello world") 673 | print("Hello world") 674 | print("Hello world") 675 | print("Hello world") 676 | print("Hello world") 677 | print("Hello world") 678 | print("Hello world") 679 | print("Hello world") 680 | print("Hello world") 681 | print("Hello world") 682 | print("Hello world") 683 | print("Hello world") 684 | print("Hello world") 685 | print("Hello world") 686 | print("Hello world") 687 | print("Hello world") 688 | print("Hello world") 689 | print("Hello world") 690 | print("Hello world") 691 | print("Hello world") 692 | print("Hello world") 693 | print("Hello world") 694 | print("Hello world") 695 | print("Hello world") 696 | print("Hello world") 697 | print("Hello world") 698 | print("Hello world") 699 | print("Hello world") 700 | print("Hello world") 701 | print("Hello world") 702 | print("Hello world") 703 | print("Hello world") 704 | print("Hello world") 705 | print("Hello world") 706 | print("Hello world") 707 | print("Hello world") 708 | print("Hello world") 709 | print("Hello world") 710 | print("Hello world") 711 | print("Hello world") 712 | print("Hello world") 713 | print("Hello world") 714 | print("Hello world") 715 | print("Hello world") 716 | print("Hello world") 717 | print("Hello world") 718 | print("Hello world") 719 | print("Hello world") 720 | print("Hello world") 721 | print("Hello world") 722 | print("Hello world") 723 | print("Hello world") 724 | print("Hello world") 725 | print("Hello world") 726 | print("Hello world") 727 | print("Hello world") 728 | print("Hello world") 729 | print("Hello world") 730 | print("Hello world") 731 | print("Hello world") 732 | print("Hello world") 733 | print("Hello world") 734 | print("Hello world") 735 | print("Hello world") 736 | print("Hello world") 737 | print("Hello world") 738 | print("Hello world") 739 | print("Hello world") 740 | print("Hello world") 741 | print("Hello world") 742 | print("Hello world") 743 | print("Hello world") 744 | print("Hello world") 745 | print("Hello world") 746 | print("Hello world") 747 | print("Hello world") 748 | print("Hello world") 749 | print("Hello world") 750 | print("Hello world") 751 | print("Hello world") 752 | print("Hello world") 753 | print("Hello world") 754 | print("Hello world") 755 | print("Hello world") 756 | print("Hello world") 757 | print("Hello world") 758 | print("Hello world") 759 | print("Hello world") 760 | print("Hello world") 761 | print("Hello world") 762 | print("Hello world") 763 | print("Hello world") 764 | print("Hello world") 765 | print("Hello world") 766 | print("Hello world") 767 | print("Hello world") 768 | print("Hello world") 769 | print("Hello world") 770 | print("Hello world") 771 | print("Hello world") 772 | print("Hello world") 773 | print("Hello world") 774 | print("Hello world") 775 | print("Hello world") 776 | print("Hello world") 777 | print("Hello world") 778 | print("Hello world") 779 | print("Hello world") 780 | print("Hello world") 781 | print("Hello world") 782 | print("Hello world") 783 | print("Hello world") 784 | print("Hello world") 785 | print("Hello world") 786 | print("Hello world") 787 | print("Hello world") 788 | print("Hello world") 789 | print("Hello world") 790 | print("Hello world") 791 | print("Hello world") 792 | print("Hello world") 793 | print("Hello world") 794 | print("Hello world") 795 | print("Hello world") 796 | print("Hello world") 797 | print("Hello world") 798 | print("Hello world") 799 | print("Hello world") 800 | print("Hello world") 801 | print("Hello world") 802 | print("Hello world") 803 | print("Hello world") 804 | print("Hello world") 805 | print("Hello world") 806 | print("Hello world") 807 | print("Hello world") 808 | print("Hello world") 809 | print("Hello world") 810 | print("Hello world") 811 | print("Hello world") 812 | print("Hello world") 813 | print("Hello world") 814 | print("Hello world") 815 | print("Hello world") 816 | print("Hello world") 817 | print("Hello world") 818 | print("Hello world") 819 | print("Hello world") 820 | print("Hello world") 821 | print("Hello world") 822 | print("Hello world") 823 | print("Hello world") 824 | print("Hello world") 825 | print("Hello world") 826 | print("Hello world") 827 | print("Hello world") 828 | print("Hello world") 829 | print("Hello world") 830 | print("Hello world") 831 | print("Hello world") 832 | print("Hello world") 833 | print("Hello world") 834 | print("Hello world") 835 | print("Hello world") 836 | print("Hello world") 837 | print("Hello world") 838 | print("Hello world") 839 | print("Hello world") 840 | print("Hello world") 841 | print("Hello world") 842 | print("Hello world") 843 | print("Hello world") 844 | print("Hello world") 845 | print("Hello world") 846 | print("Hello world") 847 | print("Hello world") 848 | print("Hello world") 849 | print("Hello world") 850 | print("Hello world") 851 | print("Hello world") 852 | print("Hello world") 853 | print("Hello world") 854 | print("Hello world") 855 | print("Hello world") 856 | print("Hello world") 857 | print("Hello world") 858 | print("Hello world") 859 | print("Hello world") 860 | print("Hello world") 861 | print("Hello world") 862 | print("Hello world") 863 | print("Hello world") 864 | print("Hello world") 865 | print("Hello world") 866 | print("Hello world") 867 | print("Hello world") 868 | print("Hello world") 869 | print("Hello world") 870 | print("Hello world") 871 | print("Hello world") 872 | print("Hello world") 873 | print("Hello world") 874 | print("Hello world") 875 | print("Hello world") 876 | print("Hello world") 877 | print("Hello world") 878 | print("Hello world") 879 | print("Hello world") 880 | print("Hello world") 881 | print("Hello world") 882 | print("Hello world") 883 | print("Hello world") 884 | print("Hello world") 885 | print("Hello world") 886 | print("Hello world") 887 | print("Hello world") 888 | print("Hello world") 889 | print("Hello world") 890 | print("Hello world") 891 | print("Hello world") 892 | print("Hello world") 893 | print("Hello world") 894 | print("Hello world") 895 | print("Hello world") 896 | print("Hello world") 897 | print("Hello world") 898 | print("Hello world") 899 | print("Hello world") 900 | print("Hello world") 901 | print("Hello world") 902 | print("Hello world") 903 | print("Hello world") 904 | print("Hello world") 905 | print("Hello world") 906 | print("Hello world") 907 | print("Hello world") 908 | print("Hello world") 909 | print("Hello world") 910 | print("Hello world") 911 | print("Hello world") 912 | print("Hello world") 913 | print("Hello world") 914 | print("Hello world") 915 | print("Hello world") 916 | print("Hello world") 917 | print("Hello world") 918 | print("Hello world") 919 | print("Hello world") 920 | print("Hello world") 921 | print("Hello world") 922 | print("Hello world") 923 | print("Hello world") 924 | print("Hello world") 925 | print("Hello world") 926 | print("Hello world") 927 | print("Hello world") 928 | print("Hello world") 929 | print("Hello world") 930 | print("Hello world") 931 | print("Hello world") 932 | print("Hello world") 933 | print("Hello world") 934 | print("Hello world") 935 | print("Hello world") 936 | print("Hello world") 937 | print("Hello world") 938 | print("Hello world") 939 | print("Hello world") 940 | print("Hello world") 941 | print("Hello world") 942 | print("Hello world") 943 | print("Hello world") 944 | print("Hello world") 945 | print("Hello world") 946 | print("Hello world") 947 | print("Hello world") 948 | print("Hello world") 949 | print("Hello world") 950 | print("Hello world") 951 | print("Hello world") 952 | print("Hello world") 953 | print("Hello world") 954 | print("Hello world") 955 | print("Hello world") 956 | print("Hello world") 957 | print("Hello world") 958 | print("Hello world") 959 | print("Hello world") 960 | print("Hello world") 961 | print("Hello world") 962 | print("Hello world") 963 | print("Hello world") 964 | print("Hello world") 965 | print("Hello world") 966 | print("Hello world") 967 | print("Hello world") 968 | print("Hello world") 969 | print("Hello world") 970 | print("Hello world") 971 | print("Hello world") 972 | print("Hello world") 973 | print("Hello world") 974 | print("Hello world") 975 | print("Hello world") 976 | print("Hello world") 977 | print("Hello world") 978 | print("Hello world") 979 | print("Hello world") 980 | print("Hello world") 981 | print("Hello world") 982 | print("Hello world") 983 | print("Hello world") 984 | print("Hello world") 985 | print("Hello world") 986 | print("Hello world") 987 | print("Hello world") 988 | print("Hello world") 989 | print("Hello world") 990 | print("Hello world") 991 | print("Hello world") 992 | print("Hello world") 993 | print("Hello world") 994 | print("Hello world") 995 | print("Hello world") 996 | print("Hello world") 997 | print("Hello world") 998 | print("Hello world") 999 | print("Hello world") 1000 | print("Hello world") 1001 | print("Hello world") 1002 | print("Hello world") 1003 | print("Hello world") 1004 | print("Hello world") 1005 | print("Hello world") 1006 | print("Hello world") 1007 | print("Hello world") 1008 | print("Hello world") 1009 | print("Hello world") 1010 | print("Hello world") 1011 | print("Hello world") 1012 | print("Hello world") 1013 | print("Hello world") 1014 | print("Hello world") 1015 | print("Hello world") 1016 | print("Hello world") 1017 | print("Hello world") 1018 | print("Hello world") 1019 | print("Hello world") 1020 | print("Hello world") 1021 | print("Hello world") 1022 | print("Hello world") 1023 | print("Hello world") 1024 | print("Hello world") 1025 | print("Hello world") 1026 | print("Hello world") 1027 | print("Hello world") 1028 | print("Hello world") 1029 | print("Hello world") 1030 | print("Hello world") 1031 | print("Hello world") 1032 | print("Hello world") 1033 | print("Hello world") 1034 | print("Hello world") 1035 | print("Hello world") 1036 | print("Hello world") 1037 | print("Hello world") 1038 | print("Hello world") 1039 | print("Hello world") 1040 | print("Hello world") 1041 | print("Hello world") 1042 | print("Hello world") 1043 | print("Hello world") 1044 | print("Hello world") 1045 | print("Hello world") 1046 | print("Hello world") 1047 | print("Hello world") 1048 | print("Hello world") 1049 | print("Hello world") 1050 | print("Hello world") 1051 | print("Hello world") 1052 | print("Hello world") 1053 | print("Hello world") 1054 | print("Hello world") 1055 | print("Hello world") 1056 | print("Hello world") 1057 | print("Hello world") 1058 | print("Hello world") 1059 | print("Hello world") 1060 | print("Hello world") 1061 | print("Hello world") 1062 | print("Hello world") 1063 | print("Hello world") 1064 | print("Hello world") 1065 | print("Hello world") 1066 | print("Hello world") 1067 | print("Hello world") 1068 | print("Hello world") 1069 | print("Hello world") 1070 | print("Hello world") 1071 | print("Hello world") 1072 | print("Hello world") 1073 | print("Hello world") 1074 | print("Hello world") 1075 | print("Hello world") 1076 | print("Hello world") 1077 | print("Hello world") 1078 | print("Hello world") 1079 | print("Hello world") 1080 | print("Hello world") 1081 | print("Hello world") 1082 | print("Hello world") 1083 | print("Hello world") 1084 | print("Hello world") 1085 | print("Hello world") 1086 | print("Hello world") 1087 | print("Hello world") 1088 | print("Hello world") 1089 | print("Hello world") 1090 | print("Hello world") 1091 | print("Hello world") 1092 | print("Hello world") 1093 | print("Hello world") 1094 | print("Hello world") 1095 | print("Hello world") 1096 | print("Hello world") 1097 | print("Hello world") 1098 | print("Hello world") 1099 | print("Hello world") 1100 | print("Hello world") 1101 | print("Hello world") 1102 | print("Hello world") 1103 | print("Hello world") 1104 | print("Hello world") 1105 | print("Hello world") 1106 | print("Hello world") 1107 | print("Hello world") 1108 | print("Hello world") 1109 | print("Hello world") 1110 | print("Hello world") 1111 | print("Hello world") 1112 | print("Hello world") 1113 | print("Hello world") 1114 | print("Hello world") 1115 | print("Hello world") 1116 | print("Hello world") 1117 | print("Hello world") 1118 | print("Hello world") 1119 | print("Hello world") 1120 | print("Hello world") 1121 | print("Hello world") 1122 | print("Hello world") 1123 | print("Hello world") 1124 | print("Hello world") 1125 | print("Hello world") 1126 | print("Hello world") 1127 | print("Hello world") 1128 | print("Hello world") 1129 | print("Hello world") 1130 | print("Hello world") 1131 | print("Hello world") 1132 | print("Hello world") 1133 | print("Hello world") 1134 | print("Hello world") 1135 | print("Hello world") 1136 | print("Hello world") 1137 | print("Hello world") 1138 | print("Hello world") 1139 | print("Hello world") 1140 | print("Hello world") 1141 | print("Hello world") 1142 | print("Hello world") 1143 | print("Hello world") 1144 | print("Hello world") 1145 | print("Hello world") 1146 | print("Hello world") 1147 | print("Hello world") 1148 | print("Hello world") 1149 | print("Hello world") 1150 | print("Hello world") 1151 | print("Hello world") 1152 | print("Hello world") 1153 | print("Hello world") 1154 | print("Hello world") 1155 | print("Hello world") 1156 | print("Hello world") 1157 | print("Hello world") 1158 | print("Hello world") 1159 | print("Hello world") 1160 | print("Hello world") 1161 | print("Hello world") 1162 | print("Hello world") 1163 | print("Hello world") 1164 | print("Hello world") 1165 | print("Hello world") 1166 | print("Hello world") 1167 | print("Hello world") 1168 | print("Hello world") 1169 | print("Hello world") 1170 | print("Hello world") 1171 | print("Hello world") 1172 | print("Hello world") 1173 | print("Hello world") 1174 | print("Hello world") 1175 | print("Hello world") 1176 | print("Hello world") 1177 | print("Hello world") 1178 | print("Hello world") 1179 | print("Hello world") 1180 | print("Hello world") 1181 | print("Hello world") 1182 | print("Hello world") 1183 | print("Hello world") 1184 | print("Hello world") 1185 | print("Hello world") 1186 | print("Hello world") 1187 | print("Hello world") 1188 | print("Hello world") 1189 | print("Hello world") 1190 | print("Hello world") 1191 | print("Hello world") 1192 | print("Hello world") 1193 | print("Hello world") 1194 | print("Hello world") 1195 | print("Hello world") 1196 | print("Hello world") 1197 | print("Hello world") 1198 | print("Hello world") 1199 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 1. [ ] Project URL: 10 | 2. [ ] Update contents.json instead of README 11 | 3. [ ] One project per pull request 12 | 4. [ ] Avoid iOS or open-source in description as it is assumed 13 | 5. [ ] Use this commit title format if applicable: Add app-name by @github-username 14 | 6. [ ] Use approved format for your entry 15 | 16 | 31 | -------------------------------------------------------------------------------- /.github/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | git config user.name "READMEbot" 6 | git config user.email "readmebot@users.noreply.github.com" 7 | 8 | status=`git status` 9 | 10 | if [[ $status == *"README.md"* ]] 11 | then 12 | git add README.md 13 | git commit -m "[auto] [ci skip] Generate README" 14 | fi 15 | 16 | if [[ $status == *"ARCHIVE.md"* ]] 17 | then 18 | git add ARCHIVE.md 19 | git commit -m "[auto] [ci skip] Generate ARCHIVE" 20 | fi 21 | 22 | git push --quiet "https://${GH_TOKEN}@github.com/dkhamsing/open-source-ios-apps" master:master > /dev/null 2>&1 23 | -------------------------------------------------------------------------------- /.github/inspect.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | require 'pp' 3 | 4 | if ARGV.count == 0 5 | puts "Usage: ruby inspect.rb " 6 | exit 7 | end 8 | 9 | c = File.read 'contents.json' 10 | j = JSON.parse c 11 | 12 | projects = j['projects'] 13 | 14 | proj = ARGV[0].to_i 15 | pp projects[proj] 16 | -------------------------------------------------------------------------------- /.github/osia_category_list.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | j = get_json 4 | c = j['categories'] 5 | 6 | osia_allowed_categories(c).each { |cat| puts cat } -------------------------------------------------------------------------------- /.github/osia_convert.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | require 'date' 3 | 4 | README = 'README.md' 5 | 6 | ARCHIVE = 'ARCHIVE.md' 7 | ARCHIVE_TAG = 'archive' 8 | 9 | def apps_archived(apps) 10 | a = apps.select {|a| a['tags'] != nil }.select {|b| b['tags'].include?ARCHIVE_TAG} 11 | a.sort_by { |k, v| k['title'].downcase } 12 | end 13 | 14 | def apps_for_cat(apps, id) 15 | f = apps.select do |a| 16 | 17 | tags = a['tags'] 18 | if tags.nil? 19 | true 20 | else 21 | !(tags.include? ARCHIVE_TAG) 22 | end 23 | end 24 | 25 | s = f.select do |a| 26 | cat = a['category-ids'] 27 | cat.class == Array ? cat.include?(id) : (cat == id) 28 | end 29 | s.sort_by { |k, v| k['title'].downcase } 30 | end 31 | 32 | def output_apps(apps) 33 | o = '' 34 | apps.each do |a| 35 | name = a['title'] 36 | link = a['source'] 37 | itunes = a['itunes'] 38 | homepage = a['homepage'] 39 | desc = a['description'] 40 | tags = a['tags'] 41 | stars = a['stars'] 42 | lang = a['lang'] 43 | 44 | date_added = a['date_added'] 45 | screenshots = a['screenshots'] 46 | license = a['license'] 47 | 48 | t = "#{name}" 49 | 50 | if desc.nil? 51 | t << ' ' 52 | else 53 | t << ": #{desc} " if desc.size>0 54 | end 55 | 56 | unless itunes.nil? 57 | t << "[` App Store`](#{itunes}) " 58 | end 59 | o << "- #{t} \n" 60 | 61 | o << "
" 62 | 63 | details = if tags.nil? 64 | 'objc ' 65 | else 66 | '' 67 | end 68 | 69 | unless tags.nil? 70 | details << 'swift ' if tags.include? 'swift' 71 | 72 | tags.each do |t| 73 | details << "#{t.downcase} " if t.downcase!='swift' 74 | end 75 | end 76 | 77 | unless lang.nil? 78 | details << output_flag(lang) 79 | details << ' ' 80 | end 81 | 82 | unless stars.nil? 83 | details << output_stars(stars) 84 | end 85 | o << details 86 | 87 | o << "" 88 | 89 | details_list = [] 90 | 91 | details_list.push link 92 | 93 | unless homepage.nil? 94 | details_list.push homepage 95 | end 96 | 97 | unless date_added.nil? 98 | date = DateTime.parse(date_added) 99 | formatted_date = date.strftime "%B %e, %Y" 100 | details_list.push "Added #{formatted_date}" 101 | end 102 | 103 | unless license.nil? 104 | license_display = license=='other'? "`#{license}`" : "[`#{license}`](http://choosealicense.com/licenses/#{license}/)" 105 | details_list.push "License: #{license_display}" 106 | end 107 | 108 | details = "\n\n " 109 | details << details_list[0] 110 | details_list[1..-1].each { |x| details << "
#{x}" } 111 | 112 | unless screenshots.nil? 113 | details << "\n
" 114 | screenshots.each_with_index do |s, i| 115 | details << "#{name} image #{i+1} " 116 | end 117 | details << "\n
" 118 | end 119 | 120 | details << "\n
\n\n" 121 | o << details 122 | end 123 | o 124 | end 125 | 126 | def output_badges(count) 127 | date = DateTime.now 128 | date_display = date.strftime "%B %e, %Y" 129 | date_display = date_display.gsub ' ', '%20' 130 | 131 | b = "![](https://img.shields.io/badge/Projects-#{count}-green.svg) [![](https://img.shields.io/badge/Twitter-@opensourceios-blue.svg)](https://twitter.com/opensourceios) ![](https://img.shields.io/badge/Updated-#{date_display}-lightgrey.svg)" 132 | b 133 | end 134 | 135 | def output_flag(lang) 136 | case lang 137 | when 'deu' 138 | '🇩🇪' 139 | when 'fra' 140 | '🇫🇷' 141 | when 'jpn' 142 | '🇯🇵' 143 | when 'ltz' 144 | '🇱🇺' 145 | when 'nld' 146 | '🇳🇱' 147 | when 'por' 148 | '🇵🇹' 149 | when 'spa' 150 | '🇪🇸' 151 | when 'rus' 152 | '🇷🇺' 153 | when 'zho' 154 | '🇨🇳' 155 | else 156 | '' 157 | end 158 | end 159 | 160 | def output_stars(number) 161 | case number 162 | when 100...200 163 | '🔥' 164 | when 200...500 165 | '🔥🔥' 166 | when 500...1000 167 | '🔥🔥🔥' 168 | when 1000...2000 169 | '🔥🔥🔥🔥' 170 | when 2000...100000 171 | '🔥🔥🔥🔥🔥' 172 | else 173 | '' 174 | end 175 | end 176 | 177 | def write_readme(j) 178 | t = j['title'] 179 | subt = j['subtitle'] 180 | desc = j['description'] 181 | h = j['header'] 182 | f = j['footer'] 183 | cats = j['categories'] 184 | apps = j['projects'] 185 | 186 | output = '# ' + t 187 | output << "\n\n" 188 | output << desc 189 | output << "\n\n#{subt}\n\n" 190 | output << output_badges(apps.count) 191 | 192 | output << "\n\nJump to\n\n" 193 | 194 | cats.each do |c| 195 | title = c['title'] 196 | m = title.match /\[.*?\]/ 197 | title = m[0].sub('[', '').sub(']', '') unless m.nil? 198 | temp = "#{' ' unless c['parent']==nil }- [#{title}](\##{c['id']}) \n" 199 | output << temp 200 | end 201 | 202 | output << "- [Thanks](#thanks)\n" 203 | output << "- [Contact](#contact)\n" 204 | 205 | output << "\n" 206 | output << h 207 | output << "\n" 208 | 209 | cats.each do |c| 210 | temp = "\n#\##{'#' unless c['parent']==nil } #{c['title']} \n \n" 211 | 212 | d = c['description'] 213 | temp << "#{d} — " unless d.nil? 214 | 215 | temp << "[back to top](#readme) \n \n" 216 | output << temp 217 | 218 | cat_apps = apps_for_cat(apps, c['id']) 219 | output << output_apps(cat_apps) 220 | end 221 | 222 | output << "\n" 223 | output << f 224 | 225 | File.open(README, 'w') { |f| f.write output } 226 | puts "wrote #{README} ✨" 227 | end 228 | 229 | def write_archive(j) 230 | t = j['title'] 231 | desc = "This is an archive of the [main list](https://github.com/dkhamsing/open-source-ios-apps) for projects that are no longer maintained / old.\n\n" 232 | f = "## Contact\n\n- [github.com/dkhamsing](https://github.com/dkhamsing)\n- [twitter.com/dkhamsing](https://twitter.com/dkhamsing)\n" 233 | apps = j['projects'] 234 | archived = apps_archived apps 235 | 236 | output = "\# #{t} Archive\n\n" 237 | output << desc 238 | 239 | archived.each do |a| 240 | t = a['title'] 241 | s = a['source'] 242 | output << "- #{t} #{s}\n" 243 | end 244 | 245 | output << "\n" 246 | output << f 247 | 248 | file = ARCHIVE 249 | File.open(file, 'w') { |f| f.write output } 250 | puts "wrote #{file} ✨" 251 | end 252 | 253 | j = get_json 254 | 255 | write_readme(j) 256 | write_archive(j) 257 | -------------------------------------------------------------------------------- /.github/osia_get_history.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | HISTORY = 'git_history' 4 | 5 | j = get_json 6 | apps = j['projects'] 7 | 8 | h = {} 9 | apps.each_with_index do |a, i| 10 | t = a['title'] 11 | puts "#{i + 1}/#{apps.count}. checking #{t}" 12 | command = "git log --all --grep='#{t}'" 13 | 14 | begin 15 | r = `#{command}` 16 | rescue e 17 | r = e 18 | end 19 | 20 | h[t] = r 21 | end 22 | 23 | File.open(HISTORY, 'w') { |f| f.write JSON.pretty_generate h } 24 | puts "wrote #{HISTORY} ✨" 25 | -------------------------------------------------------------------------------- /.github/osia_get_lic.rb: -------------------------------------------------------------------------------- 1 | require 'octokit' 2 | require 'awesome_print' 3 | 4 | g = ARGV[0] 5 | 6 | if g.nil? 7 | puts "Usage: get_lic \n i.e. get_lic dkhamsing/BrandColors" 8 | exit 9 | end 10 | 11 | client = Octokit 12 | 13 | begin 14 | r = client.repo g, accept: 'application/vnd.github.drax-preview+json' 15 | ap r 16 | lic = r[:license][:key] 17 | 18 | print "Result: " 19 | ap lic 20 | rescue => e 21 | puts "Error: #{e}" 22 | end 23 | -------------------------------------------------------------------------------- /.github/osia_get_links.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | UNIQUES = 'check-unique.txt' # should be unique 4 | LINKS = 'check-links.txt' # allow dupes 5 | INFO = 'check-info.txt' # errors are allowed 6 | 7 | def apps_archived(apps) 8 | a = apps.select {|a| a['tags'] != nil }.select {|b| b['tags'].include?'archive'} 9 | a.sort_by { |k, v| k['title'] } 10 | end 11 | 12 | j = get_json 13 | a = j['projects'] 14 | archived = apps_archived a 15 | active = a.reject { |x| archived.include? x } 16 | 17 | uniques = [] 18 | info = [] 19 | active.each do |z| 20 | uniques.push z['source'] 21 | uniques.push z['screenshots'] unless z['screenshots'].nil? 22 | info.push z['itunes'] unless z['itunes'].nil? 23 | end 24 | 25 | uniques.each_with_index { |z, i| puts "#{i+1} #{z}" } 26 | 27 | puts "Writing #{UNIQUES}" 28 | File.open(UNIQUES, 'w') { |f| f.puts uniques } 29 | 30 | puts "Writing #{INFO}" 31 | File.open(INFO, 'w') { |f| f.puts info } 32 | 33 | links = [] 34 | active.each do |z| 35 | links.push z['homepage'] unless z['homepage'].nil? 36 | links.push z['title'] unless z['title'].nil? 37 | links.push z['description'] unless z['description'].nil? 38 | end 39 | 40 | c = j['categories'] 41 | c.each do |z| 42 | links.push z['title'] 43 | end 44 | 45 | links.each_with_index { |z, i| puts "#{i+1} #{z}" } 46 | 47 | puts "Writing #{LINKS}" 48 | File.open(LINKS, 'w') { |f| f.puts links } 49 | -------------------------------------------------------------------------------- /.github/osia_helper.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | FILE = 'contents.json' 4 | 5 | def get_json 6 | JSON.parse(File.read FILE) 7 | end 8 | 9 | def osia_allowed_categories(c) 10 | c.sort_by { |h| h['title']}.map { |x| x['id']} 11 | end -------------------------------------------------------------------------------- /.github/osia_history_missing.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | j = get_json 4 | apps = j['projects'] 5 | 6 | i = 0 7 | apps.each do |a| 8 | if a['date_added'].nil? 9 | puts "#{i + 1}. History missing for #{a['title']}" 10 | i = i + 1 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /.github/osia_screenshots_missing.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | j = get_json 4 | apps = j['projects'] 5 | 6 | i = 0 7 | apps.select {|a| a['screenshots'].nil? }.each do |a| 8 | # if a['screenshots'].nil? 9 | puts "#{i + 1}. Screenshots missing for #{a['title']}" 10 | i = i + 1 11 | # end 12 | end 13 | 14 | # apps.select {|a| a['screenshots']!=nil }.each do |a| 15 | # s = a['screenshots'] 16 | # if s.count==0 17 | # puts s 18 | # puts "#{i + 1}. Screenshots missing for #{a['title']}" 19 | # i = i + 1 20 | # end 21 | # end 22 | -------------------------------------------------------------------------------- /.github/osia_tweet_clean.rb: -------------------------------------------------------------------------------- 1 | require 'delete_my_tweets' 2 | 3 | c = { 4 | "consumer_key" => "X7TNI7gi1Bo3l3hRwShZr6Q5l", 5 | "consumer_secret" => "clafmSRaf7AnnusNMaZEhMajEESfhw3XTGBfTwlfgBcjwRSHcn", 6 | "access_token" => ENV['TWITTER_ACCESS_TOKEN'], 7 | "access_token_secret" => ENV['TWITTER_ACCESS_TOKEN_SECRET'], 8 | "filter" => { 9 | "exclude" => [ 10 | "Add", 11 | "add" 12 | ] 13 | } 14 | } 15 | 16 | DeleteMyTweets.twitter_delete(c) do |o| 17 | puts o 18 | end 19 | puts 'all done 🐤' 20 | -------------------------------------------------------------------------------- /.github/osia_update_history.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | require 'awesome_print' 4 | require 'colored' 5 | 6 | HISTORY = 'git_history' 7 | 8 | def get_author(a) 9 | a = a.gsub 'Author:', '' 10 | 11 | u = 12 | if a.include? 'users.noreply.github.com>' 13 | m = /<.*?@/.match a 14 | '@' + m[0].sub('@','') 15 | else 16 | m = /.* true) 7 | 8 | j = get_json 9 | apps = j['projects'] 10 | updated = [] 11 | 12 | apps.each do |a| 13 | s = a['source'] 14 | if s.nil? 15 | updated.push a 16 | elsif !(s.include? 'github') 17 | updated.push a 18 | else 19 | begin 20 | g = s.gsub('https://github.com/', '') 21 | r = client.repo g, accept: 'application/vnd.github.drax-preview+json' 22 | lic = r[:license][:key] 23 | print lic 24 | print ':' 25 | 26 | a['license'] = lic 27 | puts a['license'] 28 | 29 | updated.push a 30 | rescue => e 31 | a['license'] = 'other' 32 | puts a['license'] 33 | 34 | updated.push a 35 | next 36 | end 37 | end 38 | end 39 | 40 | j['projects'] = updated 41 | 42 | File.open(FILE, 'w') { |f| f.write JSON.pretty_generate(j) } 43 | puts "\nUpdated #{FILE} ⭐️" 44 | -------------------------------------------------------------------------------- /.github/osia_update_stars.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | require 'octokit' 4 | require 'netrc' 5 | 6 | client = Octokit::Client.new(:netrc => true) 7 | 8 | j = get_json 9 | apps = j['projects'] 10 | updated = [] 11 | 12 | apps.each do |a| 13 | s = a['source'] 14 | if s.nil? 15 | updated.push a 16 | elsif !(s.include? 'github') 17 | updated.push a 18 | else 19 | print '.' 20 | begin 21 | g = s.gsub('https://github.com/', '') 22 | r = client.repo g 23 | stars = r['stargazers_count'] 24 | a['stars'] = stars 25 | updated.push a 26 | rescue => e 27 | puts "\nerror for #{s}: #{e}" 28 | updated.push a 29 | next 30 | end 31 | end 32 | end 33 | 34 | j['projects'] = updated 35 | 36 | File.open(FILE, 'w') { |f| f.write JSON.pretty_generate(j) } 37 | puts "\nUpdated #{FILE} ⭐️" 38 | -------------------------------------------------------------------------------- /.github/osia_validate_categories.rb: -------------------------------------------------------------------------------- 1 | require_relative 'osia_helper' 2 | 3 | j = get_json 4 | c = j['categories'] 5 | apps = j['projects'] 6 | 7 | def failed(cat, app) 8 | puts "‼️ #{cat} is not a valid category for #{app}" 9 | exit 1 10 | end 11 | 12 | def verify(cat, allowed, app) 13 | failed(cat, app) unless allowed.include? cat 14 | end 15 | 16 | allowed_categories = osia_allowed_categories(c) 17 | 18 | apps.each do |a| 19 | cat = a['category-ids'] 20 | 21 | if cat.nil? 22 | puts "missing category for #{a}" 23 | exit 1 24 | end 25 | 26 | if cat.class == String 27 | verify(cat, allowed_categories, a) 28 | elsif cat.class == Array 29 | cat.each { |d| verify(d, allowed_categories, a) } 30 | end 31 | end 32 | 33 | puts 'categories validated ✅' 34 | -------------------------------------------------------------------------------- /.github/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "$id": "https://raw.githubusercontent.com/dkhamsing/open-source-ios-apps/master/.github/schema.json", 4 | "type": "object", 5 | "properties": { 6 | "title": { 7 | "type": "string" 8 | }, 9 | "subtitle": { 10 | "type": "string" 11 | }, 12 | "description": { 13 | "type": "string" 14 | }, 15 | "header": { 16 | "type": "string" 17 | }, 18 | "footer": { 19 | "type": "string" 20 | }, 21 | "categories": { 22 | "type": "array", 23 | "uniqueItems": true, 24 | "items": { 25 | "title": "Category Object", 26 | "description": "A category to group project objects under.", 27 | "properties": { 28 | "title": { 29 | "title": "Category Title", 30 | "description": "A human-readable identifier for the category.", 31 | "type": "string" 32 | }, 33 | "id": { 34 | "title": "Category Identifier", 35 | "description": "A short identifier designed for programs. It should only contain lowercase alphanumeric characters and a - (dash) for replacing spaces.", 36 | "type": "string", 37 | "pattern": "^[^A-Z_ ]+$" 38 | }, 39 | "description": { 40 | "title": "Category Description", 41 | "description": "A description of the category meant to be provided to the user.", 42 | "type": "string", 43 | "default": "" 44 | }, 45 | "parent": { 46 | "title": "Category Parent", 47 | "description": "Makes the current category a subcategory of the category with an id that matches this value.", 48 | "type": ["string", "null"], 49 | "default": null 50 | } 51 | }, 52 | "required": ["title", "id"], 53 | "additionalProperties": false 54 | } 55 | }, 56 | "projects": { 57 | "type": "array", 58 | "uniqueItems": true, 59 | "items": { 60 | "title": "Project Object", 61 | "description": "An object that holds all the information for a specific project.", 62 | "properties": { 63 | "title": { 64 | "title": "Project Title", 65 | "description": "The official title of the project.", 66 | "type": "string" 67 | }, 68 | "category-ids": { 69 | "title": "Project Category", 70 | "description": "The list of categories that the project falls under. If it is a list, the categories should be ordered from most to least relevant/applicable to the project.", 71 | "type": ["array"], 72 | "items": { 73 | "type": "string" 74 | } 75 | }, 76 | "description": { 77 | "title": "Project Description", 78 | "description": "A brief 1 sentence summary of the project.", 79 | "type": "string" 80 | }, 81 | "lang": { 82 | "title": "Project Language", 83 | "description": "A three-character ISO 639-2 code representing the primary language of the project, or a list of such codes, with the primary language first.", 84 | "type": ["string", "array"], 85 | "minLength": 3, 86 | "maxLength": 3, 87 | "minItems": 1, 88 | "items": { 89 | "type": "string", 90 | "minLength": 3, 91 | "maxLength": 3 92 | }, 93 | "default": "eng" 94 | }, 95 | "country": { 96 | "title": "Project Country", 97 | "description": "The country that the project operates out of or the country the project is designed for (if designed for a specific location). Null if country is unclear/unspecified.", 98 | "type": ["string", "null"], 99 | "minLength": 2, 100 | "maxLength": 2, 101 | "default": null 102 | }, 103 | "license": { 104 | "title": "Project License", 105 | "description": "The license that the project's source is under.", 106 | "type": "string", 107 | "enum": ["mit", "mpl-2.0", "gpl-3.0", "lgpl-3.0", "unlicense", "bsd-2-clause", "isc", "lgpl-2.1", "gpl-2.0", "apache-2.0", "cc0-1.0", "artistic-2.0", "bsd-3-clause", "agpl-3.0", "epl-1.0", "other"], 108 | "default": "other" 109 | }, 110 | "source": { 111 | "title": "Project Source", 112 | "description": "A URL where the source code to the project can be found.", 113 | "type": "string", 114 | "pattern": "^https?:\\/\\/.*?\\..*$" 115 | }, 116 | "homepage": { 117 | "title": "Project Homepage", 118 | "description": "The URL for the project's homepage.", 119 | "type": ["string", "null"], 120 | "pattern": "^https?:\\/\\/.*?\\..*$", 121 | "default": null 122 | }, 123 | "itunes": { 124 | "title": "Project iTunes Page", 125 | "description": "The URL for iTunes page for the project's app.", 126 | "type": ["string", "null"], 127 | "pattern": "^https:\\/\\/itunes\\.apple\\.com\\/.*?app\\/([^\\/]+\\/)?id[0-9]+$", 128 | "default": null 129 | }, 130 | "stars": { 131 | "title": "Project Stars", 132 | "description": "The number of stars a project has on Github, or null if the project is not a Github project.", 133 | "type": ["null", "number"], 134 | "multipleOf": 1.0, 135 | "minimum": 0, 136 | "default": null 137 | }, 138 | "tags": { 139 | "title": "Project Tags", 140 | "description": "A place to put any metadata for a project. The items can be any type.", 141 | "type": "array", 142 | "default": [] 143 | }, 144 | "suggested_by": { 145 | "title": "Suggested By", 146 | "description": "Name of person who suggested project.", 147 | "type": "string" 148 | }, 149 | "date_added": { 150 | "title": "Date Added", 151 | "description": "Date when project was added.", 152 | "type": "string" 153 | }, 154 | "screenshots": { 155 | "title": "Screenshots", 156 | "description": "Links to screenshot images.", 157 | "type": "array" 158 | } 159 | }, 160 | "required": ["title", "category-ids", "source"], 161 | "additionalProperties": false 162 | } 163 | } 164 | }, 165 | "required": ["title", "categories", "projects"], 166 | "additionalProperties": false 167 | } 168 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 2.2 3 | before_script: 4 | - gem install awesome_bot 5 | - gem install danger 6 | script: 7 | - ruby .github/osia_get_links.rb 8 | - awesome_bot check-unique.txt --allow-ssl -a 302 -w xbmc/xbmc,Cherry/master,preyproject 9 | - awesome_bot check-links.txt --allow-ssl -a 403 --allow-dupe -w wheelmap.org,sourceforge,radioparadise,iltofa,douban,preyproject,laravel-china 10 | after_script: 11 | - awesome_bot check-info.txt -a 403 12 | - danger 13 | -------------------------------------------------------------------------------- /ARCHIVE.md: -------------------------------------------------------------------------------- 1 | # Open-Source iOS Apps Archive 2 | 3 | This is an archive of the [main list](https://github.com/dkhamsing/open-source-ios-apps) for projects that are no longer maintained / old. 4 | 5 | - 2048 https://github.com/facebook/react-native/tree/d2fc08d33b2c89812d1871f8b786d666207ed362/Examples/2048 6 | - ABU https://github.com/flexih/ABU 7 | - Adler Planetarium Navigation & Tour https://github.com/lucasqiu/Adler-Mobile-App 8 | - Alien Blue https://github.com/alienblue/AlienBlue 9 | - Alphabet-Blocks https://github.com/insurgentgames/Alphabet-Blocks 10 | - Anypic https://github.com/opensourceios/Anypic 11 | - AnyWall https://github.com/opensourceios/AnyWall 12 | - apnagent-ios https://github.com/logicalparadox/apnagent-ios 13 | - AppleWatchProductHunt https://github.com/BalestraPatrick/AppleWatchProductHunt 14 | - AppSales-Mobile https://github.com/omz/AppSales-Mobile 15 | - Bancha https://github.com/squallstar/bancha-ios-app 16 | - Be my eyes https://github.com/opensourceios/bemyeyes-ios 17 | - boilerplate https://github.com/tailec/boilerplate 18 | - Canvas https://github.com/usecanvas/ios-v1 19 | - Cheddar https://github.com/nothingmagical/cheddar-ios 20 | - Chess https://github.com/mjcuva/Chess 21 | - Communiqué https://github.com/zadr/Communique 22 | - DrugsNRock https://github.com/biou/DrugsNRock 23 | - Eleven https://github.com/coderyi/Eleven 24 | - Everest https://github.com/EverestOpenSource/Everest-iOS 25 | - FinalFighter https://github.com/sebcode/FinalFighter-iphone 26 | - Forecast https://github.com/richardxyx/Forecast 27 | - fudge https://github.com/FredericJacobs/fudge 28 | - github-issues https://github.com/chriseidhof/github-issues 29 | - Google Feud https://github.com/opensourceios/Google-Feud-iOS 30 | - Hack Cancer Hackathon https://github.com/HackCancer/iOS 31 | - iLabyrinth https://github.com/RolandasRazma/iLabyrinth 32 | - iOctocat https://github.com/dennisreimann/ioctocat 33 | - Jupp https://github.com/dasdom/Jupp 34 | - LastFM https://github.com/lastfm/lastfm-iphone 35 | - Letters https://github.com/jessegrosjean/letters.iphone 36 | - Light-Jockey https://github.com/jmfieldman/Light-Jockey 37 | - Lister https://developer.apple.com/library/content/samplecode/Lister/Introduction/Intro.html 38 | - Morse https://github.com/ijoshsmith/swift-morse-code 39 | - Movies https://github.com/facebook/react-native/tree/d2fc08d33b2c89812d1871f8b786d666207ed362/Examples/Movies 40 | - Mume https://github.com/opensourceios/Mume 41 | - Munch https://github.com/opensourceios/Munch 42 | - OpenCB https://github.com/opensourceios/OpenCB 43 | - OpenClien https://github.com/kewlbear/OpenClien 44 | - Pancake https://github.com/Imaginea/pancake-ios 45 | - Parse 2013 Developer Day https://github.com/ParsePlatform/ParseDeveloperDay 46 | - ParseStore https://github.com/opensourceios/ParseStore 47 | - Paws http://www.appcoda.com/instagram-app-parse-swift/ 48 | - Pi https://github.com/opensourceios/Pi 49 | - PocketFlix https://code.google.com/archive/p/metasyntactic/wikis/PocketFlix.wiki 50 | - Potatso https://github.com/opensourceios/Potatso 51 | - Product Catalogue https://github.com/contentful/product-catalogue-swift 52 | - Repo https://github.com/ricburton/Repo 53 | - Speak https://github.com/opensourceios/speakability 54 | - Steps https://github.com/gizmosachin/Steps 55 | - SudokuResolv https://github.com/Haoest/SudokuResolv 56 | - Swift Off https://github.com/opensourceios/swift-off-todo 57 | - TaskPaper https://github.com/jessegrosjean/NOTTaskPaperForIOS 58 | - The Spin Zone https://github.com/opensourceios/Spin-Zone 59 | - theNews https://github.com/TosinAF/thenews-objc 60 | - Tic-tac-toe https://github.com/ijoshsmith/swift-tic-tac-toe 61 | - TicTacToe https://github.com/facebook/react-native/tree/d2fc08d33b2c89812d1871f8b786d666207ed362/Examples/TicTacToe 62 | - Toggl Timer https://github.com/opensourceios/toggle-mobile 63 | - Vim https://github.com/applidium/Vim 64 | - WatchNotes https://github.com/azamsharp/WatchNotes 65 | - wikiHow https://github.com/tderouin/wikiHow-iPhone-Application 66 | - XPilot http://7b5labs.com/xpilot.git/ 67 | - Yorkie https://github.com/opensourceios/YorkieApp 68 | 69 | ## Contact 70 | 71 | - [github.com/dkhamsing](https://github.com/dkhamsing) 72 | - [twitter.com/dkhamsing](https://twitter.com/dkhamsing) 73 | -------------------------------------------------------------------------------- /Dangerfile: -------------------------------------------------------------------------------- 1 | # Check links 2 | def ab_results(file) 3 | require 'json' 4 | results = File.read file 5 | j = JSON.parse results 6 | if j['error']==true 7 | warn j['title'] 8 | markdown j['message'] 9 | end 10 | end 11 | 12 | ab_results 'ab-results-check-info.txt-markdown-table.json' 13 | ab_results 'ab-results-check-links.txt-markdown-table.json' 14 | ab_results 'ab-results-check-unique.txt-markdown-table.json' 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | ruby: 3 | version: 2.2.0 4 | test: 5 | pre: 6 | - sudo pip install json-spec 7 | override: 8 | - json validate --schema-file=.github/schema.json --document-file=contents.json 9 | - ruby .github/osia_validate_categories.rb 10 | deployment: 11 | master: 12 | branch: master 13 | commands: 14 | - ruby .github/osia_convert.rb 15 | - ./.github/deploy.sh 16 | - gem install delete_my_tweets 17 | - ruby .github/osia_tweet_clean.rb 18 | --------------------------------------------------------------------------------