Thursday, August 24, 2017

NWJS & Mac App : Signing and Submission to Store

Hi Guys,

I am feeling very relieved and relaxed today. Wanna know WHY???

Finally I am able to sign the nwjs mac app with App store 3rd Party App and Installer certificates and create the package and yippie its on App store. :) :) :)

Lets proceed towards the starting point and follow a path to Successful upload. Here you go.


Pre-requisites for Mac App Store Upload:
  • All Apps must have Sandbox enabled. Yes its mandatory.
  • Bit Code is not supported in Mac Apps. So chill.
  • App must be packaged and submitted using Apple's packaging technology included in xcode or via command line tools.Third party installers are not allowed.
  • Bundle Display name, identifier must be properly set.
  • Provide proper Icon Files.

Mac App Certificates and their Naming Conventions:
  • The name begins with:
    • “Mac Developer” for a Mac Development certificate.
    • “3rd Party Mac Developer Application” for a Mac Submission certificate.
    • “3rd Party Mac Developer Application” for a Mac Submission certificate.
    • “3rd Party Mac Developer Application” for a Mac Submission certificate
  • Both your distribution and developer certificates appear in the My Certificates category in Keychain Access. 
    • The distribution certificates begin with the text “3rd Party Mac Developer” followed by the type of certificate and your team name.
  • Only a team agent or admin can obtain and use Distribution certificates or Developer ID certificates.


Things to Do:

  • In Info.plist of your App 
    • Add a key [if not present] named Application Category and choose its value from list provided.
    • Delete key CFBundleDocumentTypes and its Values

  • Ensure that all the files can be read by Non root users. for this you can run command in terminal
    • $ cd path_to_nwjs.app
    • $ chmod a+rX *
    • $ chmod -R u+rwX,go+rX,go-w *
    • Provide readable permission to app file , Parent and Child plists also that will be served as entitlements while code signing the app.

  • Create Parent and Child Entitlements.





  • Set the Bundle identifier of the NWJS Helper App.

  • Set the Bundle Identifier of the App_mode_loader App.

  • Now Sign the App and create package to be uploaded:
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework/Resources/app_mode_loader.app
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework/Versions/A/Helpers/crashpad_handler
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework/Versions/A/XPCServices/AlertNotificationService.xpc/Contents/MacOS/AlertNotificationService
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework/libnode.dylib
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework/libffmpeg.dylib
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Framework.framework/Versions/A/nwjs\ Framework
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Child.plist hello.app/Contents/Version/59.0.3071.115/nwjs\ Helper.app
    • $ codesign -f --deep -s "3rd Party Mac Developer Application : Organization_Name (Team ID)" --entitlements Parent.plist hello.app

  • Create Package:
    • $ Productbuild --component "hello.app" /Applications --sign "3rd Party Mac Developer Installer : Organization_Name (Team ID)" --product "hello.app/Contents/Info.plist" myPackage.pkg

  • Upload this package using Application Loader. Choose the latest one.

You may also face some Errors:

  • The Session status is failed and the error description is "failed to open ssh session. (16)"
    • Open Preferences of Application Loader.
    • Click Advanced
    • Select only DAV and unselect Signiant and Aspera.
  • Resource fork : Finder information or similar ditritus not allowed
    • $ xattr -cr hello.app
  • Malformed framework : Framework must contain symbolic link
    • Choose nwjs version that already has inbuilt support for symlinks.
  • Unsealed contents present in the root directory of an embedded framework.
    • Do not change Info.plist files other that nwjs , nwjs Helper and app_mode_loader.app

Fix the issues and upload again.
Success is here....


Hope you guys find it useful.
Thanks a lot for the view.


:)
:)







Monday, June 19, 2017

Terminal : Commands of Daily Use

Hey folks,

Please have a look at some cool terminal commands


1. Show / hide Hidden Files : Do relaunch finder after you hit this command
$ defaults write com.apple.finder AppleShowAllFiles true / false


2. Copy Contents of folder to another
$ ditto <path of Source Folder> <Path of Destination Folder>
ditto /Users/admin/Documents/test /Users/admin/Documents/Swati/try


3. Zip a Folder
Zip -r <path of resultant zipped file> <Folder to be zipped>
$ zip -r test.zip  test 
Zip -r <path of resultant zipped file> <Folder to be zipped> -x <file not to be included in zip>
$ zip   -r  test.zip test  -x "*.DS_Store” 


4. Unzip archive
Unzip  <path of zipped file>
$ Unzip test.zip


5. Custom message on Login Window
Sudo defaults write  <path of login window> LoginwindowText "custom text"
$ sudo defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "This is Swati's Mac.. "





6. Show AnyWhere option in GateKeeper of MAC OSX Sierra or Disable GateKeeper
Sudo spctl <prefixes>
$ sudo spctl --master-disable


7. Enable GateKeeper
Sudo spctl <prefixes>
$ sudo spctl --master-enable


8. Download content from any url
Curl -0 <url>
$ curl -0 http://file-to-be-downloaded.flv


9. To know the network connectivity
Ping <host>
$ ping google.com


10. Lets talk
say "your text"
$ say "Hello Swati"



Hope its useful :)



Sunday, June 18, 2017

Dealing with Gatekeeper in OSX Sierra

Hi all,

Found something interesting in OSX Sierra. The gate keeper showed only 2 options





No Anywhere option in Gatekeeper. :(

But you can make it visible by running command in Terminal. So to

Disable GateKeeper
sudo spctl --master-disable


Enable GateKeeper
sudo spctl --master-disable



Thanks for reading :)

Wednesday, June 14, 2017

The case of Missing 'Archive'

Hey Folks,

Many of you might have faced this issue..
You start your day with creating an archive to get it tested or to upload to App store but AFAIK no archive created or created with ZERO bytes.

Had faced the same issue multiple times and solved it with different steps.
So here you go. It might help some one.


Steps that should definitely be followed:


Set Installation Directory in Build Settings of the Target

  • /Applications

Set Skip Install of Project
  • NO


Set Skip Install of Targets / Libraries for Release Scheme
  • NO


Set Skip Install of Targets / Libraries for Debug Scheme
  • YES


Check Compile Sources of all the Targets
  • Files should be listed here



Thanks to All....

Tuesday, June 13, 2017

Appstore Build Create, Upload & Test

Hey Folks,

I know you guys know the process 😉
But its worth sharing what say!!!

Create AppStore Build
  • Open Project
  • Select Target
  • Click General 
    • Set Display Name Bundle Identifier, Version and Build.
  • Click Build Settings
    • Choose Appstore Provisioning Profile corresponding to Bundle Identifier.
    • For Release Scheme choose the Certificate corresponding to the provisioning profile.
    • Now click Target Selector next to Stop Button
    • Click Archive
      • Choose Build Configuration as Release
      • Tick mark on "Reveal Archive in Finder"
    • Click on Product 
      • Click Archive : This will start the build creation.
    • Choose Always Allow for Code-signing Popup
    • Build Succeeded Toast will be shown
    • An organizer will be visible which will show your archive.
    • Right Click to show in Finder
    • You will see <TARGET><DATE>, <TIME>.xcarchive
      • Right click to Show Package Contents
      • Products >> Applications >> Build_Display_NAME.app
      • Drag and Drop this .app file in iTunes
      • Right click on the app in iTunes and click Show In Finder
      • You will see the IPA for Appstore.
    Note:
    Sometimes SwiftSupport folder is not embedded under .app.
    But you need to do this if you give swift support in App.
    So follow these steps:
    • Create a Folder Test
      • Copy SwiftSupport Folder inside Test
      • Unzip ipa and add Payload folder here inside Test
      • Open Terminal
      • Type Command : $ zip -r Name.ipa Payload SwiftSupport -x "*.DS_Store"
      • -r is for adding and -x is for removing files
      • Enter
      • A new IPA is generated with SwiftSupport


    Upload AppStore Build using Application Loader


    • Open Latest Application Loader
    • Login with Apple ID


    • Choose your IPA that you wish to upload.



    • It will start reviewing your app.



    • Then it will show you the App details.
    • Check them and click Next.



    • Now its starts adding application.
    • Then it uploads package to Appstore.
    • Uploaded package to the Appstore.
    • Click Next.



    • Success message is displayed.
    • Click Done.



    View In iTunes Connect
    • Visit https://itunesconnect.apple.com/
    • Login with Apple Id
    • Click on My Apps
    • Click on your App
    • Goto Activity Tab
    • You will see your versioned app with text (Processing)
    • Once processing is done you will see the new versioned build under TestFlight Tab.
    • Now its available for testing.
    • You can add testers either via User and Roles section or via sending invitation emails to users under TestFlight tab.


    Happy Coding
    Enjoy Uploading and Testing 😀😁😃



      Tuesday, March 28, 2017

      Swift 3.0 Cheat Sheet


      Hi All,
      Started learning Swift 3.0. Need transformed to LOVE :)
      Gathered some data that I would like to share with all.

      So below is Objective C Code and its corresponding Swift 3 Code




      ============= Variables =============


      Strings declaration
      Objective C : Type is Must for Variable or Constant
      double price = 23.55;NSString *firstMessage = @"Swift 3 is awesome. ";

      Swift : Variable Type is Not Required, this feature is called "type inference"
      var price = 123.55
      let firstMessage = "Swift 3 is awesome.



      Mutable and Immutable + variables and constants
      Objective C 
      double price = 23.55;
      int const temp = 100;

      Swift : Var is for mutable variable and let is for immutable constant, VAR is must if LET is not used
      var price = 23.55
      let temp = 100;



      Using Pointer symbol?
      Objective C
      NSString *str = @""Hello world"";

      Swift
      var str = "Hello world"



      ============= Strings ============= 


      Strings declaration
      Objective C
      NSString *str = @"Hello world";

      Swift 
      var str = "Hello world"



      String Concatenation
      Objective C
      NSString *a = @"Hello";
      NSString *b = @"World";
      NSString *str = [NSString stringWithFormat:@"%@%@",a,b];

      Swift 
      var a = "Hello"
      var b = "World"
      var str = a + b



      String Comparison
      Objective C 
      [a equalsTostring:b]

      Swift
      a == b




      Imports
      Objective C 
      #import <UIKit/UIKit.h>

      Swift 
      import UIKit


      Line Termination
      Objective C
      NSString *a = @"Hello";

      Swift 
      var a = "Hello"


      Logs
      Objective C 
      NSLog(@"test");

      Swift
      print("test")


      Colors
      Objective C
      [UIColor redcolor];

      Swift 
      UIColor.red


      Pragma Marks 
      Objective C
      #pragma mark - Separators

      Swift  
      // MARK: 


      Arrays 
      Objective C
      NSMutablearray *arr = [NSMutableArray alloc] init];
      [arr addObject:@"first"];
      [arr addObject:@"second"];
      [arr addObject:@"third"];

      Swift
      var arrayOfInts: [Int]
      var numbers: [Int] = []var listOfNames = ["Sam", "Andrew", "George"] // an array of strings
      var arrayOfStrings: [String] = ["We", "Love", "Swift"]
      var listOfNumbers = [1, 22, 13, 10, 100] // an array of numbers


      Dictionaries 
      Objective C : Keys can only be string
      NSMutableDictionary *dict = [NSDictionary alloc] init];
      [dict setValue"@"SWATI" forKey:@"NAME"];

      Swift : keys can be anything
      var dict = [String:String]()
      dict["NAME"] = "SWATI"


      Button Clicks 
      Objective C
      -(IBAction)buttonClicked:(NSString*)str;

      Swift
      @IBAction func buttonClicked();


      Parameterized Methods
      Objective C
      Signature:- (void)showAlertWithTitle:(NSString*)title andMessage:(NSString*)message;
      Calling:[self showAlertWithTitle:@"Hello" andMessage:@"Welcome to Objective C"];

      Swift
      Signature:showAlert(title:String , message:String)
      Calling:showAlert(title:"Hello", message:"Welcome To Swift")


      Enums 
      Objective C
      enum WebServiceType
      {   
          WebServiceTypeLogin,    
          WebServiceTypeFetchData
      }
      Usage : WebServiceTypeLogin use as it is when required

      Swift
      enum WebServiceType:Int
      {    
        case Login = 1   
        case FetchData = 2
      }
      enum NetworkStatusCode:Int
      {
        case Success = 1 
        case Failure = 2
      }
      Usage : NetworkStatusCode.Success


      Protocols 
      Objective C
      @protocol WebServiceResponseDelegate:NSObject
      {
       @optional
       - (void)test; 

      @required
      - (void)webServiceResponse:WebservicesManager
                        finishedTaskType:WebServiceType                                                                                                            status:NetworkStatusCode                                                                                                               id:remoteData
      }

      Swift
      protocol WebServiceResponseDelegate:class
      {
            func test();   
            func webServiceResponse(assistant:WebServicesManager ,                                                                                  finishedTaskType:WebServiceType ,                                                                                                           status:NetworkStatusCode ,                                                                                            remoteData:Any)
      }

      How to make some methods in a protocol as Optional coz by default methods are mandatory to implement 
      @objc protocol abc { func test() }

      How to call methods using delegates
      Objective C
      [delegate webServiceResponse:self                 
                             finishedTaskType:finishedTaskType   
                                              status:NetworkStatusCodeSuccess       
                                     remoteData:@""];

      Swift
      delegate.webServiceResponse(assistant:self, 
                                        finishedTransaction:finishedTransaction,  
                                                             status:NetworkStatusCode.Success,         
                                                    remoteData: ""); 


      Exception Handling

      Objective C
      @try {}
      catch (NSException *e) {}
      finally {}

      Swift
      do{}catch{}

      Thursday, March 23, 2017

      Fun with Gradle

      Hi All,

      Greetings for the day!!!

      Have been wondering from many days as to why should I use Gradle if same features are provided by xcodebuild also

      • A command line tool provided by Apple that creates builds/packages.
      • It can take input target, scheme, ipa name, signing information etc in the arguments.
      • Supports multiple tasks and environments.
      • Can be integrated with Jenkins too.


      Then why Gradle??
      • Build Management along with Dependency Management. Xcodebuild can only do build management and for dependency management it needs Cocoapods.
      • If you are working on multiple platforms like iOS and Android then Gradle is the common choice for both.

      Now how to Use Gradle with Xcode

      • In terminal java -version should be 7 
      • if not type $ brew cask install java  or $ brew cask install Caskroom/versions/java7
      • Download gradle via homebrew $ brew install gradle
      • Type $ gradle -v to check its version

      2) Create build.gradle file for your project.
      3) Navigate to project directory in terminal.
      4) $ gradle build
      5) Project builds
      ta da....


      Sample build.gradle file

      plugins {
        id "org.openbakery.xcode-plugin" version "0.14.5"
      }

      xcodebuild {
           target = 'Hello-Gradle'

      /* If need to differentiate between iOS and android */
           type = 'IOS'             

      /* Set ipa file name*/
           ipaFileName = ipaName 

       /* if u wish to create archive its necessary to set simulator as FALSE coz for archive we need DEVICE*/
           simulator = false        
      }


      To execute above file code you can also use:

      $ gradle xcodebuild 

      Wednesday, March 22, 2017

      Fun with Collection Views



      Hi all,

      Lets start the new year with some fun. I was always interested to create grid like structures in my app and for many times i tried third party tools to fulfill my need but this time i decided to work with Apple's UICollectionView and trust me its awesome.

      I know its easy for many who have worked with them but for those who haven't here is a path to start.
      You want to show a grid view layout on your view controller. For this we need 3 things :

      1) UICollectionViewCell               : This will decide the UI of the grid controls
      2) UICollectionViewFlowLayout : This will provide the UI placements and positions
      3) UICollectionViewController    :  This will help in UI rendering


      First of all create a class named "CollectionViewCell" that is derived from UICollectionViewCell.
      This class must have an attached XIB [though u can create programmatically too]. :)

      CollectionViewCell.h



      CollectionViewCell.m



      CollectionViewCell.xib

      CustomFlowLayout.h



      CustomFlowLayout.m







      CollectionViewController.h




      CollectionViewController.m





      Now here we set the collection view info


      The important collection View DataSource Methods









      Compile & Run the App
        &
      Here is the final cartoon grid view